int IMG_isTIF(SDL_RWops* src) { TIFF* tiff; TIFFErrorHandler prev_handler; /* Suppress output from libtiff */ prev_handler = TIFFSetErrorHandler(NULL); /* Attempt to process the given file data */ /* turn off memory mapped access with the m flag */ tiff = TIFFClientOpen("SDL_image", "rm", (thandle_t)src, tiff_read, tiff_write, tiff_seek, tiff_close, tiff_size, NULL, NULL); /* Reset the default error handler, since it can be useful for info */ TIFFSetErrorHandler(prev_handler); /* If it's not a TIFF, then tiff will be NULL. */ if(!tiff) return 0; /* Free up any dynamically allocated memory libtiff uses */ TIFFClose(tiff); return 1; }
static gboolean process(GeglOperation *operation, GeglBuffer *input, const GeglRectangle *result, int level) { GeglProperties *o = GEGL_PROPERTIES(operation); Priv *p = g_new0(Priv, 1); gboolean status = TRUE; GError *error = NULL; g_assert(p != NULL); o->user_data = (void*) p; p->stream = gegl_gio_open_output_stream(NULL, o->path, &p->file, &error); if (p->stream != NULL && p->file != NULL) p->can_seek = g_seekable_can_seek(G_SEEKABLE(p->stream)); if (p->stream == NULL) { status = FALSE; g_warning("%s", error->message); goto cleanup; } TIFFSetErrorHandler(error_handler); TIFFSetWarningHandler(warning_handler); p->tiff = TIFFClientOpen("GEGL-tiff-save", "w", (thandle_t) p, read_from_stream, write_to_stream, seek_in_stream, close_stream, get_file_size, NULL, NULL); if (p->tiff == NULL) { status = FALSE; g_warning("failed to open TIFF from %s", o->path); goto cleanup; } if (export_tiff(operation, input, result)) { status = FALSE; g_warning("could not export TIFF file"); goto cleanup; } cleanup: cleanup(operation); if (o->user_data != NULL) g_free(o->user_data); o->user_data = NULL; if (error != NULL) g_error_free(error); return status; }
TIFF * qxe_TIFFClientOpen (const char *x1, const char *x2, thandle_t x3, TIFFReadWriteProc x4, TIFFReadWriteProc x5, TIFFSeekProc x6, TIFFCloseProc x7, TIFFSizeProc x8, TIFFMapFileProc x9, TIFFUnmapFileProc x10) { return TIFFClientOpen (x1, x2, x3, x4, x5, x6, x7, x8, x9, x10); }
SDL_Surface* IMG_LoadTIF_RW(SDL_RWops* src) { TIFF* tiff; SDL_Surface* surface = NULL; Uint32 img_width, img_height; Uint32 Rmask, Gmask, Bmask, Amask, mask; Uint32 x, y; Uint32 half; if ( !src ) { /* The error message has been set in SDL_RWFromFile */ return NULL; } /* turn off memory mapped access with the m flag */ tiff = TIFFClientOpen("SDL_image", "rm", (thandle_t)src, tiff_read, tiff_write, tiff_seek, tiff_close, tiff_size, NULL, NULL); if(!tiff) return NULL; /* Retrieve the dimensions of the image from the TIFF tags */ TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &img_width); TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &img_height); Rmask = 0x000000FF; Gmask = 0x0000FF00; Bmask = 0x00FF0000; Amask = 0xFF000000; surface = SDL_AllocSurface(SDL_SWSURFACE, img_width, img_height, 32, Rmask, Gmask, Bmask, Amask); if(!surface) return NULL; if(!TIFFReadRGBAImage(tiff, img_width, img_height, surface->pixels, 0)) return NULL; /* libtiff loads the image upside-down, flip it back */ half = img_height / 2; for(y = 0; y < half; y++) { Uint32 *top = (Uint32 *)surface->pixels + y * surface->pitch/4; Uint32 *bot = (Uint32 *)surface->pixels + (img_height - y - 1) * surface->pitch/4; for(x = 0; x < img_width; x++) { Uint32 tmp = top[x]; top[x] = bot[x]; bot[x] = tmp; } } TIFFClose(tiff); return surface; }
TIFF* TIFFwxOpen(wxOutputStream &stream, const char* name, const char* mode) { TIFF* tif = TIFFClientOpen(name, mode, (thandle_t) &stream, wxTIFFNullProc, wxTIFFWriteProc, wxTIFFSeekOProc, wxTIFFCloseOProc, wxTIFFSizeProc, wxTIFFMapProc, wxTIFFUnmapProc); return tif; }
TIFF* TIFFwxOpen(wxOutputStream &stream, const char* name, const char* mode) { TIFF* tif = TIFFClientOpen(name, mode, (thandle_t) &stream, _tiffNullProc, _tiffWriteProc, _tiffSeekOProc, _tiffCloseProc, _tiffSizeProc, _tiffMapProc, _tiffUnmapProc); return tif; }
/* * Open a TIFF file descriptor for read/writing. */ TIFF* TIFFFdOpen(int fd, const char* name, const char* mode) { TIFF* tif; tif = TIFFClientOpen(name, mode, (thandle_t) fd, _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, _tiffMapProc, _tiffUnmapProc); if (tif) tif->tif_fd = fd; return (tif); }
static gboolean gdk_pixbuf__tiff_image_stop_load (gpointer data, GError **error) { TiffContext *context = data; TIFF *tiff; gboolean retval; g_return_val_if_fail (data != NULL, FALSE); tiff_push_handlers (); tiff = TIFFClientOpen ("libtiff-pixbuf", "r", data, tiff_load_read, tiff_load_write, tiff_load_seek, tiff_load_close, tiff_load_size, tiff_load_map_file, tiff_load_unmap_file); if (!tiff || global_error) { tiff_set_error (error, GDK_PIXBUF_ERROR_FAILED, _("Failed to load TIFF image")); retval = FALSE; } else { GdkPixbuf *pixbuf; pixbuf = tiff_image_parse (tiff, context, error); if (pixbuf) g_object_unref (pixbuf); retval = pixbuf != NULL; if (global_error) { tiff_set_error (error, GDK_PIXBUF_ERROR_FAILED, _("Failed to load TIFF image")); tiff_pop_handlers (); retval = FALSE; } } if (tiff) TIFFClose (tiff); g_assert (!global_error); g_free (context->buffer); g_free (context); tiff_pop_handlers (); return retval; }
TIFF *iTIFFOpen(char *Mode) { TIFF *tif; tif = TIFFClientOpen("TIFFMemFile", Mode, NULL, _tiffFileReadProc, _tiffFileWriteProc, _tiffFileSeekProc, _tiffFileCloseProc, _tiffFileSizeProc, _tiffDummyMapProc, _tiffDummyUnmapProc); return tif; }
static TIFF *imb_tiff_client_open(ImbTIFFMemFile *memFile, unsigned char *mem, size_t size) { /* open the TIFF client layer interface to the in-memory file */ memFile->mem = mem; memFile->offset = 0; memFile->size = size; return TIFFClientOpen("(Blender TIFF Interface Layer)", "r", (thandle_t)(memFile), imb_tiff_ReadProc, imb_tiff_WriteProc, imb_tiff_SeekProc, imb_tiff_CloseProc, imb_tiff_SizeProc, imb_tiff_DummyMapProc, imb_tiff_DummyUnmapProc); }
TIFF* _TIFFFdOpen(void* fd, const char* name, const char* mode) { TIFF* tif; tif = TIFFClientOpen(name, mode, (thandle_t) fd, _tiffReadProcEx, _tiffWriteProcEx, _tiffSeekProcEx, _tiffCloseProcEx, _tiffSizeProcEx, _tiffMapProcEx, _tiffUnmapProcEx); if (tif) tif->tif_fd = reinterpret_cast<int>(fd); return (tif); }
void HILL_read_tiff( HILL_input_stream i, struct HILL_image_data *img ){ TIFF *t; uint32_t width=0; uint32_t height=0; uint32_t bytes=0; TIFFSetErrorHandler(read_tiff_error_handler); TIFFSetWarningHandler(read_tiff_error_handler); t=TIFFClientOpen( "Memory", "r", (thandle_t)i, read_tiff_read, read_tiff_write, read_tiff_seek, read_tiff_close, read_tiff_size, NULL, NULL ); if(t==NULL) { img->err=HILL_IMAGE_LIBRARY_ERROR; return; } TIFFGetField(t, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(t, TIFFTAG_IMAGELENGTH, &height); bytes=width*height*sizeof(uint32_t); img->w=width; img->h=height; img->fmt=HILL_RGBA8; img->data=malloc(bytes); if(TIFFReadRGBAImageOriented(t, width, height, (uint32_t *)img->data, ORIENTATION_TOPLEFT, 1) != 0) { img->err=HILL_IMAGE_NO_ERROR; TIFFClose(t); } else { img->err=HILL_IMAGE_NOT_SUPPORTED; free(img->data); TIFFClose(t); } }
/* * Open a TIFF file descriptor for read/writing. */ TIFF* DECLARE3(TIFFFdOpen, int, fd, const char*, name, const char*, mode) { TIFF *tif; tif = TIFFClientOpen(name, mode, (void*) fd, _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, _tiffMapProc, _tiffUnmapProc); if (tif) tif->tif_fd = fd; return (tif); }
TIFF* _TIFFFdOpen(void* fd, const char* name, const char* mode) { TIFF* tif; tif = TIFFClientOpen(name, mode, (thandle_t) fd, _tiffReadProcEx, _tiffWriteProcEx, _tiffSeekProcEx, _tiffCloseProcEx, _tiffSizeProcEx, _tiffMapProcEx, _tiffUnmapProcEx); #ifndef _LINUX if (tif) tif->tif_fd = fd; #endif return (tif); }
/* * Open a TIFF file descriptor for read/writing. * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode * string, which forces the file to be opened unmapped. */ TIFF* TIFFFdOpen(int ifd, const char* name, const char* mode) { TIFF* tif; BOOL fSuppressMap = (mode[1] == 'u' || (mode[1]!=0 && mode[2] == 'u')); tif = TIFFClientOpen(name, mode, (thandle_t)ifd, _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc); if (tif) tif->tif_fd = ifd; return (tif); }
/* * Open a TIFF file for read/writing. */ TIFF* TIFFOpen(const char* name, const char* mode) { static const char module[] = "TIFFOpen"; int i, a_out; char szAccess[32]; VSILFILE *fp; TIFF *tif; char *pszAccess = szAccess; a_out = 0; pszAccess[0] = '\0'; for( i = 0; mode[i] != '\0'; i++ ) { if( mode[i] == 'r' || mode[i] == 'w' || mode[i] == '+' || mode[i] == 'a' ) { szAccess[a_out++] = mode[i]; szAccess[a_out] = '\0'; } } strcat( szAccess, "b" ); fp = VSIFOpenL( name, szAccess ); if (fp == NULL) { if( errno >= 0 ) TIFFError(module,"%s: %s", name, VSIStrerror( errno ) ); else TIFFError(module, "%s: Cannot open", name); return ((TIFF *)0); } tif = TIFFClientOpen(name, mode, (thandle_t) fp, _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, _tiffMapProc, _tiffUnmapProc); if( tif != NULL ) tif->tif_fd = 0; else CPL_IGNORE_RET_VAL_INT(VSIFCloseL( fp )); return tif; }
TIFF* tiff_reader<T>::open(std::istream & input) { if (!tif_) { tif_ = tiff_ptr(TIFFClientOpen("tiff_input_stream", "rm", reinterpret_cast<thandle_t>(&input), impl::tiff_read_proc, impl::tiff_write_proc, impl::tiff_seek_proc, impl::tiff_close_proc, impl::tiff_size_proc, impl::tiff_map_proc, impl::tiff_unmap_proc), tiff_closer()); } return tif_.get(); }
TIFF* _TIFFFdOpen(void* fd, const char* name, const char* mode) { TIFF* tif; tif = TIFFClientOpen(name, mode, (thandle_t) fd, _tiffReadProcEx, _tiffWriteProcEx, _tiffSeekProcEx, _tiffCloseProcEx, _tiffSizeProcEx, _tiffMapProcEx, _tiffUnmapProcEx); if (tif) { tif->tif_fd = static_cast<int>(reinterpret_cast<long>(fd)); //@HACK //tif->tif_fd = (int)fd; } return (tif); }
/* * Open a TIFF file descriptor for read/writing. */ TIFF* TIFFFdOpen(int fd, const char* name, const char* mode) { TIFF* tif; fd_as_handle_union_t fdh; fdh.fd = fd; tif = TIFFClientOpen(name, mode, fdh.h, _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, _tiffMapProc, _tiffUnmapProc); if (tif) tif->tif_fd = fd; return (tif); }
TIFF* TiffStream::makeFileStream(iostream* str) { m_inStream = NULL; m_outStream = NULL; m_ioStream = str; m_streamLength = getSize(m_this); m_tif = TIFFClientOpen(m_name, "r+w", m_this, read, write, seek, close, size, map, unmap); return m_tif; }
bool ZLWin32ImageManager::tiffConvert(const std::string &stringData, ZLWin32ImageData &data, bool &result) const { result = false; TIFFReader reader(stringData); TIFF *tiff = TIFFClientOpen("ZLWin32ImageManager", "rM", &reader, TIFFReader::read, TIFFReader::write, TIFFReader::seek, TIFFReader::close, TIFFReader::size, TIFFReader::map, TIFFReader::unmap); if (tiff == 0) { return false; } int width, height; if (!TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &width) || !TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &height)) { TIFFClose(tiff); return false; } data.init(width, height, true, 0); result = TIFFReadRGBAImage(tiff, width, height, (uint32*)data.myArray, 1) != 0; data.bgr2rgb(); TIFFClose(tiff); return true; }
TIFF* XTIFFClientOpen(const char* name, const char* mode, thandle_t thehandle, TIFFReadWriteProc RWProc, TIFFReadWriteProc RWProc2, TIFFSeekProc SProc, TIFFCloseProc CProc, TIFFSizeProc SzProc, TIFFMapFileProc MFProvc, TIFFUnmapFileProc UMFProc ) { TIFF *tif; /* Set up the callback */ XTIFFInitialize(); /* Open the file; the callback will set everything up */ tif = TIFFClientOpen(name, mode, thehandle, RWProc, RWProc2, SProc, CProc, SzProc, MFProvc, UMFProc); if (!tif) return tif; return tif; }
/* * Open a TIFF file descriptor for read/writing. * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode * string, which forces the file to be opened unmapped. */ TIFF* TIFFFdOpen(int ifd, const char* name, const char* mode) { TIFF* tif; int fSuppressMap; int m; fSuppressMap=0; for (m=0; mode[m]!=0; m++) { if (mode[m]=='u') { fSuppressMap=1; break; } } tif = TIFFClientOpen(name, mode, (thandle_t)ifd, /* FIXME: WIN64 cast to pointer warning */ _tiffReadProc, _tiffWriteProc, _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc); if (tif) tif->tif_fd = ifd; return (tif); }
WriteResult::WriteStatus writeTIFStream(std::ostream& fout, const osg::Image& img) const { //Code is based from the following article on CodeProject.com //http://www.codeproject.com/bitmap/BitmapsToTiffs.asp TIFF *image; int samplesPerPixel; int bitsPerSample; uint16 photometric; image = TIFFClientOpen("outputstream", "w", (thandle_t)&fout, libtiffOStreamReadProc, //Custom read function libtiffOStreamWriteProc, //Custom write function libtiffOStreamSeekProc, //Custom seek function libtiffStreamCloseProc, //Custom close function libtiffOStreamSizeProc, //Custom size function libtiffStreamMapProc, //Custom map function libtiffStreamUnmapProc); //Custom unmap function if(image == NULL) { return WriteResult::ERROR_IN_WRITING_FILE; } switch(img.getPixelFormat()) { case GL_LUMINANCE: case GL_ALPHA: photometric = PHOTOMETRIC_MINISBLACK; samplesPerPixel = 1; break; case GL_LUMINANCE_ALPHA: photometric = PHOTOMETRIC_MINISBLACK; samplesPerPixel = 2; break; case GL_RGB: photometric = PHOTOMETRIC_RGB; samplesPerPixel = 3; break; case GL_RGBA: photometric = PHOTOMETRIC_RGB; samplesPerPixel = 4; break; default: return WriteResult::ERROR_IN_WRITING_FILE; break; } switch(img.getDataType()){ case GL_FLOAT: TIFFSetField(image, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, 1); bitsPerSample = 32; break; default: bitsPerSample = 8; break; } TIFFSetField(image, TIFFTAG_IMAGEWIDTH,img.s()); TIFFSetField(image, TIFFTAG_IMAGELENGTH,img.t()); TIFFSetField(image, TIFFTAG_BITSPERSAMPLE,bitsPerSample); TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL,samplesPerPixel); TIFFSetField(image, TIFFTAG_PHOTOMETRIC, photometric); TIFFSetField(image, TIFFTAG_COMPRESSION, COMPRESSION_PACKBITS); TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); //uint32 rowsperstrip = TIFFDefaultStripSize(image, -1); //TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, rowsperstrip); // Write the information to the file for(int i = 0; i < img.t(); ++i) { TIFFWriteScanline(image,(tdata_t)img.data(0,img.t()-i-1),i,0); } // Close the file TIFFClose(image); return WriteResult::FILE_SAVED; }
//---------------------------------------------------------------------------- void vtkVisItTIFFWriter::WriteFileHeader(ofstream *file, vtkImageData *data) { int dims[3]; int width, height; data->GetDimensions(dims); int scomponents = data->GetNumberOfScalarComponents(); int stype = data->GetScalarType(); double resolution = -1; uint32 rowsperstrip = (uint32) -1; int min0, min1, max0, max1, min2, max2; int bps; switch (stype) { case VTK_CHAR: case VTK_SIGNED_CHAR: case VTK_UNSIGNED_CHAR: bps = 8; break; case VTK_SHORT: case VTK_UNSIGNED_SHORT: bps = 16; break; case VTK_FLOAT: bps = 32; break; default: vtkErrorMacro(<< "Unsupported data type: " << data->GetScalarTypeAsString()); this->SetErrorCode(vtkErrorCode::FileFormatError); return; } int predictor = 0; // Find the length of the rows to write. data->GetWholeExtent(min0, max0, min1, max1, min2, max2); width = (max0 - min0 + 1); height = (max1 - min1 + 1); TIFF* tif = TIFFClientOpen(this->GetFileName(), "w", (thandle_t) file, reinterpret_cast<TIFFReadWriteProc>(vtkVisItTIFFWriterIO::TIFFRead), reinterpret_cast<TIFFReadWriteProc>(vtkVisItTIFFWriterIO::TIFFWrite), reinterpret_cast<TIFFSeekProc>(vtkVisItTIFFWriterIO::TIFFSeek), reinterpret_cast<TIFFCloseProc>(vtkVisItTIFFWriterIO::TIFFClose), reinterpret_cast<TIFFSizeProc>(vtkVisItTIFFWriterIO::TIFFSize), reinterpret_cast<TIFFMapFileProc>(vtkVisItTIFFWriterIO::TIFFMapFile), reinterpret_cast<TIFFUnmapFileProc>(vtkVisItTIFFWriterIO::TIFFUnmapFile)); if ( !tif ) { this->TIFFPtr = 0; return; } this->TIFFPtr = tif; uint32 w = width; uint32 h = height; TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, w); TIFFSetField(tif, TIFFTAG_IMAGELENGTH, h); TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, scomponents); TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); // Fix for stype TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); if (stype == VTK_FLOAT) { TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); } if ( scomponents > 3 ) { // if number of scalar components is greater than 3, that means we assume // there is alpha. uint16 extra_samples = scomponents-3; uint16 *sample_info = new uint16[scomponents-3]; sample_info[0]=EXTRASAMPLE_ASSOCALPHA; int cc; for ( cc = 1; cc < scomponents-3; cc ++ ) { sample_info[cc] = EXTRASAMPLE_UNSPECIFIED; } TIFFSetField(tif,TIFFTAG_EXTRASAMPLES,extra_samples, sample_info); delete [] sample_info; } int compression = COMPRESSION_PACKBITS; switch ( this->Compression ) { case vtkVisItTIFFWriter::PackBits: compression = COMPRESSION_PACKBITS; break; case vtkVisItTIFFWriter::JPEG: compression = COMPRESSION_JPEG; break; case vtkVisItTIFFWriter::Deflate: compression = COMPRESSION_DEFLATE; break; case vtkVisItTIFFWriter::LZW: compression = COMPRESSION_LZW; break; default: compression = COMPRESSION_NONE; } //compression = COMPRESSION_JPEG; TIFFSetField(tif, TIFFTAG_COMPRESSION, compression); // Fix for compression uint16 photometric = (stype == VTK_FLOAT ? PHOTOMETRIC_MINISBLACK : PHOTOMETRIC_RGB); if ( compression == COMPRESSION_JPEG ) { TIFFSetField(tif, TIFFTAG_JPEGQUALITY, 75); // Parameter TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB); photometric = PHOTOMETRIC_YCBCR; } else if ( compression == COMPRESSION_LZW ) { predictor = 2; TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor); vtkErrorMacro("LZW compression is patented outside US so it is disabled"); } else if ( compression == COMPRESSION_DEFLATE ) { predictor = 2; TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor); } TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric); // Fix for scomponents TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, TIFFDefaultStripSize(tif, rowsperstrip)); if (resolution > 0) { TIFFSetField(tif, TIFFTAG_XRESOLUTION, resolution); TIFFSetField(tif, TIFFTAG_YRESOLUTION, resolution); TIFFSetField(tif, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); } }
Image *Read (IStream *file, const Image::ReadOptions& options) { int nrow; int result = 0; long LineSize; TIFF *tif; Image *image ; uint16 BitsPerSample; uint16 BytesPerSample = 1; uint16 PhotometricInterpretation; uint16 SamplePerPixel; uint16 Orientation; uint32 RowsPerStrip; unsigned int width; unsigned int height; // TODO - TIFF files probably have some gamma info in them by default, but we're currently ignorant about that. // Until that is fixed, use whatever the user has chosen as default. GammaCurvePtr gamma; if (options.gammacorrect && options.defaultGamma) gamma = TranscodingGammaCurve::Get(options.workingGamma, options.defaultGamma); // [CLi] TIFF is specified to use associated (= premultiplied) alpha, so that's the preferred mode to use for the image container unless the user overrides // (e.g. to handle a non-compliant file). bool premul = true; if (options.premultiplyOverride) premul = options.premultiply; // Rather than have libTIFF complain about tags it doesn't understand, // we just suppress all the warnings. TIFFSetWarningHandler(SuppressTIFFWarnings); TIFFSetErrorHandler(SuppressTIFFWarnings); // Open and do initial processing tif = TIFFClientOpen("Dummy File Name", "r", file, Tiff_Read, Tiff_Write, Tiff_Seek, Tiff_Close, Tiff_Size, Tiff_Map, Tiff_Unmap); if (!tif) return (NULL) ; // Get basic information about the image int ExtraSamples, ExtraSampleInfo; TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample); TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip); TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation); TIFFGetField(tif, TIFFTAG_ORIENTATION, &Orientation); TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &SamplePerPixel); TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, &ExtraSamples, &ExtraSampleInfo); // don't support more than 16 bits per sample if (BitsPerSample == 16) { BytesPerSample = 2 ; options.warnings.push_back ("Warning: reading 16 bits/sample TIFF file; components crunched to 8"); } LineSize = TIFFScanlineSize(tif); assert (SamplePerPixel == (int) (LineSize / width) / BytesPerSample); // SamplePerPixel = (int)(LineSize / width); #if 0 // For now we are ignoring the orientation of the image... switch (Orientation) { case ORIENTATION_TOPLEFT: break; case ORIENTATION_TOPRIGHT: break; case ORIENTATION_BOTRIGHT: break; case ORIENTATION_BOTLEFT: break; case ORIENTATION_LEFTTOP: break; case ORIENTATION_RIGHTTOP: break; case ORIENTATION_RIGHTBOT: break; case ORIENTATION_LEFTBOT: break; default: break; } #endif //PhotometricInterpretation = 2 image is RGB //PhotometricInterpretation = 3 image have a color palette if (PhotometricInterpretation == PHOTOMETRIC_PALETTE && (TIFFIsTiled(tif) == 0)) { uint16 *red, *green, *blue; //load the palette int cmap_len = (1 << BitsPerSample); TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue); vector<Image::RGBMapEntry> colormap ; Image::RGBMapEntry entry; // I may be mistaken, but it appears that alpha/opacity information doesn't // appear in a Paletted Tiff image. Well - if it does, it's not as easy to // get at as RGB. // Read the palette // Is the palette 16 or 8 bits ? if (checkcmap(cmap_len, red, green, blue) == 16) { for (int i=0;i<cmap_len;i++) { entry.red = IntDecode(gamma, red[i], 65535); entry.green = IntDecode(gamma, green[i], 65535); entry.blue = IntDecode(gamma, blue[i], 65535); colormap.push_back (entry); } } else { for (int i=0;i<cmap_len;i++) { entry.red = IntDecode(gamma, red[i], 255); entry.green = IntDecode(gamma, green[i], 255); entry.blue = IntDecode(gamma, blue[i], 255); colormap.push_back (entry); } } Image::ImageDataType imagetype = options.itype; if (imagetype == Image::Undefined) imagetype = Image::Colour_Map; image = Image::Create (width, height, imagetype, colormap) ; image->SetPremultiplied(premul); // specify whether the color map data has premultiplied alpha boost::scoped_array<unsigned char> buf (new unsigned char [TIFFStripSize(tif)]); //read the tiff lines and save them in the image //with RGB mode, we have to change the order of the 3 samples RGB <=> BGR for (int row=0;row<height;row+=RowsPerStrip) { nrow = (row + (int)RowsPerStrip > height ? height - row : RowsPerStrip); TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0), buf.get(), nrow * LineSize); for (int l = 0, offset = 0; l < nrow ; l++, offset += LineSize) for (int x = 0 ; x < width ; x++) image->SetIndexedValue (x, row+l, buf[offset+x]) ; } } else { // Allocate the row buffers for the image boost::scoped_array<uint32> buf (new uint32 [width * height]) ; Image::ImageDataType imagetype = options.itype; if (imagetype == Image::Undefined) imagetype = ( GammaCurve::IsNeutral(gamma) ? Image::RGBA_Int8 : Image::RGBA_Gamma8 ); image = Image::Create (width, height, imagetype) ; image->SetPremultiplied(premul); // set desired storage mode regarding alpha premultiplication image->TryDeferDecoding(gamma, 255); // try to have gamma adjustment being deferred until image evaluation. TIFFReadRGBAImage(tif, width, height, buf.get(), 0); uint32 abgr, *tbuf = buf.get(); for (int i=height-1;i>=0;i--) { for (int j=0;j<width;j++) { abgr = *tbuf++; unsigned int b = (unsigned char)TIFFGetB(abgr); unsigned int g = (unsigned char)TIFFGetG(abgr); unsigned int r = (unsigned char)TIFFGetR(abgr); unsigned int a = (unsigned char)TIFFGetA(abgr); SetEncodedRGBAValue(image, j, i, gamma, 255, r, g, b, a, premul) ; } } } TIFFClose(tif); return (image) ; }
WriteResult::WriteStatus writeTIFStream(std::ostream& fout, const osg::Image& img, const osgDB::ReaderWriter::Options* options) const { int compressionType = COMPRESSION_PACKBITS; if (options) { std::istringstream iss(options->getOptionString()); std::string opt; while (iss >> opt) { opt = osgDB::convertToLowerCase(opt); std::size_t eqInd = opt.find("="); if (opt.substr(0, eqInd) == "tiff_compression") { std::string compressTypeOpt; compressTypeOpt = opt.substr(eqInd + 1); compressTypeOpt = osgDB::convertToLowerCase(compressTypeOpt); if (compressTypeOpt == "packbits") { compressionType = COMPRESSION_PACKBITS; } else if (compressTypeOpt == "lzw") { compressionType = COMPRESSION_LZW; } else if (compressTypeOpt == "jpeg") { compressionType = COMPRESSION_JPEG; } } } } //Code is based from the following article on CodeProject.com //http://www.codeproject.com/bitmap/BitmapsToTiffs.asp TIFF *image; int samplesPerPixel; int bitsPerSample; uint16 photometric; image = TIFFClientOpen("outputstream", "w", (thandle_t)&fout, libtiffOStreamReadProc, //Custom read function libtiffOStreamWriteProc, //Custom write function libtiffOStreamSeekProc, //Custom seek function libtiffStreamCloseProc, //Custom close function libtiffOStreamSizeProc, //Custom size function libtiffStreamMapProc, //Custom map function libtiffStreamUnmapProc); //Custom unmap function if(image == NULL) { return WriteResult::ERROR_IN_WRITING_FILE; } switch(img.getPixelFormat()) { case GL_DEPTH_COMPONENT: case GL_LUMINANCE: case GL_ALPHA: photometric = PHOTOMETRIC_MINISBLACK; samplesPerPixel = 1; break; case GL_LUMINANCE_ALPHA: photometric = PHOTOMETRIC_MINISBLACK; samplesPerPixel = 2; break; case GL_RGB: photometric = PHOTOMETRIC_RGB; samplesPerPixel = 3; break; case GL_RGBA: photometric = PHOTOMETRIC_RGB; samplesPerPixel = 4; break; default: return WriteResult::ERROR_IN_WRITING_FILE; break; } switch(img.getDataType()){ case GL_FLOAT: TIFFSetField(image, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP); TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, 1); bitsPerSample = 32; break; case GL_SHORT: TIFFSetField(image, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT); bitsPerSample = 16; break; default: bitsPerSample = 8; break; } TIFFSetField(image, TIFFTAG_IMAGEWIDTH,img.s()); TIFFSetField(image, TIFFTAG_IMAGELENGTH,img.t()); TIFFSetField(image, TIFFTAG_BITSPERSAMPLE,bitsPerSample); TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL,samplesPerPixel); TIFFSetField(image, TIFFTAG_PHOTOMETRIC, photometric); TIFFSetField(image, TIFFTAG_COMPRESSION, compressionType); TIFFSetField(image, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); TIFFSetField(image, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); //uint32 rowsperstrip = TIFFDefaultStripSize(image, -1); //TIFFSetField(image, TIFFTAG_ROWSPERSTRIP, rowsperstrip); // Write the information to the file for(int i = 0; i < img.t(); ++i) { TIFFWriteScanline(image,(tdata_t)img.data(0,img.t()-i-1),i,0); } // Close the file TIFFClose(image); return WriteResult::FILE_SAVED; }
unsigned char * simage_tiff_load(std::istream& fin, int& width_ret, int& height_ret, int& numComponents_ret, uint16& bitspersample) { TIFF *in; uint16 dataType; uint16 samplesperpixel; uint16 photometric; uint32 w, h; uint16 config; uint16* red; uint16* green; uint16* blue; unsigned char *inbuf = NULL; tsize_t rowsize; uint32 row; int format; unsigned char *buffer; int width; int height; unsigned char *currPtr; TIFFSetErrorHandler(tiff_error); TIFFSetWarningHandler(tiff_warn); in = TIFFClientOpen("inputstream", "r", (thandle_t)&fin, libtiffStreamReadProc, //Custom read function libtiffStreamWriteProc, //Custom write function libtiffStreamSeekProc, //Custom seek function libtiffStreamCloseProc, //Custom close function libtiffStreamSizeProc, //Custom size function libtiffStreamMapProc, //Custom map function libtiffStreamUnmapProc); //Custom unmap function if (in == NULL) { tifferror = ERR_OPEN; return NULL; } if (TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &photometric) == 1) { if (photometric != PHOTOMETRIC_RGB && photometric != PHOTOMETRIC_PALETTE && photometric != PHOTOMETRIC_MINISWHITE && photometric != PHOTOMETRIC_MINISBLACK) { OSG_NOTICE << "Photometric type "<<photometric<<" not handled; can only handle Grayscale, RGB and Palette images" << std::endl; TIFFClose(in); tifferror = ERR_UNSUPPORTED; return NULL; } } else { tifferror = ERR_READ; TIFFClose(in); return NULL; } if (TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel) == 1) { if (samplesperpixel != 1 && samplesperpixel != 2 && samplesperpixel != 3 && samplesperpixel != 4) { OSG_DEBUG << "Bad samples/pixel" << std::endl; tifferror = ERR_UNSUPPORTED; TIFFClose(in); return NULL; } } else { tifferror = ERR_READ; TIFFClose(in); return NULL; } if (TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample) == 1) { if (bitspersample != 8 && bitspersample != 16 && bitspersample != 32) { OSG_NOTICE << "can only handle 8, 16 and 32 bit samples" << std::endl; TIFFClose(in); tifferror = ERR_UNSUPPORTED; return NULL; } } else { tifferror = ERR_READ; TIFFClose(in); return NULL; } if (TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &w) != 1 || TIFFGetField(in, TIFFTAG_IMAGELENGTH, &h) != 1 || TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config) != 1) { TIFFClose(in); tifferror = ERR_READ; return NULL; } TIFFGetField(in, TIFFTAG_DATATYPE, &dataType); OSG_INFO<<"TIFFTAG_DATATYPE="<<dataType<<std::endl; /* if (photometric == PHOTOMETRIC_MINISWHITE || photometric == PHOTOMETRIC_MINISBLACK) format = 1; else format = 3; */ // if it has a palette, data returned is 3 byte rgb // so set format to 3. if (photometric == PHOTOMETRIC_PALETTE) format = 3; else format = samplesperpixel * bitspersample / 8; int bytespersample = bitspersample / 8; int bytesperpixel = bytespersample * samplesperpixel; OSG_INFO<<"format="<<format<<std::endl; OSG_INFO<<"bytespersample="<<bytespersample<<std::endl; OSG_INFO<<"bytesperpixel="<<bytesperpixel<<std::endl; buffer = new unsigned char [w*h*format]; if (!buffer) { tifferror = ERR_MEM; TIFFClose(in); return NULL; } // initialize memory for(unsigned char* ptr=buffer;ptr<buffer+w*h*format;++ptr) *ptr = 0; width = w; height = h; currPtr = buffer + (h-1)*w*format; tifferror = ERR_NO_ERROR; switch (pack(photometric, config)) { case pack(PHOTOMETRIC_MINISWHITE, PLANARCONFIG_CONTIG): case pack(PHOTOMETRIC_MINISBLACK, PLANARCONFIG_CONTIG): case pack(PHOTOMETRIC_MINISWHITE, PLANARCONFIG_SEPARATE): case pack(PHOTOMETRIC_MINISBLACK, PLANARCONFIG_SEPARATE): inbuf = new unsigned char [TIFFScanlineSize(in)]; for (row = 0; row < h; row++) { if (TIFFReadScanline(in, inbuf, row, 0) < 0) { tifferror = ERR_READ; break; } invert_row(currPtr, inbuf, samplesperpixel*w, photometric == PHOTOMETRIC_MINISWHITE, bitspersample); currPtr -= format*w; } break; case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_CONTIG): case pack(PHOTOMETRIC_PALETTE, PLANARCONFIG_SEPARATE): if (TIFFGetField(in, TIFFTAG_COLORMAP, &red, &green, &blue) != 1) tifferror = ERR_READ; /* */ /* Convert 16-bit colormap to 8-bit (unless it looks */ /* like an old-style 8-bit colormap). */ /* */ if (!tifferror && checkcmap(1<<bitspersample, red, green, blue) == 16) { int i; for (i = (1<<bitspersample)-1; i >= 0; i--) { red[i] = CVT(red[i]); green[i] = CVT(green[i]); blue[i] = CVT(blue[i]); } } inbuf = new unsigned char [TIFFScanlineSize(in)]; for (row = 0; row < h; row++) { if (TIFFReadScanline(in, inbuf, row, 0) < 0) { tifferror = ERR_READ; break; } remap_row(currPtr, inbuf, w, red, green, blue); currPtr -= format*w; } break; case pack(PHOTOMETRIC_RGB, PLANARCONFIG_CONTIG): inbuf = new unsigned char [TIFFScanlineSize(in)]; for (row = 0; row < h; row++) { if (TIFFReadScanline(in, inbuf, row, 0) < 0) { tifferror = ERR_READ; break; } memcpy(currPtr, inbuf, format*w); currPtr -= format*w; } break; case pack(PHOTOMETRIC_RGB, PLANARCONFIG_SEPARATE): rowsize = TIFFScanlineSize(in); inbuf = new unsigned char [format*rowsize]; for (row = 0; !tifferror && row < h; row++) { int s; for (s = 0; s < format; s++) { if (TIFFReadScanline(in, (tdata_t)(inbuf+s*rowsize), (uint32)row, (tsample_t)s) < 0) { tifferror = ERR_READ; break; } } if (!tifferror) { if (format==3) interleave_row(currPtr, inbuf, inbuf+rowsize, inbuf+2*rowsize, w, format, bitspersample); else if (format==4) interleave_row(currPtr, inbuf, inbuf+rowsize, inbuf+2*rowsize, inbuf+3*rowsize, w, format, bitspersample); currPtr -= format*w; } } break; default: tifferror = ERR_UNSUPPORTED; break; } if (inbuf) delete [] inbuf; TIFFClose(in); if (tifferror) { if (buffer) delete [] buffer; return NULL; } width_ret = width; height_ret = height; if (photometric == PHOTOMETRIC_PALETTE) numComponents_ret = format; else numComponents_ret = samplesperpixel; return buffer; }
static gboolean gdk_pixbuf__tiff_image_save_to_callback (GdkPixbufSaveFunc save_func, gpointer user_data, GdkPixbuf *pixbuf, gchar **keys, gchar **values, GError **error) { TIFF *tiff; gint width, height, rowstride; const gchar *bits_per_sample = NULL; long bps; const gchar *compression = NULL; guchar *pixels; gboolean has_alpha; gushort alpha_samples[1] = { EXTRASAMPLE_UNASSALPHA }; int y; TiffSaveContext *context; gboolean retval; const gchar *icc_profile = NULL; const gchar *x_dpi = NULL; const gchar *y_dpi = NULL; guint16 codec; tiff_set_handlers (); context = create_save_context (); tiff = TIFFClientOpen ("libtiff-pixbuf", "w", context, tiff_save_read, tiff_save_write, tiff_save_seek, tiff_save_close, tiff_save_size, NULL, NULL); if (!tiff) { g_set_error_literal (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_FAILED, _("Failed to save TIFF image")); free_save_context (context); return FALSE; } rowstride = gdk_pixbuf_get_rowstride (pixbuf); pixels = gdk_pixbuf_get_pixels (pixbuf); has_alpha = gdk_pixbuf_get_has_alpha (pixbuf); height = gdk_pixbuf_get_height (pixbuf); width = gdk_pixbuf_get_width (pixbuf); TIFFSetField (tiff, TIFFTAG_IMAGEWIDTH, width); TIFFSetField (tiff, TIFFTAG_IMAGELENGTH, height); /* libtiff supports a number of 'codecs' such as: 1 None, 2 Huffman, 5 LZW, 7 JPEG, 8 Deflate, see tiff.h */ if (keys && *keys && values && *values) { guint i = 0; while (keys[i]) { if (g_str_equal (keys[i], "bits-per-sample")) bits_per_sample = values[i]; else if (g_str_equal (keys[i], "compression")) compression = values[i]; else if (g_str_equal (keys[i], "icc-profile")) icc_profile = values[i]; else if (g_str_equal (keys[i], "x-dpi")) x_dpi = values[i]; else if (g_str_equal (keys[i], "y-dpi")) y_dpi = values[i]; i++; } } /* Use 8 bits per sample by default, if none was recorded or specified. */ if (!bits_per_sample) bits_per_sample = "8"; /* Use DEFLATE compression (8) by default, if none was recorded or specified. */ if (!compression) compression = "8"; /* libtiff supports a number of 'codecs' such as: 1 None, 2 Huffman, 5 LZW, 7 JPEG, 8 Deflate, see tiff.h */ codec = strtol (compression, NULL, 0); if (TIFFIsCODECConfigured (codec)) TIFFSetField (tiff, TIFFTAG_COMPRESSION, codec); else { g_set_error_literal (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_FAILED, _("TIFF compression doesn't refer to a valid codec.")); retval = FALSE; goto cleanup; } /* We support 1-bit or 8-bit saving */ bps = atol (bits_per_sample); if (bps == 1) { TIFFSetField (tiff, TIFFTAG_BITSPERSAMPLE, 1); TIFFSetField (tiff, TIFFTAG_SAMPLESPERPIXEL, 1); TIFFSetField (tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); TIFFSetField (tiff, TIFFTAG_COMPRESSION, COMPRESSION_CCITTFAX4); } else if (bps == 8) { TIFFSetField (tiff, TIFFTAG_BITSPERSAMPLE, 8); TIFFSetField (tiff, TIFFTAG_SAMPLESPERPIXEL, has_alpha ? 4 : 3); TIFFSetField (tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); if (has_alpha) TIFFSetField (tiff, TIFFTAG_EXTRASAMPLES, 1, alpha_samples); if (icc_profile != NULL) { guchar *icc_profile_buf; gsize icc_profile_size; /* decode from base64 */ icc_profile_buf = g_base64_decode (icc_profile, &icc_profile_size); if (icc_profile_size < 127) { g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_BAD_OPTION, _("Color profile has invalid length %d."), (gint) icc_profile_size); retval = FALSE; g_free (icc_profile_buf); goto cleanup; } TIFFSetField (tiff, TIFFTAG_ICCPROFILE, icc_profile_size, icc_profile_buf); g_free (icc_profile_buf); } } else { /* The passed bits-per-sample is not supported. */ g_set_error_literal (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_FAILED, _("TIFF bits-per-sample doesn't contain a supported value.")); retval = FALSE; goto cleanup; } TIFFSetField (tiff, TIFFTAG_ROWSPERSTRIP, height); TIFFSetField (tiff, TIFFTAG_FILLORDER, FILLORDER_MSB2LSB); TIFFSetField (tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); if (bps == 1) { guchar *mono_row; gint *dith_row_1, *dith_row_2, *dith_row_tmp; dith_row_1 = g_new (gint, width); dith_row_2 = g_new (gint, width); mono_row = g_malloc ((width + 7) / 8); copy_gray_row (dith_row_1, pixels, width, has_alpha); for (y = 0; y < height; y++) { guint x; gint *p; memset (mono_row, 0, (width + 7) / 8); if (y > 0) { dith_row_tmp = dith_row_1; dith_row_1 = dith_row_2; dith_row_2 = dith_row_tmp; } if (y < (height - 1)) copy_gray_row (dith_row_2, pixels + ((y + 1) * rowstride), width, has_alpha); p = dith_row_1; for (x = 0; x < width; x++) { gint p_old, p_new, quant_error; /* Apply Floyd-Steinberg dithering */ p_old = *p++; if (p_old > 127) p_new = 255; else p_new = 0; quant_error = p_old - p_new; if (x < (width - 1)) dith_row_1[x + 1] += 7 * quant_error / 16; if (y < (height - 1)) { if (x > 0) dith_row_2[x - 1] += 3 * quant_error / 16; dith_row_2[x] += 5 * quant_error / 16; if (x < (width - 1)) dith_row_2[x + 1] += quant_error / 16; } if (p_new > 127) mono_row[x / 8] |= (0x1 << (7 - (x % 8))); } if (TIFFWriteScanline (tiff, mono_row, y, 0) == -1) break; } g_free (mono_row); g_free (dith_row_1); g_free (dith_row_2); } else { for (y = 0; y < height; y++) { if (TIFFWriteScanline (tiff, pixels + y * rowstride, y, 0) == -1) break; } } if (y < height) { g_set_error_literal (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_FAILED, _("Failed to write TIFF data")); TIFFClose (tiff); retval = FALSE; goto cleanup; } if (x_dpi != NULL && y_dpi != NULL) { char *endptr = NULL; uint16 resolution_unit = RESUNIT_INCH; float x_dpi_value, y_dpi_value; x_dpi_value = strtol (x_dpi, &endptr, 10); if (x_dpi[0] != '\0' && *endptr != '\0') x_dpi_value = -1; if (x_dpi_value <= 0) { g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_BAD_OPTION, _("TIFF x-dpi must be greater than zero; value '%s' is not allowed."), x_dpi); retval = FALSE; goto cleanup; } y_dpi_value = strtol (y_dpi, &endptr, 10); if (y_dpi[0] != '\0' && *endptr != '\0') y_dpi_value = -1; if (y_dpi_value <= 0) { g_set_error (error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_BAD_OPTION, _("TIFF y-dpi must be greater than zero; value '%s' is not allowed."), y_dpi); retval = FALSE; goto cleanup; } TIFFSetField (tiff, TIFFTAG_RESOLUTIONUNIT, resolution_unit); TIFFSetField (tiff, TIFFTAG_XRESOLUTION, x_dpi_value); TIFFSetField (tiff, TIFFTAG_YRESOLUTION, y_dpi_value); } TIFFClose (tiff); /* Now call the callback */ retval = save_func (context->buffer, context->used, error, user_data); cleanup: free_save_context (context); return retval; }
int main(int argc, char* argv[]) { FILE *in; TIFF *out = NULL; TIFFErrorHandler whandler = NULL; int compression_in = COMPRESSION_CCITTFAX3; int compression_out = COMPRESSION_CCITTFAX3; int fillorder_in = FILLORDER_LSB2MSB; int fillorder_out = FILLORDER_LSB2MSB; uint32 group3options_in = 0; /* 1d-encoded */ uint32 group3options_out = 0; /* 1d-encoded */ uint32 group4options_in = 0; /* compressed */ uint32 group4options_out = 0; /* compressed */ uint32 defrowsperstrip = (uint32) 0; uint32 rowsperstrip; int photometric_in = PHOTOMETRIC_MINISWHITE; int photometric_out = PHOTOMETRIC_MINISWHITE; int mode = FAXMODE_CLASSF; int rows; int c; int pn, npages; float resY = 196.0; extern int optind; extern char* optarg; while ((c = getopt(argc, argv, "R:X:o:1234ABLMPUW5678abcflmprsuvwz?")) != -1) switch (c) { /* input-related options */ case '3': /* input is g3-encoded */ compression_in = COMPRESSION_CCITTFAX3; break; case '4': /* input is g4-encoded */ compression_in = COMPRESSION_CCITTFAX4; break; case 'U': /* input is uncompressed (g3 and g4) */ group3options_in |= GROUP3OPT_UNCOMPRESSED; group4options_in |= GROUP4OPT_UNCOMPRESSED; break; case '1': /* input is 1d-encoded (g3 only) */ group3options_in &= ~GROUP3OPT_2DENCODING; break; case '2': /* input is 2d-encoded (g3 only) */ group3options_in |= GROUP3OPT_2DENCODING; break; case 'P': /* input has not-aligned EOL (g3 only) */ group3options_in &= ~GROUP3OPT_FILLBITS; break; case 'A': /* input has aligned EOL (g3 only) */ group3options_in |= GROUP3OPT_FILLBITS; break; case 'W': /* input has 0 mean white */ photometric_in = PHOTOMETRIC_MINISWHITE; break; case 'B': /* input has 0 mean black */ photometric_in = PHOTOMETRIC_MINISBLACK; break; case 'L': /* input has lsb-to-msb fillorder */ fillorder_in = FILLORDER_LSB2MSB; break; case 'M': /* input has msb-to-lsb fillorder */ fillorder_in = FILLORDER_MSB2LSB; break; case 'R': /* input resolution */ resY = (float) atof(optarg); break; case 'X': /* input width */ xsize = (uint32) atoi(optarg); break; /* output-related options */ case '7': /* generate g3-encoded output */ compression_out = COMPRESSION_CCITTFAX3; break; case '8': /* generate g4-encoded output */ compression_out = COMPRESSION_CCITTFAX4; break; case 'u': /* generate uncompressed output (g3 and g4) */ group3options_out |= GROUP3OPT_UNCOMPRESSED; group4options_out |= GROUP4OPT_UNCOMPRESSED; break; case '5': /* generate 1d-encoded output (g3 only) */ group3options_out &= ~GROUP3OPT_2DENCODING; break; case '6': /* generate 2d-encoded output (g3 only) */ group3options_out |= GROUP3OPT_2DENCODING; break; case 'c': /* generate "classic" g3 format */ mode = FAXMODE_CLASSIC; break; case 'f': /* generate Class F format */ mode = FAXMODE_CLASSF; break; case 'm': /* output's fillorder is msb-to-lsb */ fillorder_out = FILLORDER_MSB2LSB; break; case 'l': /* output's fillorder is lsb-to-msb */ fillorder_out = FILLORDER_LSB2MSB; break; case 'o': out = TIFFOpen(optarg, "w"); if (out == NULL) { fprintf(stderr, "%s: Can not create or open %s\n", argv[0], optarg); return EXIT_FAILURE; } break; case 'a': /* generate EOL-aligned output (g3 only) */ group3options_out |= GROUP3OPT_FILLBITS; break; case 'p': /* generate not EOL-aligned output (g3 only) */ group3options_out &= ~GROUP3OPT_FILLBITS; break; case 'r': /* rows/strip */ defrowsperstrip = atol(optarg); break; case 's': /* stretch image by dup'ng scanlines */ stretch = 1; break; case 'w': /* undocumented -- for testing */ photometric_out = PHOTOMETRIC_MINISWHITE; break; case 'b': /* undocumented -- for testing */ photometric_out = PHOTOMETRIC_MINISBLACK; break; case 'z': /* undocumented -- for testing */ compression_out = COMPRESSION_LZW; break; case 'v': /* -v for info */ verbose++; break; case '?': usage(); /*NOTREACHED*/ } npages = argc - optind; if (npages < 1) usage(); rowbuf = _TIFFmalloc(TIFFhowmany8(xsize)); refbuf = _TIFFmalloc(TIFFhowmany8(xsize)); if (rowbuf == NULL || refbuf == NULL) { fprintf(stderr, "%s: Not enough memory\n", argv[0]); return (EXIT_FAILURE); } if (out == NULL) { out = TIFFOpen("fax.tif", "w"); if (out == NULL) { fprintf(stderr, "%s: Can not create fax.tif\n", argv[0]); return (EXIT_FAILURE); } } faxTIFF = TIFFClientOpen("(FakeInput)", "w", /* TIFFClientOpen() fails if we don't set existing value here */ TIFFClientdata(out), TIFFGetReadProc(out), TIFFGetWriteProc(out), TIFFGetSeekProc(out), TIFFGetCloseProc(out), TIFFGetSizeProc(out), TIFFGetMapFileProc(out), TIFFGetUnmapFileProc(out)); if (faxTIFF == NULL) { fprintf(stderr, "%s: Can not create fake input file\n", argv[0]); return (EXIT_FAILURE); } TIFFSetMode(faxTIFF, O_RDONLY); TIFFSetField(faxTIFF, TIFFTAG_IMAGEWIDTH, xsize); TIFFSetField(faxTIFF, TIFFTAG_SAMPLESPERPIXEL, 1); TIFFSetField(faxTIFF, TIFFTAG_BITSPERSAMPLE, 1); TIFFSetField(faxTIFF, TIFFTAG_FILLORDER, fillorder_in); TIFFSetField(faxTIFF, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(faxTIFF, TIFFTAG_PHOTOMETRIC, photometric_in); TIFFSetField(faxTIFF, TIFFTAG_YRESOLUTION, resY); TIFFSetField(faxTIFF, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); /* NB: this must be done after directory info is setup */ TIFFSetField(faxTIFF, TIFFTAG_COMPRESSION, compression_in); if (compression_in == COMPRESSION_CCITTFAX3) TIFFSetField(faxTIFF, TIFFTAG_GROUP3OPTIONS, group3options_in); else if (compression_in == COMPRESSION_CCITTFAX4) TIFFSetField(faxTIFF, TIFFTAG_GROUP4OPTIONS, group4options_in); for (pn = 0; optind < argc; pn++, optind++) { in = fopen(argv[optind], "r" BINMODE); if (in == NULL) { fprintf(stderr, "%s: %s: Can not open\n", argv[0], argv[optind]); continue; } #if defined(_WIN32) && defined(USE_WIN32_FILEIO) TIFFSetClientdata(faxTIFF, (thandle_t)_get_osfhandle(fileno(in))); #else TIFFSetClientdata(faxTIFF, (thandle_t)fileno(in)); #endif TIFFSetFileName(faxTIFF, (const char*)argv[optind]); TIFFSetField(out, TIFFTAG_IMAGEWIDTH, xsize); TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 1); TIFFSetField(out, TIFFTAG_COMPRESSION, compression_out); TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric_out); TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1); switch (compression_out) { /* g3 */ case COMPRESSION_CCITTFAX3: TIFFSetField(out, TIFFTAG_GROUP3OPTIONS, group3options_out); TIFFSetField(out, TIFFTAG_FAXMODE, mode); rowsperstrip = (defrowsperstrip)?defrowsperstrip:(uint32)-1L; break; /* g4 */ case COMPRESSION_CCITTFAX4: TIFFSetField(out, TIFFTAG_GROUP4OPTIONS, group4options_out); TIFFSetField(out, TIFFTAG_FAXMODE, mode); rowsperstrip = (defrowsperstrip)?defrowsperstrip:(uint32)-1L; break; default: rowsperstrip = (defrowsperstrip) ? defrowsperstrip : TIFFDefaultStripSize(out, 0); } TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip); TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(out, TIFFTAG_FILLORDER, fillorder_out); TIFFSetField(out, TIFFTAG_SOFTWARE, "fax2tiff"); TIFFSetField(out, TIFFTAG_XRESOLUTION, 204.0); if (!stretch) { TIFFGetField(faxTIFF, TIFFTAG_YRESOLUTION, &resY); TIFFSetField(out, TIFFTAG_YRESOLUTION, resY); } else TIFFSetField(out, TIFFTAG_YRESOLUTION, 196.); TIFFSetField(out, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); TIFFSetField(out, TIFFTAG_PAGENUMBER, pn, npages); if (!verbose) whandler = TIFFSetWarningHandler(NULL); rows = copyFaxFile(faxTIFF, out); fclose(in); if (!verbose) (void) TIFFSetWarningHandler(whandler); TIFFSetField(out, TIFFTAG_IMAGELENGTH, rows); if (verbose) { fprintf(stderr, "%s:\n", argv[optind]); fprintf(stderr, "%d rows in input\n", rows); fprintf(stderr, "%ld total bad rows\n", (long) badfaxlines); fprintf(stderr, "%d max consecutive bad rows\n", badfaxrun); } if (compression_out == COMPRESSION_CCITTFAX3 && mode == FAXMODE_CLASSF) { TIFFSetField(out, TIFFTAG_BADFAXLINES, badfaxlines); TIFFSetField(out, TIFFTAG_CLEANFAXDATA, badfaxlines ? CLEANFAXDATA_REGENERATED : CLEANFAXDATA_CLEAN); TIFFSetField(out, TIFFTAG_CONSECUTIVEBADFAXLINES, badfaxrun); } TIFFWriteDirectory(out); } TIFFClose(out); _TIFFfree(rowbuf); _TIFFfree(refbuf); return (EXIT_SUCCESS); }