// returns new buffer length static int addKeyValueDouble(char** buf, int bufLen, const char* key, double value, const char* format) { char valueStr[30]; snprintf(valueStr, 30, format, value); return addKeyValueString(buf, bufLen, key, valueStr); }
static jstring getAttributes(JNIEnv *env, jobject jobj, jstring jfilename) { #ifdef SUPERDEBUG ALOGE("******************************** getAttributes\n"); #endif const char* filename = (*env)->GetStringUTFChars(env, jfilename, NULL); loadExifInfo(filename, FALSE); #ifdef SUPERDEBUG ShowImageInfo(TRUE); #endif (*env)->ReleaseStringUTFChars(env, jfilename, filename); attributeCount = 0; #ifdef REALLOCTEST int bufLen = 5; #else int bufLen = 1000; #endif char* buf = malloc(bufLen); if (buf == NULL) { return NULL; } *buf = 0; // start the string out at zero length // save a fake "hasThumbnail" tag to pass to the java ExifInterface bufLen = addKeyValueString(&buf, bufLen, "hasThumbnail", ImageInfo.ThumbnailOffset == 0 || ImageInfo.ThumbnailAtEnd == FALSE || ImageInfo.ThumbnailSize == 0 ? "false" : "true"); if (bufLen == 0) return NULL; if (ImageInfo.CameraMake[0]) { bufLen = addKeyValueString(&buf, bufLen, "Make", ImageInfo.CameraMake); if (bufLen == 0) return NULL; } if (ImageInfo.CameraModel[0]) { bufLen = addKeyValueString(&buf, bufLen, "Model", ImageInfo.CameraModel); if (bufLen == 0) return NULL; } if (ImageInfo.DateTime[0]) { bufLen = addKeyValueString(&buf, bufLen, "DateTime", ImageInfo.DateTime); if (bufLen == 0) return NULL; } if (ImageInfo.DigitizedTime[0]) { bufLen = addKeyValueString(&buf, bufLen, "DateTimeDigitized", ImageInfo.DigitizedTime); if (bufLen == 0) return NULL; } if (ImageInfo.SubSecTime[0]) { bufLen = addKeyValueString(&buf, bufLen, "SubSecTime", ImageInfo.SubSecTime); if (bufLen == 0) return NULL; } if (ImageInfo.SubSecTimeOrig[0]) { bufLen = addKeyValueString(&buf, bufLen, "SubSecTimeOriginal", ImageInfo.SubSecTimeOrig); if (bufLen == 0) return NULL; } if (ImageInfo.SubSecTimeDig[0]) { bufLen = addKeyValueString(&buf, bufLen, "SubSecTimeDigitized", ImageInfo.SubSecTimeDig); if (bufLen == 0) return NULL; } bufLen = addKeyValueInt(&buf, bufLen, "ImageWidth", ImageInfo.Width); if (bufLen == 0) return NULL; bufLen = addKeyValueInt(&buf, bufLen, "ImageLength", ImageInfo.Height); if (bufLen == 0) return NULL; bufLen = addKeyValueInt(&buf, bufLen, "Orientation", ImageInfo.Orientation); if (bufLen == 0) return NULL; if (ImageInfo.FlashUsed >= 0) { bufLen = addKeyValueInt(&buf, bufLen, "Flash", ImageInfo.FlashUsed); if (bufLen == 0) return NULL; } if (ImageInfo.FocalLength.num != 0 && ImageInfo.FocalLength.denom != 0) { bufLen = addKeyValueRational(&buf, bufLen, "FocalLength", ImageInfo.FocalLength); if (bufLen == 0) return NULL; } if (ImageInfo.DigitalZoomRatio > 1.0){ // Digital zoom used. Shame on you! bufLen = addKeyValueDouble(&buf, bufLen, "DigitalZoomRatio", ImageInfo.DigitalZoomRatio, "%1.3f"); if (bufLen == 0) return NULL; } if (ImageInfo.ExposureTime){ const char* format; if (ImageInfo.ExposureTime < 0.010){ format = "%6.4f"; } else { format = "%5.3f"; } bufLen = addKeyValueDouble(&buf, bufLen, "ExposureTime", (double)ImageInfo.ExposureTime, format); if (bufLen == 0) return NULL; } if (ImageInfo.ApertureFNumber){ bufLen = addKeyValueDouble(&buf, bufLen, "FNumber", (double)ImageInfo.ApertureFNumber, "%3.3f"); if (bufLen == 0) return NULL; } if (ImageInfo.Distance){ bufLen = addKeyValueDouble(&buf, bufLen, "SubjectDistance", (double)ImageInfo.Distance, "%4.2f"); if (bufLen == 0) return NULL; } if (ImageInfo.ISOequivalent){ bufLen = addKeyValueInt(&buf, bufLen, "ISOSpeedRatings", ImageInfo.ISOequivalent); if (bufLen == 0) return NULL; } if (ImageInfo.ExposureBias){ // If exposure bias was specified, but set to zero, presumably its no bias at all, // so only show it if its nonzero. bufLen = addKeyValueDouble(&buf, bufLen, "ExposureBiasValue", (double)ImageInfo.ExposureBias, "%4.2f"); if (bufLen == 0) return NULL; } if (ImageInfo.Whitebalance >= 0) { bufLen = addKeyValueInt(&buf, bufLen, "WhiteBalance", ImageInfo.Whitebalance); if (bufLen == 0) return NULL; } bufLen = addKeyValueInt(&buf, bufLen, "LightSource", ImageInfo.LightSource); if (bufLen == 0) return NULL; if (ImageInfo.MeteringMode) { bufLen = addKeyValueInt(&buf, bufLen, "MeteringMode", ImageInfo.MeteringMode); if (bufLen == 0) return NULL; } if (ImageInfo.ExposureProgram) { bufLen = addKeyValueInt(&buf, bufLen, "ExposureProgram", ImageInfo.ExposureProgram); if (bufLen == 0) return NULL; } if (ImageInfo.ExposureMode) { bufLen = addKeyValueInt(&buf, bufLen, "ExposureMode", ImageInfo.ExposureMode); if (bufLen == 0) return NULL; } if (ImageInfo.GpsInfoPresent) { if (ImageInfo.GpsLatRaw[0]) { bufLen = addKeyValueString(&buf, bufLen, "GPSLatitude", ImageInfo.GpsLatRaw); if (bufLen == 0) return NULL; } if (ImageInfo.GpsLatRef[0]) { bufLen = addKeyValueString(&buf, bufLen, "GPSLatitudeRef", ImageInfo.GpsLatRef); if (bufLen == 0) return NULL; } if (ImageInfo.GpsLongRaw[0]) { bufLen = addKeyValueString(&buf, bufLen, "GPSLongitude", ImageInfo.GpsLongRaw); if (bufLen == 0) return NULL; } if (ImageInfo.GpsLongRef[0]) { bufLen = addKeyValueString(&buf, bufLen, "GPSLongitudeRef", ImageInfo.GpsLongRef); if (bufLen == 0) return NULL; } if (ImageInfo.GpsAlt[0]) { bufLen = addKeyValueRational(&buf, bufLen, "GPSAltitude", ImageInfo.GpsAltRaw); bufLen = addKeyValueInt(&buf, bufLen, "GPSAltitudeRef", ImageInfo.GpsAltRef); if (bufLen == 0) return NULL; } if (ImageInfo.GpsDateStamp[0]) { bufLen = addKeyValueString(&buf, bufLen, "GPSDateStamp", ImageInfo.GpsDateStamp); if (bufLen == 0) return NULL; } if (ImageInfo.GpsTimeStamp[0]) { bufLen = addKeyValueString(&buf, bufLen, "GPSTimeStamp", ImageInfo.GpsTimeStamp); if (bufLen == 0) return NULL; } if (ImageInfo.GpsProcessingMethod[0]) { bufLen = addKeyValueString(&buf, bufLen, "GPSProcessingMethod", ImageInfo.GpsProcessingMethod); if (bufLen == 0) return NULL; } } if (ImageInfo.Comments[0]) { bufLen = addKeyValueString(&buf, bufLen, "UserComment", ImageInfo.Comments); if (bufLen == 0) return NULL; } // put the attribute count at the beginnnig of the string int finalBufLen = strlen(buf) + 20; char* finalResult = malloc(finalBufLen); if (finalResult == NULL) { free(buf); return NULL; } snprintf(finalResult, finalBufLen, "%d %s", attributeCount, buf); int k; for (k = 0; k < finalBufLen; k++) if (!isascii(finalResult[k])) finalResult[k] = '?'; free(buf); #ifdef SUPERDEBUG ALOGE("*********Returning result \"%s\"", finalResult); #endif jstring result = ((*env)->NewStringUTF(env, finalResult)); free(finalResult); DiscardData(); return result; }
// returns new buffer length static int addKeyValueInt(char** buf, int bufLen, const char* key, int value) { char valueStr[20]; snprintf(valueStr, 20, "%d", value); return addKeyValueString(buf, bufLen, key, valueStr); }
// Returns new buffer length. Rational value will be appended as "numerator/denominator". static int addKeyValueRational(char** buf, int bufLen, const char* key, rat_t value) { char valueStr[25]; snprintf(valueStr, sizeof(valueStr), "%u/%u", value.num, value.denom); return addKeyValueString(buf, bufLen, key, valueStr); }