void writeExif( void *origData, void *destData , int origSize , uint32_t *resultSize, int orientation,camera_position_type *pt, int wb, int ledm ) { const char *filename = "/cache/tmp/temp.jpg"; dump_to_file( filename, (uint8_t *)origData, origSize ); LOGV("WRITE EXIF Filename %s", filename); chmod( filename, S_IRWXU ); ResetJpgfile(); memset(&ImageInfo, 0, sizeof(ImageInfo)); ImageInfo.MeteringMode = -1; int gpsTag = 0; if( pt != NULL ) { LOGV("EXIF ADD GPS DATA ........"); gpsTag = 6; } else{ LOGV("EXIF NO GPS ........"); } ExifElement_t *t = (ExifElement_t *)malloc( sizeof(ExifElement_t)*(EXIF_TOTAL_DATA+gpsTag) ); ExifElement_t *it = t; // Store file date/time. (*it).Tag = TAG_ORIENTATION; (*it).Format = FMT_USHORT; (*it).DataLength = 1; unsigned short v; LOGV("EXIF Orientation %d", orientation); if( orientation == 90 ) { (*it).Value = "6\0"; } else if( orientation == 180 ) { (*it).Value = "3\0"; } else { (*it).Value = "1\0"; } (*it).GpsTag = FALSE; it++; (*it).Tag = TAG_MAKE; (*it).Format = FMT_STRING; (*it).Value = "Motorola\0"; (*it).DataLength = strlen((*it).Value); (*it).GpsTag = FALSE; it++; (*it).Tag = TAG_MODEL; (*it).Format = FMT_STRING; (*it).Value = "MB200 with CyanogenMOD\0"; (*it).DataLength = strlen((*it).Value); (*it).GpsTag = FALSE; it++; (*it).Tag = TAG_FLASH; (*it).Format = FMT_USHORT; (*it).Value = (ledm ? "1\0" : "0\0"); (*it).DataLength = 1; (*it).GpsTag = FALSE; it++; (*it).Tag = TAG_WHITEBALANCE; (*it).Format = FMT_USHORT; (*it).Value = (wb ? "1\0" : "0\0"); (*it).DataLength = 1; (*it).GpsTag = FALSE; if( pt != NULL ) { LOGV("pt->latitude == %f", pt->latitude ); LOGV("pt->longitude == %f", pt->longitude ); LOGV("pt->altitude == %d", pt->altitude ); it++; (*it).Tag = 0x01; (*it).Format = FMT_STRING; if( pt->latitude > 0 ) { (*it).Value = "N\0"; } else { (*it).Value = "S\0"; } (*it).DataLength = 2; (*it).GpsTag = TRUE; it++; (*it).Value = coord2degminsec( pt->latitude ); LOGV("writeExif: latitude is: %s", (*it).Value); (*it).Tag = 0x02; (*it).Format = FMT_URATIONAL; (*it).DataLength = 3; (*it).GpsTag = TRUE; it++; (*it).Tag = 0x03; (*it).Format = FMT_STRING; if( (*pt).longitude > 0 ) { (*it).Value = "E\0"; } else { (*it).Value = "W\0"; } (*it).DataLength = 2; (*it).GpsTag = TRUE; it++; (*it).Value = coord2degminsec( pt->longitude ); LOGV("writeExif: longitude is: %s", (*it).Value); (*it).Tag = 0x04; (*it).Format = FMT_URATIONAL; (*it).DataLength = 3; (*it).GpsTag = TRUE; it++; (*it).Tag = 0x05; (*it).Format = FMT_USHORT; if( (*pt).altitude > 0 ) { (*it).Value = "0\0"; } else { (*it).Value = "1\0"; } (*it).DataLength = 1; (*it).GpsTag = TRUE; it++; (*it).Value = float2rationnal( fabs( pt->altitude ) ); LOGV("writeExif: altitude is: %s", (*it).Value); (*it).Tag = 0x06; (*it).Format = FMT_SRATIONAL; (*it).DataLength = 1; (*it).GpsTag = TRUE; } { struct stat st; if (stat(filename, &st) >= 0) { ImageInfo.FileDateTime = st.st_mtime; ImageInfo.FileSize = st.st_size; } } strncpy(ImageInfo.FileName, filename, PATH_MAX); LOGV("Image EXIF Filename %s", filename); ReadMode_t ReadMode; ReadMode = READ_METADATA; ReadMode |= READ_IMAGE; int res = ReadJpegFile(filename, (ReadMode_t)ReadMode ); LOGV("READ EXIF Filename %s", filename); create_EXIF( t, EXIF_TOTAL_DATA, gpsTag); WriteJpegFile(filename); chmod( filename, S_IRWXU ); DiscardData(); FILE *src; src = fopen( filename, "r"); fseek( src, 0L, SEEK_END ); (*resultSize) = ftell(src); fseek( src, 0L, SEEK_SET ); int read = fread( destData, 1, (*resultSize), src ); free( t ); unlink( filename ); }
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); }
static void saveAttributes(JNIEnv *env, jobject jobj, jstring jfilename, jstring jattributes) { #ifdef SUPERDEBUG LOGE("******************************** saveAttributes\n"); #endif // format of attributes string passed from java: // "attrCnt attr1=valueLen value1attr2=value2Len value2..." // example input: "4 ImageLength=4 1024Model=6 FooImageWidth=4 1280Make=3 FOO" ExifElement_t* exifElementTable = NULL; const char* filename = NULL; uchar* thumbnailData = NULL; int attrCnt = 0; const char* attributes = (*env)->GetStringUTFChars(env, jattributes, NULL); if (attributes == NULL) { goto exit; } #ifdef SUPERDEBUG LOGE("attributes %s\n", attributes); #endif // Get the number of attributes - it's the first number in the string. attrCnt = atoi(attributes); char* attrPtr = strchr(attributes, ' ') + 1; #ifdef SUPERDEBUG LOGE("attribute count %d attrPtr %s\n", attrCnt, attrPtr); #endif // Load all the hash exif elements into a more c-like structure exifElementTable = malloc(sizeof(ExifElement_t) * attrCnt); if (exifElementTable == NULL) { goto exit; } #ifdef OUTOFMEMORYTEST1 goto exit; #endif int i; char tag[100]; int gpsTagCount = 0; int exifTagCount = 0; for (i = 0; i < attrCnt; i++) { // get an element from the attribute string and add it to the c structure // first, extract the attribute name char* tagEnd = strchr(attrPtr, '='); if (tagEnd == 0) { #ifdef SUPERDEBUG LOGE("saveAttributes: couldn't find end of tag"); #endif goto exit; } if (tagEnd - attrPtr > 99) { #ifdef SUPERDEBUG LOGE("saveAttributes: attribute tag way too long"); #endif goto exit; } memcpy(tag, attrPtr, tagEnd - attrPtr); tag[tagEnd - attrPtr] = 0; if (IsGpsTag(tag)) { exifElementTable[i].GpsTag = TRUE; exifElementTable[i].Tag = GpsTagNameToValue(tag); ++gpsTagCount; } else { exifElementTable[i].GpsTag = FALSE; exifElementTable[i].Tag = TagNameToValue(tag); ++exifTagCount; } attrPtr = tagEnd + 1; // next get the length of the attribute value int valueLen = atoi(attrPtr); attrPtr = strchr(attrPtr, ' ') + 1; if (attrPtr == 0) { #ifdef SUPERDEBUG LOGE("saveAttributes: couldn't find end of value len"); #endif goto exit; } exifElementTable[i].Value = malloc(valueLen + 1); if (exifElementTable[i].Value == NULL) { goto exit; } memcpy(exifElementTable[i].Value, attrPtr, valueLen); exifElementTable[i].Value[valueLen] = 0; exifElementTable[i].DataLength = valueLen; attrPtr += valueLen; #ifdef SUPERDEBUG LOGE("tag %s id %d value %s data length=%d isGps=%d", tag, exifElementTable[i].Tag, exifElementTable[i].Value, exifElementTable[i].DataLength, exifElementTable[i].GpsTag); #endif } filename = (*env)->GetStringUTFChars(env, jfilename, NULL); #ifdef SUPERDEBUG LOGE("Call loadAttributes() with filename is %s. Loading exif info\n", filename); #endif loadExifInfo(filename, TRUE); #ifdef SUPERDEBUG // DumpExifMap = TRUE; ShowTags = TRUE; ShowImageInfo(TRUE); LOGE("create exif 2"); #endif // If the jpg file has a thumbnail, preserve it. int thumbnailLength = ImageInfo.ThumbnailSize; if (ImageInfo.ThumbnailOffset) { Section_t* ExifSection = FindSection(M_EXIF); if (ExifSection) { uchar* thumbnailPointer = ExifSection->Data + ImageInfo.ThumbnailOffset + 8; thumbnailData = (uchar*)malloc(ImageInfo.ThumbnailSize); // if the malloc fails, we just won't copy the thumbnail if (thumbnailData) { memcpy(thumbnailData, thumbnailPointer, thumbnailLength); } } } create_EXIF(exifElementTable, exifTagCount, gpsTagCount); if (thumbnailData) { copyThumbnailData(thumbnailData, thumbnailLength); } exit: #ifdef SUPERDEBUG LOGE("cleaning up now in saveAttributes"); #endif // try to clean up resources if (attributes) { (*env)->ReleaseStringUTFChars(env, jattributes, attributes); } if (filename) { (*env)->ReleaseStringUTFChars(env, jfilename, filename); } if (exifElementTable) { // free the table for (i = 0; i < attrCnt; i++) { free(exifElementTable[i].Value); } free(exifElementTable); } if (thumbnailData) { free(thumbnailData); } #ifdef SUPERDEBUG LOGE("returning from saveAttributes"); #endif // Temporarily saving these commented out lines because they represent a lot of figuring out // patterns for JNI. // // Get link to Method "entrySet" // jmethodID entrySetMethod = (*env)->GetMethodID(env, jclass_of_hashmap, "entrySet", "()Ljava/util/Set;"); // // // Invoke the "entrySet" method on the HashMap object // jobject jobject_of_entryset = (*env)->CallObjectMethod(env, hashMap, entrySetMethod); // // // Get the Set Class // jclass jclass_of_set = (*env)->FindClass(env, "java/util/Set"); // // if (jclass_of_set == 0) { // printf("java/util/Set lookup failed\n"); // return; // } // // // Get link to Method "iterator" // jmethodID iteratorMethod = (*env)->GetMethodID(env, jclass_of_set, "iterator", "()Ljava/util/Iterator;"); // // // Invoke the "iterator" method on the jobject_of_entryset variable of type Set // jobject jobject_of_iterator = (*env)->CallObjectMethod(env, jobject_of_entryset, iteratorMethod); // // // Get the "Iterator" class // jclass jclass_of_iterator = (*env)->FindClass(env, "java/util/Iterator"); // // // Get link to Method "hasNext" // jmethodID hasNextMethod = (*env)->GetMethodID(env, jclass_of_iterator, "hasNext", "()Z"); // // // Invoke - Get the value hasNextMethod // jboolean bHasNext = (*env)->CallBooleanMethod(env, jobject_of_iterator, hasNextMethod); // // Get link to Method "hasNext" // jmethodID nextMethod = (*env)->GetMethodID(env, jclass_of_iterator, "next", "()Ljava/util/Map/Entry;"); // // jclass jclass_of_mapentry = (*env)->FindClass(env, "java/util/Map/Entry"); // // jmethodID getKeyMethod = (*env)->GetMethodID(env, jclass_of_mapentry, "getKey", "()Ljava/lang/Object"); // // jmethodID getValueMethod = (*env)->GetMethodID(env, jclass_of_mapentry, "getValue", "()Ljava/lang/Object"); }