void show_exif_window(GtkWidget* widget, ExifWin * win) { GError* error = NULL; const char* current_image = image_list_get_current_file_path(win->mw->img_list); win->exif_window = (GtkWindow*)gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_resizable (win->exif_window, TRUE); gtk_window_set_default_size (win->exif_window, 400, 400); gtk_window_set_position(win->exif_window,GTK_WIN_POS_CENTER); gtk_window_set_title(win->exif_window, "Exif information"); win->box = (GtkVBox*)gtk_vbox_new (FALSE,0); win->hbox = (GtkHBox*)gtk_hbox_new (FALSE,0); win->exif_label = (GtkLabel*)gtk_label_new("Exif data"); gtk_label_set_justify(GTK_LABEL(win->exif_label), GTK_JUSTIFY_CENTER); gtk_box_pack_start(GTK_BOX(win->box), (GtkWidget*)win->exif_label, FALSE, FALSE, 5); win->exif_button = (GtkButton*)gtk_button_new_with_label("Close"); win->list = gtk_tree_view_new(); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(win->list), FALSE); win->align = gtk_alignment_new( 1,0 ,0,0); gtk_container_add( (GtkContainer*)win->align, (GtkWidget*)win->exif_button); win->scroll = (GtkScrolledWindow*)gtk_scrolled_window_new(NULL,NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(win->scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_add_with_viewport(win->scroll, win->list); gtk_box_pack_start(GTK_BOX(win->box), GTK_WIDGET(win->scroll), TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(win->box), GTK_WIDGET(gtk_hseparator_new()), FALSE, TRUE,0); gtk_box_pack_start(GTK_BOX(win->box), GTK_WIDGET(win->hbox), FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(win->hbox),GTK_WIDGET(win->align), TRUE, TRUE, 0); int Modified = FALSE; ReadMode_t ReadMode; ReadMode = READ_METADATA; CurrentFile = current_image; FilesMatched = 1; ResetJpgfile(); memset(&ImageInfo, 0, sizeof(ImageInfo)); ImageInfo.FlashUsed = -1; ImageInfo.MeteringMode = -1; ImageInfo.Whitebalance = -1; { struct stat st; if (stat(current_image, &st) >= 0){ ImageInfo.FileDateTime = st.st_mtime; ImageInfo.FileSize = st.st_size; }else{ printf("No such file"); } } if (current_image == NULL) return; strncpy(ImageInfo.FileName, current_image, PATH_MAX); if (!ReadJpegFile(current_image, READ_METADATA)) return; DoModify = TRUE; Modified = TRUE; ReadMode = READ_IMAGE; if (!ReadJpegFile(current_image, ReadMode)) return; create_EXIF(); CheckFileSkip(); ShowTags = TRUE; ShowConciseImageInfo(); ShowImageInfo(TRUE); char buf[35]; char buf1[35]; char buf2[35]; char buf3[35]; char buf4[35]; char buf5[35]; char buf6[35]; char buf7[35]; char buf8[35]; char buf9[35]; char buf10[35]; char* size = itoa(ImageInfo.FileSize,buf); char* width = itoa(ImageInfo.Width, buf1); char* height = itoa(ImageInfo.Height, buf2); char Temp[20]; FileTimeAsString(Temp); const char* largest_offset = itoa(ImageInfo.LargestExifOffset, buf3); const char* thumbnail_size = itoa(ImageInfo.ThumbnailSize, buf4); const char* ThumbnailOffset = itoa(ImageInfo.ThumbnailOffset, buf5); const char* image_xdensity = itoa(ImageInfo.JfifHeader.XDensity, buf6); const char* image_ydensity = itoa(ImageInfo.JfifHeader.XDensity, buf7); const char* zoom = itoa(ImageInfo.DigitalZoomRatio, buf8); const char* iso = itoa(ImageInfo.ISOequivalent, buf9); const char* distance = itoa(ImageInfo.DistanceRange, buf10); float value = ImageInfo.ExposureTime; char *str = (char*)malloc(20); sprintf(str, "%f\n", value); float value2 = ImageInfo.ApertureFNumber; char *str2 = (char*)malloc(20); sprintf(str2, "f/%3.1f" , value2); float value3 = ImageInfo.FocalLength35mmEquiv; char *str3 = (char*)malloc(20); sprintf(str3, "f(35)=%dmm" , value3); init_list(win->list); add_to_list(win->list, "File name: ", ImageInfo.FileName); add_to_list(win->list, "File size (bytes) :", size); add_to_list(win->list, "File date: ", Temp); if (ImageInfo.CameraMake[0]){ add_to_list(win->list, "Camera make: ", ImageInfo.CameraMake); add_to_list(win->list, "Camer model: ", ImageInfo.CameraModel); } add_to_list(win->list, "Date time: ", ctime(&ImageInfo.FileDateTime)); if (ImageInfo.IsColor == 0) { add_to_list(win->list, "Color/bw: ", "Black and White"); } else { add_to_list(win->list, "Color/bw: ", "Non Black and White"); } add_to_list(win->list, "Image type :", "image/jpg"); add_to_list(win->list, "Image Width: ", width); add_to_list(win->list, "Image Height: ",height); add_to_list(win->list, "Largest Exif Offset: ", largest_offset); add_to_list(win->list, "Thumbnail size: ", thumbnail_size); add_to_list(win->list, "Thumbnail offset: ", ThumbnailOffset); add_to_list(win->list, "Image comments: ", ImageInfo.Comments); add_to_list(win->list, "Image X Density: ",image_xdensity); add_to_list(win->list, "Image Y Density: ", image_xdensity); add_to_list(win->list, "Digital zoom ratio: ", zoom); if (ImageInfo.FlashUsed > 0) add_to_list(win->list, "Flash used: ", "yes"); else add_to_list(win->list, "Flash used: ", "No"); add_to_list(win->list, "Exposure Time (s): ", str); add_to_list(win->list, "Aperture FNumber: ", str2); add_to_list(win->list, "Focal Length 35mm Equiv: ", str3); add_to_list(win->list, "ISOequivalent: ", iso); add_to_list(win->list, "Distance range: ", distance); switch(ImageInfo.ExposureProgram) { case 1: add_to_list(win->list, "Expusure: ", "manual"); break; case 2: add_to_list(win->list, "Expusure: ", "program (auto)"); break; case 3: add_to_list(win->list, "Expusure: ", "aperture priority (semi-auto)"); break; case 4: add_to_list(win->list, "Expusure: ", "shutter priority (semi-auto)"); break; case 5: add_to_list(win->list, "Expusure: ", "Creative Program (based towards depth of field)"); break; case 6: add_to_list(win->list, "Expusure: ", "Action program (based towards fast shutter speed)"); break; case 7: add_to_list(win->list, "Expusure: ", "Portrait Mode"); break; case 8: add_to_list(win->list, "Expusure: ", "LandscapeMode"); break; default: break; } if (ImageInfo.MeteringMode > 0)\ { switch(ImageInfo.MeteringMode) { case 1: add_to_list(win->list, "Metering Mode: ", "average"); break; case 2: add_to_list(win->list, "Metering Mode: ", "center weight"); break; case 3: add_to_list(win->list, "Metering Mode: ", "spot"); break; case 4: add_to_list(win->list, "Metering Mode: ", "multi spot"); break; case 5: add_to_list(win->list, "Metering Mode: ", "pattern"); break; case 6: printf("partial\n"); break; case 255: printf("other\n"); break; default: printf("unknown (%d)\n",ImageInfo.MeteringMode); break; } } g_signal_connect( win->exif_button, "clicked", G_CALLBACK(on_close), win ); gtk_container_add(GTK_CONTAINER(win->exif_window), GTK_WIDGET(win->box)); gtk_widget_show_all((GtkWidget*)win->exif_window); g_free(str); g_free(str2); g_free(str3); }
//-------------------------------------------------------------------------- // Do selected operations to one file at a time. //-------------------------------------------------------------------------- void ProcessFile(const char * FileName) { int Modified = FALSE; ReadMode_t ReadMode = READ_EXIF; CurrentFile = FileName; ResetJpgfile(); // Start with an empty image information structure. memset(&ImageInfo, 0, sizeof(ImageInfo)); ImageInfo.FlashUsed = -1; ImageInfo.MeteringMode = -1; // Store file date/time. { struct stat st; if (stat(FileName, &st) >= 0){ ImageInfo.FileDateTime = st.st_mtime; ImageInfo.FileSize = st.st_size; }else{ ErrFatal("No such file"); } } strncpy(ImageInfo.FileName, FileName, PATH_MAX); if (ApplyCommand){ // Applying a command is special - the headers from the file have to be // pre-read, then the command executed, and then the image part of the file read. if (!ReadJpegFile(FileName, READ_EXIF)) return; #ifdef MATTHIAS if (AutoResize){ // Automatic resize computation - to customize for each run... if (AutoResizeCmdStuff() == 0){ DiscardData(); return; } } #endif // MATTHIAS if (CheckFileSkip()){ DiscardData(); return; } DiscardAllButExif(); DoCommand(FileName); Modified = TRUE; ReadMode = READ_IMAGE; // Don't re-read exif section again on next read. }else if (ExifXferScrFile){ char RelativeExifName[PATH_MAX+1]; // Make a relative name. RelativeName(RelativeExifName, ExifXferScrFile, FileName); if(!ReadJpegFile(RelativeExifName, READ_EXIF)) return; DiscardAllButExif(); // Don't re-read exif section again on next read. Modified = TRUE; ReadMode = READ_IMAGE; } FilesMatched += 1; FilesMatched = TRUE; // Turns off complaining that nothing matched. if (DoModify){ ReadMode |= READ_IMAGE; } if (!ReadJpegFile(FileName, ReadMode)) return; if (CheckFileSkip()){ DiscardData(); return; } if (ShowConcise){ ShowConciseImageInfo(); }else{ if (!(DoModify || DoReadAction) || ShowTags){ if (DoN3) { ShowImageInfoInN3(); } else { ShowImageInfo(); } } } if (ThumbnailName){ if (ImageInfo.ThumbnailPointer){ FILE * ThumbnailFile; char OutFileName[PATH_MAX+1]; // Make a relative name. RelativeName(OutFileName, ThumbnailName, FileName); #ifndef _WIN32 if (strcmp(ThumbnailName, "-") == 0){ // A filename of '-' indicates thumbnail goes to stdout. // This doesn't make much sense under Windows, so this feature is unix only. ThumbnailFile = stdout; }else #endif { ThumbnailFile = fopen(OutFileName,"wb"); } if (ThumbnailFile){ fwrite(ImageInfo.ThumbnailPointer, ImageInfo.ThumbnailSize ,1, ThumbnailFile); fclose(ThumbnailFile); if (ThumbnailFile != stdout){ printf("Created: '%s'\n", OutFileName); }else{ // No point in printing to stdout when that is where the thumbnail goes! } }else{ ErrFatal("Could not write thumbnail file"); } }else{ printf("Image '%s' contains no thumbnail\n",FileName); } } #ifdef MATTHIAS if (EditComment || CommentInsertfileName || AddComment || RemComment){ #else if (EditComment || CommentInsertfileName){ #endif Section_t * CommentSec; char Comment[1000]; int CommentSize; CommentSec = FindSection(M_COM); if (CommentSec == NULL){ unsigned char * DummyData; DummyData = (uchar *) malloc(3); DummyData[0] = 0; DummyData[1] = 2; DummyData[2] = 0; CommentSec = CreateSection(M_COM, DummyData, 2); } CommentSize = CommentSec->Size-2; if (CommentInsertfileName){ // Read a new comment section from file. char CommentFileName[PATH_MAX+1]; FILE * CommentFile; // Make a relative name. RelativeName(CommentFileName, CommentInsertfileName, FileName); CommentFile = fopen(CommentFileName,"r"); if (CommentFile == NULL){ printf("Could not open '%s'\n",CommentFileName); }else{ // Read it in. // Replace the section. CommentSize = fread(Comment, 1, 999, CommentFile); fclose(CommentFile); if (CommentSize < 0) CommentSize = 0; } }else{ #ifdef MATTHIAS if (ModifyDescriptComment(Comment, (char *)CommentSec->Data+2)){ Modified = TRUE; CommentSize = strlen(Comment); } if (EditComment) #else memcpy(Comment, (char *)CommentSec->Data+2, CommentSize); #endif { char EditFileName[PATH_MAX+4]; strcpy(EditFileName, FileName); strcat(EditFileName, ".txt"); CommentSize = FileEditComment(EditFileName, Comment, CommentSize); } } if (strcmp(Comment, (char *)CommentSec->Data+2)){ // Discard old comment section and put a new one in. int size; size = CommentSize+2; free(CommentSec->Data); CommentSec->Size = size; CommentSec->Data = malloc(size); CommentSec->Data[0] = (uchar)(size >> 8); CommentSec->Data[1] = (uchar)(size); memcpy((CommentSec->Data)+2, Comment, size-2); Modified = TRUE; } if (!Modified){ printf("Comment not modified\n"); } }