Exemplo n.º 1
0
Arquivo: IMG_tif.c Projeto: K0F/FreeJ
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
/*
 * 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);
}
Exemplo n.º 8
0
Arquivo: io-tiff.c Projeto: hb/gtk
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;
}
Exemplo n.º 9
0
TIFF *iTIFFOpen(char *Mode)
{
	TIFF *tif;

	tif = TIFFClientOpen("TIFFMemFile", Mode,
						NULL,
						_tiffFileReadProc, _tiffFileWriteProc,
						_tiffFileSeekProc, _tiffFileCloseProc,
						_tiffFileSizeProc, _tiffDummyMapProc,
						_tiffDummyUnmapProc);

	return tif;
}
Exemplo n.º 10
0
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);
}
Exemplo n.º 11
0
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);
}
Exemplo n.º 12
0
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);
    }
}
Exemplo n.º 13
0
/*
 * 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);
}
Exemplo n.º 14
0
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);
}
Exemplo n.º 15
0
/*
 * 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);
}
Exemplo n.º 16
0
/*
 * 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;
}
Exemplo n.º 17
0
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();
}
Exemplo n.º 18
0
	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);
	}
Exemplo n.º 19
0
/*
 * 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);
}
Exemplo n.º 20
0
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;
}
Exemplo n.º 22
0
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;
}
Exemplo n.º 23
0
/*
 * 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);
}
Exemplo n.º 24
0
        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;
        }
Exemplo n.º 25
0
//----------------------------------------------------------------------------
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);
    }
}
Exemplo n.º 26
0
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) ;
}
Exemplo n.º 27
0
        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;
        }
Exemplo n.º 28
0
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;
}
Exemplo n.º 29
0
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;
}
Exemplo n.º 30
0
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);
}