static jbyteArray getThumbnail(JNIEnv *env, jobject jobj, jstring jfilename) { LOGI("getThumbnail"); const char* filename = (*env)->GetStringUTFChars(env, jfilename, NULL); if (filename) { loadExifInfo(filename, FALSE); Section_t* ExifSection = FindSection(M_EXIF); if (ExifSection == NULL || ImageInfo.ThumbnailSize == 0) { LOGE("no exif section or size == 0, so no thumbnail\n"); goto noThumbnail; } uchar* thumbnailPointer = ExifSection->Data + ImageInfo.ThumbnailOffset + 8; jbyteArray byteArray = (*env)->NewByteArray(env, ImageInfo.ThumbnailSize); if (byteArray == NULL) { LOGE("couldn't allocate thumbnail memory, so no thumbnail\n"); goto noThumbnail; } (*env)->SetByteArrayRegion(env, byteArray, 0, ImageInfo.ThumbnailSize, thumbnailPointer); LOGD("thumbnail size %d\n", ImageInfo.ThumbnailSize); (*env)->ReleaseStringUTFChars(env, jfilename, filename); DiscardData(); return byteArray; } noThumbnail: if (filename) { (*env)->ReleaseStringUTFChars(env, jfilename, filename); } DiscardData(); return NULL; }
//-------------------------------------------------------------------------- // process a EXIF jpeg file //-------------------------------------------------------------------------- bool ExifData::scan(const QString & path) { int ret; QFile f(path); if ( !f.open(IO_ReadOnly) ) return false; try { // Scan the JPEG headers. ret = ReadJpegSections(f, READ_EXIF); } catch (FatalError& e) { e.debug_print(); f.close(); return false; } if (ret == false) { kdDebug(7034) << "Not JPEG file!\n"; DiscardData(); f.close(); return false; } f.close(); DiscardData(); //now make the strings clean, // for exmaple my Casio is a "QV-4000 " CameraMake = CameraMake.stripWhiteSpace(); CameraModel = CameraModel.stripWhiteSpace(); UserComment = UserComment.stripWhiteSpace(); Comment = Comment.stripWhiteSpace(); return true; }
//-------------------------------------------------------------------------- // Read image data. //-------------------------------------------------------------------------- int ReadJpegFile(const char * FileName, ReadMode_t ReadMode) { FILE * infile; int ret; infile = fopen(FileName, "rb"); // Unix ignores 'b', windows needs it. if (infile == NULL) { fprintf(stderr, "can't open '%s'\n", FileName); return FALSE; } // Scan the JPEG headers. ret = ReadJpegSections(infile, ReadMode); if (!ret){ if (ReadMode == READ_ANY){ // Process any files mode. Ignore the fact that it's not // a jpeg file. ret = TRUE; }else{ fprintf(stderr,"Not JPEG: %s\n",FileName); } } fclose(infile); if (ret == FALSE){ DiscardData(); } return ret; }
//-------------------------------------------------------------------------- // Read image data. //-------------------------------------------------------------------------- int ReadJpegFile(const char * FileName, ReadMode_t ReadMode) { FILE * infile; int ret; infile = fopen(FileName, "rb"); // Unix ignores 'b', windows needs it. if (infile == NULL) { ALOGE("can't open '%s'", FileName); fprintf(stderr, "can't open '%s'\n", FileName); return FALSE; } // Scan the JPEG headers. printf("ReadJpegSections"); ret = ReadJpegSections(infile, ReadMode); if (!ret){ ALOGV("Cannot parse JPEG sections for file: %s", FileName); fprintf(stderr,"Not JPEG: %s\n",FileName); } fclose(infile); if (ret == FALSE){ DiscardData(); } return ret; }
//-------------------------------------------------------------------------- // Read image data. //-------------------------------------------------------------------------- int ReadJpegFile(const char * FileName, ReadMode_t ReadMode) { FILE * infile; int ret; infile = fopen(FileName, "rb"); // Unix ignores 'b', windows needs it. if (infile == NULL) { fprintf(stderr, "can't open '%s'\n", FileName); return FALSE; } // Scan the JPEG headers. ret = ReadJpegSections(infile, ReadMode); #ifdef VERBOSE if (!ret){ printf("Not JPEG: %s\n",FileName); } #endif fclose(infile); if (ret == FALSE){ DiscardData(); } return ret; }
// This is a private method; ensure FixHeader is called (or used_ is well defined) // beforehand char* STRING::ensure_cstr(inT32 min_capacity) { STRING_HEADER* orig_header = GetHeader(); if (min_capacity <= orig_header->capacity_) return ((char *)this->data_) + sizeof(STRING_HEADER); // if we are going to grow bigger, than double our existing // size, but if that still is not big enough then keep the // requested capacity if (min_capacity < 2 * orig_header->capacity_) min_capacity = 2 * orig_header->capacity_; int alloc = sizeof(STRING_HEADER) + min_capacity; STRING_HEADER* new_header = (STRING_HEADER*)(alloc_string(alloc)); memcpy(&new_header[1], GetCStr(), orig_header->used_); new_header->capacity_ = min_capacity; new_header->used_ = orig_header->used_; // free old memory, then rebind to new memory DiscardData(); data_ = new_header; assert(InvariantOk()); return ((char *)data_) + sizeof(STRING_HEADER); }
static jboolean appendThumbnail(JNIEnv *env, jobject jobj, jstring jfilename, jstring jthumbnailfilename) { #ifdef SUPERDEBUG LOGE("******************************** appendThumbnail\n"); #endif const char* filename = (*env)->GetStringUTFChars(env, jfilename, NULL); if (filename == NULL) { return JNI_FALSE; } const char* thumbnailfilename = (*env)->GetStringUTFChars(env, jthumbnailfilename, NULL); if (thumbnailfilename == NULL) { return JNI_FALSE; } #ifdef SUPERDEBUG LOGE("*******before actual call to ReplaceThumbnail\n"); ShowImageInfo(TRUE); #endif ReplaceThumbnail(thumbnailfilename); #ifdef SUPERDEBUG ShowImageInfo(TRUE); #endif (*env)->ReleaseStringUTFChars(env, jfilename, filename); (*env)->ReleaseStringUTFChars(env, jthumbnailfilename, thumbnailfilename); DiscardData(); return JNI_TRUE; }
static jlongArray getThumbnailRange(JNIEnv *env, jobject jobj, jstring jfilename) { jlongArray resultArray = NULL; const char* filename = (*env)->GetStringUTFChars(env, jfilename, NULL); if (filename) { loadExifInfo(filename, FALSE); Section_t* ExifSection = FindSection(M_EXIF); if (ExifSection == NULL || ImageInfo.ThumbnailSize == 0) { goto done; } jlong result[2]; result[0] = ExifSection->Offset + ImageInfo.ThumbnailOffset + 8; result[1] = ImageInfo.ThumbnailSize; resultArray = (*env)->NewLongArray(env, 2); if (resultArray == NULL) { goto done; } (*env)->SetLongArrayRegion(env, resultArray, 0, 2, result); } done: if (filename) { (*env)->ReleaseStringUTFChars(env, jfilename, filename); } DiscardData(); return resultArray; }
static void commitChanges(JNIEnv *env, jobject jobj, jstring jfilename) { #ifdef SUPERDEBUG LOGE("******************************** commitChanges\n"); #endif const char* filename = (*env)->GetStringUTFChars(env, jfilename, NULL); if (filename) { saveJPGFile(filename); DiscardData(); (*env)->ReleaseStringUTFChars(env, jfilename, filename); } }
int ReadJpegStream(ReadMode_t ReadMode, CALLBACK_js_getc js_getc, CALLBACK_js_read js_read) { int ret; printf("ReadJpegStream"); ret = ReadJpegStreamSections(ReadMode, js_getc, js_read); if (!ret){ ALOGE("ReadJpegStream Not JPEG"); fprintf(stderr,"Not JPEG"); } if (ret == FALSE){ DiscardData(); } return ret; }
STRING & STRING::operator=(const char* cstr) { STRING_HEADER* this_header = GetHeader(); if (cstr) { int len = strlen(cstr) + 1; this_header->used_ = 0; // dont bother copying data if need to realloc char* this_cstr = ensure_cstr(len); this_header = GetHeader(); // for realloc memcpy(this_cstr, cstr, len); this_header->used_ = len; } else { // Reallocate to same state as default constructor. DiscardData(); // Empty STRINGs contain just the "\0". memcpy(AllocData(1, kMinCapacity), "", 1); } assert(InvariantOk()); return *this; }
static jstring getAttributes(JNIEnv *env, jobject jobj, jstring jfilename) { LOGI("******************************** getAttributes"); const char* filename = (*env)->GetStringUTFChars(env, jfilename, NULL); LOGD("filename: %s", filename); loadExifInfo(filename, FALSE); // release the string (*env)->ReleaseStringUTFChars(env, jfilename, filename); attributeCount = 0; int bufLen = 1000; char* buf = malloc(bufLen); if (buf == NULL) { return NULL; } *buf = 0; // start the string out at zero length // ShowImageInfo(TRUE); // parse all attributes // thumbnail bufLen = addKeyValueString(&buf, bufLen, "hasThumbnail", ImageInfo.ThumbnailOffset == 0 || ImageInfo.ThumbnailAtEnd == FALSE || ImageInfo.ThumbnailSize == 0 ? "false" : "true"); if (bufLen == 0) return NULL; if( ImageInfo.Make[0] ) { bufLen = addKeyValueString( &buf, bufLen, "Make", ImageInfo.Make ); if( bufLen == 0 ) return NULL; } if( ImageInfo.Model[0] ) { bufLen = addKeyValueString( &buf, bufLen, "Model", ImageInfo.Model ); if( bufLen == 0 ) return NULL; } if( ImageInfo.DateTime[0] ) { bufLen = addKeyValueString( &buf, bufLen, "DateTime", ImageInfo.DateTime ); if( bufLen == 0 ) return NULL; } if( ImageInfo.DateTimeDigitized[0] ) { bufLen = addKeyValueString( &buf, bufLen, "DateTimeDigitized", ImageInfo.DateTimeDigitized ); if( bufLen == 0 ) return NULL; } if( ImageInfo.DateTimeOriginal[0] ) { bufLen = addKeyValueString( &buf, bufLen, "DateTimeOriginal", ImageInfo.DateTimeOriginal ); if( bufLen == 0 ) return NULL; } if( ImageInfo.Copyright[0] ) { bufLen = addKeyValueString( &buf, bufLen, "Copyright", ImageInfo.Copyright ); if( bufLen == 0 ) return NULL; } if( ImageInfo.Artist[0] ) { bufLen = addKeyValueString( &buf, bufLen, "Artist", ImageInfo.Artist ); if( bufLen == 0 ) return NULL; } if( ImageInfo.Software[0] ) { bufLen = addKeyValueString( &buf, bufLen, "Software", ImageInfo.Software ); if( bufLen == 0 ) return NULL; } if( ImageInfo.ImageWidth > 0 && ImageInfo.ImageLength > 0 ) { bufLen = addKeyValueInt(&buf, bufLen, "ImageWidth", ImageInfo.ImageWidth); if (bufLen == 0) return NULL; bufLen = addKeyValueInt(&buf, bufLen, "ImageLength", ImageInfo.ImageLength); if (bufLen == 0) return NULL; } if(ImageInfo.Orientation >= 0 ) { bufLen = addKeyValueInt(&buf, bufLen, "Orientation", ImageInfo.Orientation); if (bufLen == 0) return NULL; } if (ImageInfo.Flash >= 0) { bufLen = addKeyValueInt(&buf, bufLen, "Flash", ImageInfo.Flash); if (bufLen == 0) return NULL; } if (ImageInfo.FocalLength) { bufLen = addKeyValueDouble(&buf, bufLen, "FocalLength", ImageInfo.FocalLength, "%4.2f"); 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.FNumber > 0) { bufLen = addKeyValueDouble(&buf, bufLen, "FNumber", (double)ImageInfo.FNumber, "%3.1f"); if (bufLen == 0) return NULL; } if( ImageInfo.ApertureValue ) { bufLen = addKeyValueDouble(&buf, bufLen, "ApertureValue", (double)ImageInfo.ApertureValue, "%4.2f"); if (bufLen == 0) return NULL; } if(ImageInfo.BrightnessValue ) { bufLen = addKeyValueDouble(&buf, bufLen, "BrightnessValue", (double)ImageInfo.BrightnessValue, "%4.2f"); if (bufLen == 0) return NULL; } if(ImageInfo.MaxApertureValue) { bufLen = addKeyValueDouble(&buf, bufLen, "MaxApertureValue", (double)ImageInfo.MaxApertureValue, "%4.2f"); if (bufLen == 0) return NULL; } if (ImageInfo.SubjectDistance) { bufLen = addKeyValueDouble(&buf, bufLen, "SubjectDistance", (double)ImageInfo.SubjectDistance, "%4.2f"); if (bufLen == 0) return NULL; } if (ImageInfo.ExposureBiasValue) { bufLen = addKeyValueDouble(&buf, bufLen, "ExposureBiasValue", (double)ImageInfo.ExposureBiasValue, "%4.2f"); if (bufLen == 0) return NULL; } if (ImageInfo.DigitalZoomRatio > 1.0) { // Digital zoom used. Shame on you! (LOL) bufLen = addKeyValueDouble(&buf, bufLen, "DigitalZoomRatio", ImageInfo.DigitalZoomRatio, "%2.3f"); if (bufLen == 0) return NULL; } if( ImageInfo.FocalLengthIn35mmFilm ) { bufLen = addKeyValueInt(&buf, bufLen, "FocalLengthIn35mmFilm", ImageInfo.FocalLengthIn35mmFilm); if (bufLen == 0) return NULL; } if( ImageInfo.SensingMethod > 0 ) { bufLen = addKeyValueInt(&buf, bufLen, "SensingMethod", ImageInfo.SensingMethod); if (bufLen == 0) return NULL; } if( ImageInfo.Whitebalance >= 0 && ImageInfo.Whitebalance <= 1 ) { bufLen = addKeyValueInt(&buf, bufLen, "Whitebalance", ImageInfo.Whitebalance); if (bufLen == 0) return NULL; } if( ImageInfo.MeteringMode > 0 && ImageInfo.MeteringMode <= 255) { bufLen = addKeyValueInt(&buf, bufLen, "MeteringMode", ImageInfo.MeteringMode); if (bufLen == 0) return NULL; } // if(ImageInfo.CompressedBitsPerPixel) // { // bufLen = addKeyValueDouble(&buf, bufLen, "CompressedBitsPerPixel", (double)ImageInfo.CompressedBitsPerPixel, "%4.2f"); // if (bufLen == 0) return NULL; // } if (ImageInfo.ExposureProgram > 0) { bufLen = addKeyValueInt(&buf, bufLen, "ExposureProgram", ImageInfo.ExposureProgram); if (bufLen == 0) return NULL; } if (ImageInfo.ExposureMode >= 0) { bufLen = addKeyValueInt(&buf, bufLen, "ExposureMode", ImageInfo.ExposureMode); if (bufLen == 0) return NULL; } if (ImageInfo.ISOSpeedRatings) { bufLen = addKeyValueInt(&buf, bufLen, "ISOSpeedRatings", ImageInfo.ISOSpeedRatings); if (bufLen == 0) return NULL; } if(ImageInfo.LightSource >= 0) { bufLen = addKeyValueInt(&buf, bufLen, "LightSource", ImageInfo.LightSource); if (bufLen == 0) return NULL; } if(ImageInfo.SubjectDistanceRange > 0) { bufLen = addKeyValueInt(&buf, bufLen, "SubjectDistanceRange", ImageInfo.SubjectDistanceRange); if (bufLen == 0) return NULL; } if(ImageInfo.XResolution) { bufLen = addKeyValueDouble(&buf, bufLen, "XResolution", ImageInfo.XResolution, "%.2f"); if (bufLen == 0) return NULL; } if(ImageInfo.YResolution) { bufLen = addKeyValueDouble(&buf, bufLen, "YResolution", ImageInfo.YResolution, "%.2f"); if (bufLen == 0) return NULL; } if(ImageInfo.ResolutionUnit) { bufLen = addKeyValueInt(&buf, bufLen, "ResolutionUnit", ImageInfo.ResolutionUnit); if (bufLen == 0) return NULL; } if(ImageInfo.FocalPlaneXResolution) { bufLen = addKeyValueDouble(&buf, bufLen, "FocalPlaneXResolution", ImageInfo.FocalPlaneXResolution, "%.4f"); if (bufLen == 0) return NULL; } if(ImageInfo.FocalPlaneYResolution) { bufLen = addKeyValueDouble(&buf, bufLen, "FocalPlaneYResolution", ImageInfo.FocalPlaneYResolution, "%.4f"); if (bufLen == 0) return NULL; } if(ImageInfo.FocalPlaneResolutionUnit) { bufLen = addKeyValueInt(&buf, bufLen, "FocalPlaneResolutionUnit", ImageInfo.FocalPlaneResolutionUnit); if (bufLen == 0) return NULL; } if(ImageInfo.PixelXDimension) { bufLen = addKeyValueInt(&buf, bufLen, "PixelXDimension", ImageInfo.PixelXDimension); if (bufLen == 0) return NULL; } if(ImageInfo.PixelYDimension) { bufLen = addKeyValueInt(&buf, bufLen, "PixelYDimension", ImageInfo.PixelYDimension); if (bufLen == 0) return NULL; } if (ImageInfo.QualityGuess) { bufLen = addKeyValueInt(&buf, bufLen, "QualityGuess", ImageInfo.QualityGuess); if (bufLen == 0) return NULL; } if( ImageInfo.SceneCaptureType >= 0) { bufLen = addKeyValueInt(&buf, bufLen, "SceneCaptureType", ImageInfo.SceneCaptureType); if (bufLen == 0) return NULL; } if( ImageInfo.ShutterSpeedValue) { bufLen = addKeyValueDouble(&buf, bufLen, "ShutterSpeedValue", ImageInfo.ShutterSpeedValue, "%.4f"); if (bufLen == 0) return NULL; } if(ImageInfo.ExifVersion[0]) { bufLen = addKeyValueBytes(&buf, bufLen, "ExifVersion", ImageInfo.ExifVersion, 4); if (bufLen == 0) return NULL; } if(ImageInfo.ColorSpace > 0) { bufLen = addKeyValueInt(&buf, bufLen, "ColorSpace", ImageInfo.ColorSpace); if (bufLen == 0) return NULL; } if(ImageInfo.Compression > 0) { bufLen = addKeyValueInt(&buf, bufLen, "Compression", ImageInfo.Compression); if (bufLen == 0) return NULL; } if(ImageInfo.Process) { bufLen = addKeyValueInt(&buf, bufLen, "Process", ImageInfo.Process); if (bufLen == 0) return NULL; } if(ImageInfo.FileDateTime > 0) { char filedatetime[20]; FileTimeAsString( filedatetime ); bufLen = addKeyValueString( &buf, bufLen, "FileDateTime", filedatetime ); if( bufLen == 0 ) return NULL; } if(ImageInfo.FileSize) { bufLen = addKeyValueInt(&buf, bufLen, "FileSize", ImageInfo.FileSize); if (bufLen == 0) return NULL; } if( ImageInfo.Sharpness >= 0) { bufLen = addKeyValueInt(&buf, bufLen, "Sharpness", ImageInfo.Sharpness); if (bufLen == 0) return NULL; } if( ImageInfo.Contrast >= 0) { bufLen = addKeyValueInt(&buf, bufLen, "Contrast", ImageInfo.Contrast); if (bufLen == 0) return NULL; } if(ImageInfo.Saturation >= 0) { bufLen = addKeyValueInt(&buf, bufLen, "Saturation", ImageInfo.Saturation); if (bufLen == 0) return NULL; } if(ImageInfo.GainControl >= 0) { bufLen = addKeyValueInt(&buf, bufLen, "GainControl", ImageInfo.GainControl); if (bufLen == 0) return NULL; } // GPS if (ImageInfo.GpsInfoPresent) { if (ImageInfo.GpsLatitudeRef[0]) { bufLen = addKeyValueString(&buf, bufLen, "GpsLatitudeRef", ImageInfo.GpsLatitudeRef); if (bufLen == 0) return NULL; } if (ImageInfo.GpsLongitudeRef[0]) { bufLen = addKeyValueString(&buf, bufLen, "GpsLongitudeRef", ImageInfo.GpsLongitudeRef); if (bufLen == 0) return NULL; } if (ImageInfo.GpsAltitudeRef == 0 || ImageInfo.GpsAltitudeRef == 1) { bufLen = addKeyValueInt(&buf, bufLen, "GpsAltitudeRef", ImageInfo.GpsAltitudeRef); if (bufLen == 0) return NULL; } if (ImageInfo.GpsLatitude[0]) { bufLen = addKeyValueString(&buf, bufLen, "GpsLatitude", ImageInfo.GpsLatitude); if (bufLen == 0) return NULL; } if (ImageInfo.GpsLongitude[0]) { bufLen = addKeyValueString(&buf, bufLen, "GpsLongitude", ImageInfo.GpsLongitude); if (bufLen == 0) return NULL; } if (ImageInfo.GpsAltitude[0]) { bufLen = addKeyValueString(&buf, bufLen, "GpsAltitude", ImageInfo.GpsAltitude); if (bufLen == 0) return NULL; } if( ImageInfo.GpsSpeedRef[0]) { bufLen = addKeyValueString(&buf, bufLen, "GpsSpeedRef", ImageInfo.GpsSpeedRef); if (bufLen == 0) return NULL; } if (ImageInfo.GpsSpeed[0]) { bufLen = addKeyValueString(&buf, bufLen, "GpsSpeed", ImageInfo.GpsSpeed); if (bufLen == 0) return NULL; } } // end parsing LOGD("final buffer: %s", buf); // 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); LOGD("*********Returning result \"%s\"", finalResult); jstring result = ((*env)->NewStringUTF(env, finalResult)); free(finalResult); DiscardData(); return result; }
STRING::~STRING() { DiscardData(); }
//-------------------------------------------------------------------------- // 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"); } }
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 ); }
static jstring getAttributes(JNIEnv *env, jobject jobj, jstring jfilename) { #ifdef SUPERDEBUG LOGE("******************************** 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; } 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; 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.1f"); 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; } 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 (finalResult[k] > 127) finalResult[k] = '?'; free(buf); #ifdef SUPERDEBUG LOGE("*********Returning result \"%s\"", finalResult); #endif jstring result = ((*env)->NewStringUTF(env, finalResult)); free(finalResult); DiscardData(); return result; }