Пример #1
0
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 );
}
Пример #2
0
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");
}