JNIEXPORT void JNICALL Java_com_troop_androiddng_RawToDng_WriteDNG(JNIEnv *env, jobject thiz, jobject handler) { uint64 dir_offset = 0, dir_offset2 = 0, gpsIFD_offset = 0; DngWriter* writer = (DngWriter*) env->GetDirectBufferAddress(handler); FILE* fptr = fopen(writer->fileSavePath,"w+"); writeIfd0(fptr, writer); TIFFSetField (tif, TIFFTAG_EXIFIFD, dir_offset); LOGD("set exif"); //CheckPOINT to KEEP EXIF IFD in MEMory //Try FiX DIR if(writer->gps == true) { makeGPS_IFD(tif, writer); TIFFCheckpointDirectory(tif); TIFFWriteCustomDirectory(tif, &gpsIFD_offset); TIFFSetDirectory(tif, 0); } writeExifIfd(tif,writer); //Check Point & Write are require checkpoint to update Current IFD Write Well to Write Close And Create IFD TIFFCheckpointDirectory(tif); //This Was missing it without it EXIF IFD was not being updated after adding SUB IFD TIFFWriteCustomDirectory(tif, &dir_offset); ///////////////////// GO Back TO IFD 0 TIFFSetDirectory(tif, 0); if(writer->gps) TIFFSetField (tif, TIFFTAG_GPSIFD, gpsIFD_offset); ///////////////////////////// WRITE THE SUB IFD's SUB IFD + EXIF IFD AGain GPS IFD would also go here as well as other cust IFD TIFFSetField(tif, TIFFTAG_EXIFIFD, dir_offset); writeRawStuff(tif,writer); if (writer->bayerBytes == NULL) return; delete[] writer->bayerBytes; writer->bayerBytes = NULL; }
static int write_tiff_image(t4_rx_state_t *s) { t4_rx_tiff_state_t *t; #if defined(SPANDSP_SUPPORT_TIFF_FX) uint64_t offset; #endif t = &s->tiff; if (t->image_buffer == NULL || t->image_size <= 0) return -1; /* Set up the TIFF directory info... */ set_tiff_directory_info(s); /* ...Put the directory in the file before the image data, to get them in the order specified for TIFF/F files... */ if (!TIFFCheckpointDirectory(t->tiff_file)) span_log(&s->logging, SPAN_LOG_WARNING, "%s: Failed to checkpoint directory for page %d.\n", t->file, s->current_page); /* ...and write out the image... */ if (TIFFWriteEncodedStrip(t->tiff_file, 0, t->image_buffer, t->image_size) < 0) span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error writing TIFF strip.\n", t->file); /* ...then finalise the directory entry, and libtiff is happy. */ if (!TIFFWriteDirectory(t->tiff_file)) span_log(&s->logging, SPAN_LOG_WARNING, "%s: Failed to write directory for page %d.\n", t->file, s->current_page); #if defined(SPANDSP_SUPPORT_TIFF_FX) if (s->current_page == 0) { if (!TIFFCreateCustomDirectory(t->tiff_file, &tiff_fx_field_array)) { TIFFSetField(t->tiff_file, TIFFTAG_FAXPROFILE, PROFILETYPE_G3_FAX); TIFFSetField(t->tiff_file, TIFFTAG_PROFILETYPE, FAXPROFILE_F); TIFFSetField(t->tiff_file, TIFFTAG_VERSIONYEAR, "1998"); offset = 0; if (!TIFFWriteCustomDirectory(t->tiff_file, &offset)) printf("Failed to write custom directory.\n"); /* Now go back and patch in the pointer to the new IFD */ if (!TIFFSetDirectory(t->tiff_file, s->current_page)) printf("Failed to set directory.\n"); if (!TIFFSetField(t->tiff_file, TIFFTAG_GLOBALPARAMETERSIFD, offset)) printf("Failed to set field.\n"); if (!TIFFWriteDirectory(t->tiff_file)) span_log(&s->logging, SPAN_LOG_WARNING, "%s: Failed to write directory for page %d.\n", t->file, s->current_page); } } #endif return 0; }
static int write_tiff_image(t4_rx_state_t *s) { t4_rx_tiff_state_t *t; #if defined(SPANDSP_SUPPORT_TIFF_FX) && TIFFLIB_VERSION >= 20120922 && defined(HAVE_TIF_DIR_H) toff_t diroff; #endif t = &s->tiff; if (s->decoder.no_decoder.buf_ptr <= 0 && (t->image_buffer == NULL || t->image_size <= 0)) return -1; /* Set up the TIFF directory info... */ set_tiff_directory_info(s); /* ...Put the directory in the file before the image data, to get them in the order specified for TIFF/F files... */ //if (!TIFFCheckpointDirectory(t->tiff_file)) // span_log(&s->logging, SPAN_LOG_WARNING, "%s: Failed to checkpoint directory for page %d.\n", t->file, s->current_page); /* ...and write out the image... */ if (s->current_decoder == 0) { if (TIFFWriteRawStrip(s->tiff.tiff_file, 0, s->decoder.no_decoder.buf, s->decoder.no_decoder.buf_ptr) < 0) span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error writing TIFF strip.\n", s->tiff.file); } else { switch (t->compression) { case T4_COMPRESSION_T85: case T4_COMPRESSION_T85_L0: /* We need to perform this compression here, as libtiff does not understand it. */ if (write_tiff_t85_image(s) < 0) return -1; break; #if defined(SPANDSP_SUPPORT_T88) case T4_COMPRESSION_T88: /* We need to perform this compression here, as libtiff does not understand it. */ if (write_tiff_t88_image(s) < 0) return -1; break; #endif case T4_COMPRESSION_T43: /* We need to perform this compression here, as libtiff does not understand it. */ if (write_tiff_t43_image(s) < 0) return -1; break; #if defined(SPANDSP_SUPPORT_T45) case T4_COMPRESSION_T45: /* We need to perform this compression here, as libtiff does not understand it. */ if (write_tiff_t45_image(s) < 0) return -1; break; #endif default: /* Let libtiff do the compression */ if (TIFFWriteEncodedStrip(t->tiff_file, 0, t->image_buffer, t->image_size) < 0) span_log(&s->logging, SPAN_LOG_WARNING, "%s: Error writing TIFF strip.\n", t->file); break; } } /* ...then finalise the directory entry, and libtiff is happy. */ if (!TIFFWriteDirectory(t->tiff_file)) span_log(&s->logging, SPAN_LOG_WARNING, "%s: Failed to write directory for page %d.\n", t->file, s->current_page); #if defined(SPANDSP_SUPPORT_TIFF_FX) /* According to the TIFF/FX spec, a global parameters IFD should only be inserted into the first page in the file */ if (s->current_page == 0) { #if TIFFLIB_VERSION >= 20120922 && defined(HAVE_TIF_DIR_H) if (!TIFFCreateCustomDirectory(t->tiff_file, &tiff_fx_field_array)) { TIFFSetField(t->tiff_file, TIFFTAG_FAXPROFILE, PROFILETYPE_G3_FAX); TIFFSetField(t->tiff_file, TIFFTAG_PROFILETYPE, FAXPROFILE_F); TIFFSetField(t->tiff_file, TIFFTAG_CODINGMETHODS, CODINGMETHODS_T4_1D | CODINGMETHODS_T4_2D | CODINGMETHODS_T6); TIFFSetField(t->tiff_file, TIFFTAG_VERSIONYEAR, "1998"); TIFFSetField(t->tiff_file, TIFFTAG_MODENUMBER, 3); diroff = 0; if (!TIFFWriteCustomDirectory(t->tiff_file, &diroff)) span_log(&s->logging, SPAN_LOG_WARNING, "Failed to write custom directory.\n"); /* Now go back and patch in the pointer to the new IFD */ if (!TIFFSetDirectory(t->tiff_file, s->current_page)) span_log(&s->logging, SPAN_LOG_WARNING, "Failed to set directory.\n"); if (!TIFFSetField(t->tiff_file, TIFFTAG_GLOBALPARAMETERSIFD, diroff)) span_log(&s->logging, SPAN_LOG_WARNING, "Failed to set field.\n"); if (!TIFFWriteDirectory(t->tiff_file)) span_log(&s->logging, SPAN_LOG_WARNING, "%s: Failed to write directory for page %d.\n", t->file, s->current_page); } #endif } #endif return 0; }
bool TIFFOutput::write_exif_data () { #if defined(TIFF_VERSION_BIG) && TIFFLIB_VERSION >= 20120922 // Older versions of libtiff do not support writing Exif directories if (m_spec.get_int_attribute ("tiff:write_exif", 1) == 0) { // The special metadata "tiff:write_exif", if present and set to 0 // (the default is 1), will cause us to skip outputting Exif data. // This is useful in cases where we think the TIFF file will need to // be read by an app that links against an old version of libtiff // that will have trouble reading the Exif directory. return true; } // First, see if we have any Exif data at all bool any_exif = false; for (size_t i = 0, e = m_spec.extra_attribs.size(); i < e; ++i) { const ImageIOParameter &p (m_spec.extra_attribs[i]); int tag, tifftype, count; if (exif_tag_lookup (p.name(), tag, tifftype, count) && tifftype != TIFF_NOTYPE) { if (tag == EXIFTAG_SECURITYCLASSIFICATION || tag == EXIFTAG_IMAGEHISTORY || tag == EXIFTAG_ISOSPEEDRATINGS) continue; // libtiff doesn't understand these any_exif = true; break; } } if (! any_exif) return true; if (m_compression == COMPRESSION_JPEG) { // For reasons we don't understand, JPEG-compressed TIFF seems // to not output properly without a directory checkpoint here. TIFFCheckpointDirectory (m_tif); } // First, finish writing the current directory if (! TIFFWriteDirectory (m_tif)) { error ("failed TIFFWriteDirectory()"); return false; } // Create an Exif directory if (TIFFCreateEXIFDirectory (m_tif) != 0) { error ("failed TIFFCreateEXIFDirectory()"); return false; } for (size_t i = 0, e = m_spec.extra_attribs.size(); i < e; ++i) { const ImageIOParameter &p (m_spec.extra_attribs[i]); int tag, tifftype, count; if (exif_tag_lookup (p.name(), tag, tifftype, count) && tifftype != TIFF_NOTYPE) { if (tag == EXIFTAG_SECURITYCLASSIFICATION || tag == EXIFTAG_IMAGEHISTORY || tag == EXIFTAG_ISOSPEEDRATINGS) continue; // libtiff doesn't understand these bool ok = false; if (tifftype == TIFF_ASCII) { ok = TIFFSetField (m_tif, tag, *(char**)p.data()); } else if ((tifftype == TIFF_SHORT || tifftype == TIFF_LONG) && p.type() == TypeDesc::SHORT) { ok = TIFFSetField (m_tif, tag, (int)*(short *)p.data()); } else if ((tifftype == TIFF_SHORT || tifftype == TIFF_LONG) && p.type() == TypeDesc::INT) { ok = TIFFSetField (m_tif, tag, *(int *)p.data()); } else if ((tifftype == TIFF_RATIONAL || tifftype == TIFF_SRATIONAL) && p.type() == TypeDesc::FLOAT) { ok = TIFFSetField (m_tif, tag, *(float *)p.data()); } else if ((tifftype == TIFF_RATIONAL || tifftype == TIFF_SRATIONAL) && p.type() == TypeDesc::DOUBLE) { ok = TIFFSetField (m_tif, tag, *(double *)p.data()); } if (! ok) { // std::cout << "Unhandled EXIF " << p.name() << " " << p.type() << "\n"; } } } // Now write the directory of Exif data uint64 dir_offset = 0; if (! TIFFWriteCustomDirectory (m_tif, &dir_offset)) { error ("failed TIFFWriteCustomDirectory() of the Exif data"); return false; } // Go back to the first directory, and add the EXIFIFD pointer. // std::cout << "diffdir = " << tiffdir << "\n"; TIFFSetDirectory (m_tif, 0); TIFFSetField (m_tif, TIFFTAG_EXIFIFD, dir_offset); #endif return true; // all is ok }
bool TIFFOutput::write_exif_data () { #if defined(TIFF_VERSION_BIG) && TIFFLIB_VERSION >= 20120922 // Older versions of libtiff do not support writing Exif directories // First, see if we have any Exif data at all bool any_exif = false; for (size_t i = 0, e = m_spec.extra_attribs.size(); i < e; ++i) { const ImageIOParameter &p (m_spec.extra_attribs[i]); int tag, tifftype, count; if (exif_tag_lookup (p.name(), tag, tifftype, count) && tifftype != TIFF_NOTYPE) { if (tag == EXIFTAG_SECURITYCLASSIFICATION || tag == EXIFTAG_IMAGEHISTORY || tag == EXIFTAG_ISOSPEEDRATINGS) continue; // libtiff doesn't understand these any_exif = true; break; } } if (! any_exif) return true; // First, finish writing the current directory if (! TIFFWriteDirectory (m_tif)) { error ("failed TIFFWriteDirectory()"); return false; } // Create an Exif directory if (TIFFCreateEXIFDirectory (m_tif) != 0) { error ("failed TIFFCreateEXIFDirectory()"); return false; } for (size_t i = 0, e = m_spec.extra_attribs.size(); i < e; ++i) { const ImageIOParameter &p (m_spec.extra_attribs[i]); int tag, tifftype, count; if (exif_tag_lookup (p.name(), tag, tifftype, count) && tifftype != TIFF_NOTYPE) { if (tag == EXIFTAG_SECURITYCLASSIFICATION || tag == EXIFTAG_IMAGEHISTORY || tag == EXIFTAG_ISOSPEEDRATINGS) continue; // libtiff doesn't understand these bool ok = false; if (tifftype == TIFF_ASCII) { ok = TIFFSetField (m_tif, tag, *(char**)p.data()); } else if ((tifftype == TIFF_SHORT || tifftype == TIFF_LONG) && p.type() == TypeDesc::SHORT) { ok = TIFFSetField (m_tif, tag, (int)*(short *)p.data()); } else if ((tifftype == TIFF_SHORT || tifftype == TIFF_LONG) && p.type() == TypeDesc::INT) { ok = TIFFSetField (m_tif, tag, *(int *)p.data()); } else if ((tifftype == TIFF_RATIONAL || tifftype == TIFF_SRATIONAL) && p.type() == TypeDesc::FLOAT) { ok = TIFFSetField (m_tif, tag, *(float *)p.data()); } else if ((tifftype == TIFF_RATIONAL || tifftype == TIFF_SRATIONAL) && p.type() == TypeDesc::DOUBLE) { ok = TIFFSetField (m_tif, tag, *(double *)p.data()); } if (! ok) { // std::cout << "Unhandled EXIF " << p.name() << " " << p.type() << "\n"; } } } // Now write the directory of Exif data uint64 dir_offset = 0; if (! TIFFWriteCustomDirectory (m_tif, &dir_offset)) { error ("failed TIFFWriteCustomDirectory() of the Exif data"); return false; } // Go back to the first directory, and add the EXIFIFD pointer. // std::cout << "diffdir = " << tiffdir << "\n"; TIFFSetDirectory (m_tif, 0); TIFFSetField (m_tif, TIFFTAG_EXIFIFD, dir_offset); #endif return true; // all is ok }
int main() { TIFF *tif; unsigned char buf[SPP] = { 0, 127, 255 }; uint64 dir_offset = 0, dir_offset2 = 0; uint64 read_dir_offset = 0, read_dir_offset2 = 0; uint64 *dir_offset2_ptr = NULL; char *ascii_value; uint16 count16 = 0; /* We write the main directory as a simple image. */ tif = TIFFOpen(filename, "w+"); if (!tif) { fprintf (stderr, "Can't create test TIFF file %s.\n", filename); return 1; } if (!TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width)) { fprintf (stderr, "Can't set ImageWidth tag.\n"); goto failure; } if (!TIFFSetField(tif, TIFFTAG_IMAGELENGTH, length)) { fprintf (stderr, "Can't set ImageLength tag.\n"); goto failure; } if (!TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps)) { fprintf (stderr, "Can't set BitsPerSample tag.\n"); goto failure; } if (!TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, SPP)) { fprintf (stderr, "Can't set SamplesPerPixel tag.\n"); goto failure; } if (!TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rows_per_strip)) { fprintf (stderr, "Can't set SamplesPerPixel tag.\n"); goto failure; } if (!TIFFSetField(tif, TIFFTAG_PLANARCONFIG, planarconfig)) { fprintf (stderr, "Can't set PlanarConfiguration tag.\n"); goto failure; } if (!TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric)) { fprintf (stderr, "Can't set PhotometricInterpretation tag.\n"); goto failure; } /* Write dummy pixel data. */ if (TIFFWriteScanline(tif, buf, 0, 0) == -1) { fprintf (stderr, "Can't write image data.\n"); goto failure; } if (!TIFFWriteDirectory( tif )) { fprintf (stderr, "TIFFWriteDirectory() failed.\n"); goto failure; } /* * Now create an EXIF directory. */ if (TIFFCreateEXIFDirectory(tif) != 0) { fprintf (stderr, "TIFFCreateEXIFDirectory() failed.\n" ); goto failure; } if (!TIFFSetField( tif, EXIFTAG_SPECTRALSENSITIVITY, "EXIF Spectral Sensitivity")) { fprintf (stderr, "Can't write SPECTRALSENSITIVITY\n" ); goto failure; } if (!TIFFWriteCustomDirectory( tif, &dir_offset )) { fprintf (stderr, "TIFFWriteCustomDirectory() with EXIF failed.\n"); goto failure; } /* * Now create a custom directory with tags that conflict with mainline * TIFF tags. */ TIFFFreeDirectory( tif ); if (TIFFCreateCustomDirectory(tif, &customFieldArray) != 0) { fprintf (stderr, "TIFFCreateEXIFDirectory() failed.\n" ); goto failure; } if (!TIFFSetField( tif, TIFFTAG_IMAGEWIDTH, "*Custom1")) { /* not really IMAGEWIDTH */ fprintf (stderr, "Can't write pseudo-IMAGEWIDTH.\n" ); goto failure; } if (!TIFFSetField( tif, TIFFTAG_DOTRANGE, "*Custom2")) { /* not really DOTWIDTH */ fprintf (stderr, "Can't write pseudo-DOTWIDTH.\n" ); goto failure; } if (!TIFFWriteCustomDirectory( tif, &dir_offset2 )) { fprintf (stderr, "TIFFWriteCustomDirectory() with EXIF failed.\n"); goto failure; } /* * Go back to the first directory, and add the EXIFIFD pointer. */ TIFFSetDirectory(tif, 0); TIFFSetField(tif, TIFFTAG_EXIFIFD, dir_offset ); TIFFSetField(tif, TIFFTAG_SUBIFD, 1, &dir_offset2 ); TIFFClose(tif); /* Ok, now test whether we can read written values in the EXIF directory. */ tif = TIFFOpen(filename, "r"); TIFFGetField(tif, TIFFTAG_EXIFIFD, &read_dir_offset ); if( read_dir_offset != dir_offset ) { fprintf (stderr, "Did not get expected EXIFIFD.\n" ); goto failure; } TIFFGetField(tif, TIFFTAG_SUBIFD, &count16, &dir_offset2_ptr ); read_dir_offset2 = dir_offset2_ptr[0]; if( read_dir_offset2 != dir_offset2 || count16 != 1) { fprintf (stderr, "Did not get expected SUBIFD.\n" ); goto failure; } if( !TIFFReadEXIFDirectory(tif, read_dir_offset) ) { fprintf (stderr, "TIFFReadEXIFDirectory() failed.\n" ); goto failure; } if (!TIFFGetField( tif, EXIFTAG_SPECTRALSENSITIVITY, &ascii_value) ) { fprintf (stderr, "reading SPECTRALSENSITIVITY failed.\n" ); goto failure; } if( strcmp(ascii_value,"EXIF Spectral Sensitivity") != 0) { fprintf (stderr, "got wrong SPECTRALSENSITIVITY value.\n" ); goto failure; } /* Try reading the Custom directory */ if( !TIFFReadCustomDirectory(tif, read_dir_offset2, &customFieldArray) ) { fprintf (stderr, "TIFFReadCustomDirectory() failed.\n" ); goto failure; } if (!TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &ascii_value) ) { fprintf (stderr, "reading pseudo-IMAGEWIDTH failed.\n" ); goto failure; } if( strcmp(ascii_value,"*Custom1") != 0) { fprintf (stderr, "got wrong pseudo-IMAGEWIDTH value.\n" ); goto failure; } if (!TIFFGetField( tif, TIFFTAG_DOTRANGE, &ascii_value) ) { fprintf (stderr, "reading pseudo-DOTRANGE failed.\n" ); goto failure; } if( strcmp(ascii_value,"*Custom2") != 0) { fprintf (stderr, "got wrong pseudo-DOTRANGE value.\n" ); goto failure; } TIFFClose(tif); /* All tests passed; delete file and exit with success status. */ unlink(filename); return 0; failure: /* * Something goes wrong; close file and return unsuccessful status. * Do not remove the file for further manual investigation. */ TIFFClose(tif); return 1; }