resolve conflict
This commit is contained in:
parent
1d54148b3e
commit
a7aefc10ec
6
Makefile
6
Makefile
@ -25,7 +25,7 @@ LINUX_GL_LIBS = -lGL
|
||||
|
||||
CXXFLAGS = -std=c++20 -I$(IMGUI_DIR) -I$(IMGUI_DIR)/backends
|
||||
CXXFLAGS += -DIMGUI_DEFINE_MATH_OPERATORS -Ofast
|
||||
LIBS =
|
||||
LIBS = -lexiv2
|
||||
|
||||
##---------------------------------------------------------------------
|
||||
## OPENGL ES
|
||||
@ -44,9 +44,9 @@ LIBS =
|
||||
|
||||
ifeq ($(UNAME_S), Linux) #LINUX
|
||||
ECHO_MESSAGE = "Linux"
|
||||
LIBS += $(LINUX_GL_LIBS) -ldl `sdl2-config --libs`
|
||||
LIBS += $(LINUX_GL_LIBS) -ldl -L/usr/lib -lSDL2
|
||||
|
||||
CXXFLAGS += `sdl2-config --cflags`
|
||||
CXXFLAGS += -I/usr/include/SDL2 -D_REENTRANT
|
||||
CFLAGS = $(CXXFLAGS)
|
||||
endif
|
||||
|
||||
|
310
main.cpp
310
main.cpp
@ -7,6 +7,7 @@
|
||||
#include "lib/imgui.h"
|
||||
#include "lib/imgui_internal.h"
|
||||
#include <cstdint>
|
||||
#include <exiv2/tags.hpp>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
@ -34,50 +35,139 @@
|
||||
#include "lib/backends/tex_inspect_opengl.h"
|
||||
#include "lib/argparse.hpp"
|
||||
|
||||
#include <exiv2/exiv2.hpp>
|
||||
|
||||
struct Args : public argparse::Args {
|
||||
std::string &fpath = arg("path to the image");
|
||||
};
|
||||
|
||||
|
||||
struct EXIFData {
|
||||
std::string CameraMake;
|
||||
std::string CameraModel;
|
||||
std::string LensModel;
|
||||
std::string ImageOrientation;
|
||||
std::string ImageDimensionX;
|
||||
std::string ImageDimensiony;
|
||||
std::string ISO;
|
||||
std::string ShutterSpeed;
|
||||
std::string FNumber;
|
||||
std::string FocalLength;
|
||||
std::string ExposureBias;
|
||||
std::string MeteringMode;
|
||||
std::string Flash;
|
||||
std::string Time;
|
||||
std::string TimeTaken;
|
||||
std::string TimeTakenOffset;
|
||||
std::string GPSLat;
|
||||
std::string GPSLatref;
|
||||
std::string GPSLon;
|
||||
std::string GPSLonref;
|
||||
};
|
||||
|
||||
struct Texture
|
||||
{
|
||||
ImTextureID texture;
|
||||
ImVec2 size;
|
||||
int channels;
|
||||
EXIFData exif;
|
||||
};
|
||||
|
||||
static uint8_t* image = nullptr;
|
||||
|
||||
Texture LoadTexture(const char * path)
|
||||
{
|
||||
const int channelCount = 4;
|
||||
int imageFileChannelCount;
|
||||
int width, height;
|
||||
image = (uint8_t *)stbi_load(path, &width, &height, &imageFileChannelCount, channelCount);
|
||||
if (image == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s\nFailed to open %s\n", stbi_failure_reason(), path);
|
||||
|
||||
return {nullptr,{0,0}};
|
||||
EXIFData printExifData(const std::string& imagePath) {
|
||||
EXIFData d;
|
||||
d.CameraMake = "NULL";
|
||||
try {
|
||||
// Load the image
|
||||
Exiv2::Image::UniquePtr img = Exiv2::ImageFactory::open(imagePath);
|
||||
if (img.get() == 0) {
|
||||
std::cerr << "Error: Could not open image file " << imagePath << std::endl;
|
||||
return d;
|
||||
}
|
||||
img->readMetadata();
|
||||
|
||||
// Get the Exif data
|
||||
Exiv2::ExifData &exifData = img->exifData();
|
||||
if (exifData.empty()) {
|
||||
std::cerr << "No EXIF data found in file " << imagePath << std::endl;
|
||||
return d;
|
||||
}
|
||||
|
||||
// Helper function to print EXIF data if available
|
||||
auto printExifValue = [&exifData](const char* key, std::string *d) {
|
||||
Exiv2::ExifKey exifKey(key);
|
||||
Exiv2::ExifData::const_iterator pos = exifData.findKey(exifKey);
|
||||
if (pos != exifData.end()) {
|
||||
*d = pos->value().toString();
|
||||
}
|
||||
};
|
||||
|
||||
// Print common EXIF data
|
||||
printExifValue("Exif.Image.Make", &d.CameraMake);
|
||||
printExifValue("Exif.Image.Model", &d.CameraModel);
|
||||
printExifValue("Exif.Photo.LensModel", &d.LensModel);
|
||||
|
||||
printExifValue("Exif.Image.Orientation", &d.ImageOrientation);
|
||||
//
|
||||
printExifValue("Exif.Photo.ExposureTime", &d.ShutterSpeed);
|
||||
printExifValue("Exif.Photo.FNumber", &d.FNumber);
|
||||
printExifValue("Exif.Photo.ISOSpeedRatings", &d.ISO);
|
||||
printExifValue("Exif.Photo.FocalLength", &d.FocalLength);
|
||||
printExifValue("Exif.Photo.ExposureBiasValue", &d.ExposureBias);
|
||||
printExifValue("Exif.Photo.MeteringMode", &d.MeteringMode);
|
||||
printExifValue("Exif.Photo.Flash", &d.Flash);
|
||||
|
||||
printExifValue("Exif.Image.DateTime", &d.Time);
|
||||
printExifValue("Exif.Photo.DateTimeOriginal", &d.TimeTaken);
|
||||
printExifValue("Exif.Photo.OffsetTime", &d.TimeTakenOffset);
|
||||
printExifValue("Exif.Photo.PixelXDimension", &d.ImageDimensionX);
|
||||
printExifValue("Exif.Photo.PixelYDimension", &d.ImageDimensiony);
|
||||
|
||||
printExifValue("Exif.GPSInfo.GPSLatitudeRef", &d.GPSLatref);
|
||||
printExifValue("Exif.GPSInfo.GPSLatitude", &d.GPSLat);
|
||||
printExifValue("Exif.GPSInfo.GPSLongitudeRef", &d.GPSLonref);
|
||||
printExifValue("Exif.GPSInfo.GPSLongitude", &d.GPSLon);
|
||||
|
||||
|
||||
/*
|
||||
Exif.Image.Make 0x010f Ascii 5 SONY
|
||||
Exif.Image.Model 0x0110 Ascii 10 ILCE-7RM5
|
||||
|
||||
Exif.Image.Orientation 0x0112 Short 1 8
|
||||
Exif.Photo.PixelXDimension 0xa002 Long 1 9504
|
||||
Exif.Photo.PixelYDimension 0xa003 Long 1 6336
|
||||
|
||||
Exif.Photo.ExposureTime 0x829a Rational 1 1/400
|
||||
Exif.Photo.FNumber 0x829d Rational 1 56/10
|
||||
Exif.Photo.ISOSpeedRatings 0x8827 Short 1 100
|
||||
Exif.Photo.FocalLength 0x920a Rational 1 400/10
|
||||
Exif.Photo.ExposureBiasValue 0x9204 SRational 1 -10/10
|
||||
Exif.Photo.MeteringMode 0x9207 Short 1 5
|
||||
Exif.Photo.Flash 0x9209 Short 1 16
|
||||
|
||||
Exif.Image.DateTime 0x0132 Ascii 20 2024:06:07 08:58:07
|
||||
Exif.Photo.DateTimeOriginal 0x9003 Ascii 20 2024:06:07 08:58:07
|
||||
Exif.Photo.OffsetTime 0x9010 Ascii 7 -05:00
|
||||
|
||||
Exif.GPSInfo.GPSLatitudeRef 0x0001 Ascii 2 N
|
||||
Exif.GPSInfo.GPSLatitude 0x0002 Rational 3 40/1 43/1 32231/1000
|
||||
Exif.GPSInfo.GPSLongitudeRef 0x0003 Ascii 2 W
|
||||
Exif.GPSInfo.GPSLongitude 0x0004 Rational 3 73/1 59/1 16688/1000
|
||||
*/
|
||||
|
||||
} catch (Exiv2::Error& e) {
|
||||
std::cerr << "Error: " << e.what() << std::endl;
|
||||
}
|
||||
|
||||
GLenum dataFormat = GL_RGBA;
|
||||
GLuint textureHandle;
|
||||
glGenTextures(1, &textureHandle);
|
||||
glBindTexture(GL_TEXTURE_2D, textureHandle);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, dataFormat, GL_UNSIGNED_BYTE, image);
|
||||
|
||||
Texture t;
|
||||
t.texture = (void*)(uintptr_t)(textureHandle);
|
||||
t.size = ImVec2((float)width,(float)height);
|
||||
t.channels = channelCount;
|
||||
|
||||
return t;
|
||||
return d;
|
||||
}
|
||||
|
||||
Texture ReloadTexture(ImTextureID id, int width, int height) {
|
||||
GLuint tid = (GLuint)(uintptr_t)id;
|
||||
|
||||
|
||||
Texture ReloadTexture(Texture tin, int width, int height) {
|
||||
GLuint tid = (GLuint)(uintptr_t)tin.texture;
|
||||
glDeleteTextures((GLsizei)1, &tid);
|
||||
|
||||
GLenum dataFormat = GL_RGBA;
|
||||
@ -91,6 +181,8 @@ Texture ReloadTexture(ImTextureID id, int width, int height) {
|
||||
Texture t;
|
||||
t.texture = (void*)(uintptr_t)(textureHandle);
|
||||
t.size = ImVec2((float)width,(float)height);
|
||||
t.exif = tin.exif;
|
||||
t.channels = tin.channels;
|
||||
|
||||
return t;
|
||||
}
|
||||
@ -120,6 +212,43 @@ void RotateImage(Texture t) {
|
||||
delete[] tempBuffer;
|
||||
}
|
||||
|
||||
Texture LoadTexture(const char * path)
|
||||
{
|
||||
const int channelCount = 4;
|
||||
int imageFileChannelCount;
|
||||
int width, height;
|
||||
image = (uint8_t *)stbi_load(path, &width, &height, &imageFileChannelCount, channelCount);
|
||||
|
||||
if (image == NULL)
|
||||
{
|
||||
fprintf(stderr, "%s\nFailed to open %s\n", stbi_failure_reason(), path);
|
||||
|
||||
return {nullptr,{0,0}};
|
||||
}
|
||||
|
||||
auto exif = printExifData(path);
|
||||
|
||||
|
||||
|
||||
GLenum dataFormat = GL_RGBA;
|
||||
GLuint textureHandle;
|
||||
glGenTextures(1, &textureHandle);
|
||||
glBindTexture(GL_TEXTURE_2D, textureHandle);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, dataFormat, GL_UNSIGNED_BYTE, image);
|
||||
|
||||
Texture t;
|
||||
t.texture = (void*)(uintptr_t)(textureHandle);
|
||||
t.size = ImVec2((float)width,(float)height);
|
||||
t.channels = channelCount;
|
||||
t.exif = exif;
|
||||
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const int MAX_ANNOATED_TEXELS = 10000;
|
||||
|
||||
@ -136,6 +265,7 @@ int main(int argc, char* argv[]) {
|
||||
bool GRID_ENABLED = false;
|
||||
bool AA_ENABLED = true;
|
||||
bool SHOW_HELP = false;
|
||||
bool SHOW_EXIF = false;
|
||||
int MODE = 0;
|
||||
|
||||
// Decide GL+GLSL versions
|
||||
@ -252,11 +382,14 @@ int main(int argc, char* argv[]) {
|
||||
break;
|
||||
case SDL_SCANCODE_R:
|
||||
RotateImage(t);
|
||||
t = ReloadTexture(t.texture, t.size.y, t.size.x);
|
||||
t = ReloadTexture(t, t.size.y, t.size.x);
|
||||
break;
|
||||
case SDL_SCANCODE_Q:
|
||||
done = true;
|
||||
break;
|
||||
case SDL_SCANCODE_E:
|
||||
SHOW_EXIF = !SHOW_EXIF;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -284,7 +417,7 @@ int main(int argc, char* argv[]) {
|
||||
ImGui::SetNextWindowPos(viewport->Pos);
|
||||
ImGui::SetNextWindowSize(viewport->Size);
|
||||
ImGui::Begin("Main", NULL,
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize);
|
||||
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoBringToFrontOnFocus);
|
||||
auto wSize = ImGui::GetContentRegionAvail();
|
||||
if (t.texture != 0) {
|
||||
|
||||
@ -364,11 +497,132 @@ int main(int argc, char* argv[]) {
|
||||
ImGui::Text("\tFloat Values");
|
||||
ImGui::Separator();
|
||||
ImGui::Text("h - show help popup");
|
||||
ImGui::Text("e - toggle EXIF info");
|
||||
ImGui::Separator();
|
||||
ImGui::Text("q - quit");
|
||||
ImGui::Separator();
|
||||
ImGui::Text("click anywhere to continue");
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
if (SHOW_EXIF && t.exif.CameraMake != "NULL") {
|
||||
ImGuiWindowClass topmost;
|
||||
topmost.ClassId = ImHashStr("TopMost");
|
||||
topmost.ViewportFlagsOverrideSet = ImGuiViewportFlags_TopMost;
|
||||
ImGui::SetNextWindowClass(&topmost);
|
||||
ImGui::Begin("EXIF", NULL, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing);
|
||||
if(ImGui::BeginTable("Hardware", 2)) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("Make");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s", t.exif.CameraMake.c_str());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("Model");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s", t.exif.CameraModel.c_str());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("Lens");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s", t.exif.LensModel.c_str());
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if(ImGui::BeginTable("Photo", 2)) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("Shutter Speed");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s", t.exif.ShutterSpeed.c_str());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("F-Stop");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s", t.exif.FNumber.c_str());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("ISO");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s", t.exif.ISO.c_str());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("Focal Length");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s", t.exif.FocalLength.c_str());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("Exposure Comp");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s", t.exif.ExposureBias.c_str());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("Metering Mode");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s", t.exif.MeteringMode.c_str());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("Flash");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s", t.exif.Flash.c_str());
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if(ImGui::BeginTable("Meta", 2)) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("Date");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s %s", t.exif.TimeTaken.c_str(), t.exif.TimeTakenOffset.c_str());
|
||||
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("Dimensions");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%sx%s", t.exif.ImageDimensionX.c_str(), t.exif.ImageDimensiony.c_str());
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
if(ImGui::BeginTable("Location", 2)) {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("Latitude");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s %s", t.exif.GPSLat.c_str(), t.exif.GPSLatref.c_str());
|
||||
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableSetColumnIndex(0);
|
||||
ImGui::Text("Longitude");
|
||||
ImGui::TableSetColumnIndex(1);
|
||||
ImGui::Text("%s %s", t.exif.GPSLon.c_str(), t.exif.GPSLonref.c_str());
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Press e to hide");
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
}
|
||||
|
||||
// Rendering
|
||||
|
Loading…
Reference in New Issue
Block a user