Пример #1
0
	static void saveAttributes(JNIEnv *env, jobject jobj, jstring jfilename, jstring jattributes)
	{
		LOGI("******************************** saveAttributes");

		// 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;
		}

		// Get the number of attributes - it's the first number in the string.
		attrCnt = atoi(attributes);
		char* attrPtr = strchr(attributes, ' ') + 1;

		LOGD("attribute count %d attrPtr %s\n", attrCnt, attrPtr);

		// Load all the hash exif elements into a more c-like structure
		exifElementTable = malloc(sizeof(ExifElement_t) * attrCnt);
		if (exifElementTable == NULL)
		{
			goto exit;
		}


		int i;
		char tag[100];
		int hasDateTimeTag = FALSE;
		int gpsTagCount = 0;
		int exifTagCount = 0;
		int tagValue;
		int tagFound;
		ExifElement_t* item;

		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
			tagFound = 0;
			char* tagEnd = strchr(attrPtr, '=');
			if (tagEnd == 0)
			{
				LOGE("saveAttributes: couldn't find end of tag");
				goto exit;
			}
			if (tagEnd - attrPtr > 99)
			{
				LOGE("saveAttributes: attribute tag way too long");
				goto exit;
			}

			memcpy(tag, attrPtr, tagEnd - attrPtr);
			tag[tagEnd - attrPtr] = 0;

			exifElementTable[i].Format = 0;
			exifElementTable[i].Tag = 0;
			exifElementTable[i].GpsTag = FALSE;

			if (IsGpsTag(tag))
			{
				tagValue = GpsTagNameToValue(tag);
				if( tagValue > -1 )
				{
					LOGV("Tag '%s' with value: X%x", tag, tagValue);
					exifElementTable[i].GpsTag = TRUE;
					exifElementTable[i].Tag = GpsTagNameToValue(tag);
					++gpsTagCount;
					tagFound = 1;
				} else {
					LOGE("(GPS) Skipping gps tag: %s = %i", tag, tagValue);
				}
			} else
			{
				tagValue = TagNameToValue(tag);
				if( tagValue > -1 )
				{
					LOGV("Tag '%s' with value: X%x", tag, tagValue);
					exifElementTable[i].GpsTag = FALSE;
					exifElementTable[i].Tag = tagValue;
					++exifTagCount;
					tagFound = 1;
				} else {
					LOGE("(EXIF) Skipping tag %s = %i", tag, tagValue);
				}
			}

			LOGV("tagFound: %i", tagFound);

			attrPtr = tagEnd + 1;
			// next get the length of the attribute value
			int valueLen = atoi(attrPtr);

			if (IsDateTimeTag(exifElementTable[i].Tag))
			{
				hasDateTimeTag = TRUE;
			}


			attrPtr = strchr(attrPtr, ' ') + 1;
			if (attrPtr == 0)
			{
				LOGE("saveAttributes: couldn't find end of value len");
				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;

			LOGD("tag %s id %d value %s data length=%d isGps=%d", tag, exifElementTable[i].Tag,
					exifElementTable[i].Value, exifElementTable[i].DataLength, exifElementTable[i].GpsTag);
		}

		LOGD("Total tags: %i - %i ( total was: %i )", exifTagCount, gpsTagCount, attrCnt);

		filename = (*env)->GetStringUTFChars(env, jfilename, NULL);
		LOGD("Call loadAttributes() with filename is %s. Loading exif info\n", filename);
		loadExifInfo(filename, TRUE);

		// DEBUG ONLY ----------
		// ShowTags = TRUE;
		// ShowImageInfo(TRUE);
		// LOGD("create exif 2");
		// ---------------------

		// 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_Elements(exifElementTable, exifTagCount, gpsTagCount, attrCnt, hasDateTimeTag);

		if (thumbnailData)
		{
			copyThumbnailData(thumbnailData, thumbnailLength);
		}

		exit:
		LOGE("cleaning up now in saveAttributes");
		// 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);
		}

		LOGD("returning from saveAttributes");
	}
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");
}