Example #1
0
int ReadTile(TIFF* tiff, UINT32 col, UINT32 row, UINT32* buffer) {
    uint16 photometric;

    TIFFGetField(tiff, TIFFTAG_PHOTOMETRIC, &photometric);

    // To avoid dealing with YCbCr subsampling, let libtiff handle it
    if (photometric == PHOTOMETRIC_YCBCR) {
        UINT32 tile_width, tile_height, swap_line_size, i_row;
        UINT32* swap_line;

        TIFFGetField(tiff, TIFFTAG_TILEWIDTH, &tile_width);
        TIFFGetField(tiff, TIFFTAG_TILELENGTH, &tile_height);

        swap_line_size = tile_width * sizeof(UINT32);
        if (tile_width != swap_line_size / sizeof(UINT32)) {
            return -1;
        }

        /* Read the tile into an RGBA array */
        if (!TIFFReadRGBATile(tiff, col, row, buffer)) {
            return -1;
        }

        swap_line = (UINT32*)malloc(swap_line_size);
        /*
         * For some reason the TIFFReadRGBATile() function chooses the
         * lower left corner as the origin.  Vertically mirror scanlines.
         */
        for(i_row = 0; i_row < tile_height / 2; i_row++) {
            UINT32 *top_line, *bottom_line;

            top_line = buffer + tile_width * i_row;
            bottom_line = buffer + tile_width * (tile_height - i_row - 1);

            memcpy(swap_line, top_line, 4*tile_width);
            memcpy(top_line, bottom_line, 4*tile_width);
            memcpy(bottom_line, swap_line, 4*tile_width);
        }

        free(swap_line);

        return 0;
    }

    if (TIFFReadTile(tiff, (tdata_t)buffer, col, row, 0, 0) == -1) {
        TRACE(("Decode Error, Tile at %dx%d\n", col, row));
        return -1;
    }

    TRACE(("Successfully read tile at %dx%d; \n\n", col, row));

    return 0;
}
Example #2
0
void tiff_reader<T>::read_tiled(unsigned x0,unsigned y0,image_data_32& image)
{
    TIFF* tif = open(stream_);
    if (tif)
    {
        uint32* buf = (uint32*)_TIFFmalloc(tile_width_*tile_height_*sizeof(uint32));
        int width=image.width();
        int height=image.height();

        int start_y=(y0/tile_height_)*tile_height_;
        int end_y=((y0+height)/tile_height_+1)*tile_height_;

        int start_x=(x0/tile_width_)*tile_width_;
        int end_x=((x0+width)/tile_width_+1)*tile_width_;
        int row,tx0,tx1,ty0,ty1;

        for (int y=start_y;y<end_y;y+=tile_height_)
        {
            ty0 = std::max(y0,(unsigned)y) - y;
            ty1 = std::min(height+y0,(unsigned)(y+tile_height_)) - y;

            int n0=tile_height_-ty1;
            int n1=tile_height_-ty0-1;

            for (int x=start_x;x<end_x;x+=tile_width_)
            {

                if (!TIFFReadRGBATile(tif,x,y,buf)) break;

                tx0=std::max(x0,(unsigned)x);
                tx1=std::min(width+x0,(unsigned)(x+tile_width_));
                row=y+ty0-y0;
                for (int n=n1;n>=n0;--n)
                {
                    image.setRow(row,tx0-x0,tx1-x0,(const unsigned*)&buf[n*tile_width_+tx0-x]);
                    ++row;
                }
            }
        }
        _TIFFfree(buf);
    }
}
Example #3
0
void imb_loadtiletiff(ImBuf *ibuf, unsigned char *mem, size_t size, int tx, int ty, unsigned int *rect)
{
	TIFF *image = NULL;
	uint32 width, height;
	ImbTIFFMemFile memFile;

	image = imb_tiff_client_open(&memFile, mem, size);

	if(image == NULL) {
		printf("imb_loadtiff: could not open TIFF IO layer for loading mipmap level.\n");
		return;
	}

   	if(TIFFSetDirectory(image, ibuf->miplevel)) {
		/* allocate the image buffer */
		TIFFGetField(image, TIFFTAG_IMAGEWIDTH,  &width);
		TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);

		if(width == ibuf->x && height == ibuf->y) {
			if(rect) {
				/* tiff pixels are bottom to top, tiles are top to bottom */
				if(TIFFReadRGBATile(image, tx*ibuf->tilex, (ibuf->ytiles - 1 - ty)*ibuf->tiley, rect) == 1) {
					if(ibuf->tiley > ibuf->y)
						memmove(rect, rect+ibuf->tilex*(ibuf->tiley - ibuf->y), sizeof(int)*ibuf->tilex*ibuf->y);

					if(ibuf->flags & IB_premul)
						IMB_premultiply_rect(rect, 32, ibuf->tilex, ibuf->tiley);
				}
				else
					printf("imb_loadtiff: failed to read tiff tile at mipmap level %d\n", ibuf->miplevel);
			}
		}
		else
			printf("imb_loadtiff: mipmap level %d has unexpected size %dx%d instead of %dx%d\n", ibuf->miplevel, width, height, ibuf->x, ibuf->y);
	}
	else
		printf("imb_loadtiff: could not find mipmap level %d\n", ibuf->miplevel);

	/* close the client layer interface to the in-memory file */
	TIFFClose(image);
}
Example #4
0
int
main(int argc, char **argv)
{
	TIFF		*tif;
	static const char *srcfilerel = "images/quad-tile.jpg.tiff";
	char *srcdir = NULL;
	char srcfile[1024];
	unsigned short h, v;
	int status;
	unsigned char *buffer;
	uint32 *rgba_buffer;
	tsize_t sz, szout;
	unsigned int pixel_status = 0;

        (void) argc;
        (void) argv;

	if ((srcdir = getenv("srcdir")) == NULL) {
		srcdir = ".";
	}
	if ((strlen(srcdir) + 1 + strlen(srcfilerel)) >= sizeof(srcfile)) {
		fprintf( stderr, "srcdir too long %s\n", srcdir);
		exit( 1 );
	}
	strcpy(srcfile,srcdir);
	strcat(srcfile,"/");
	strcat(srcfile,srcfilerel);

	tif = TIFFOpen(srcfile,"r");
	if ( tif == NULL ) {
		fprintf( stderr, "Could not open %s\n", srcfile);
		exit( 1 );
	}

	status = TIFFGetField(tif,TIFFTAG_YCBCRSUBSAMPLING, &h, &v);
	if ( status == 0 || h != 2 || v != 2) {
		fprintf( stderr, "Could not retrieve subsampling tag.\n" );
		exit(1);
	}

	/*
	 * What is the appropriate size of a YCbCr encoded tile?
	 */
	sz = TIFFTileSize(tif);
	if( sz != 24576) {
		fprintf(stderr, "tiles are %d bytes\n", (int)sz);
		exit(1);
	}

	buffer = (unsigned char *) malloc(sz);

	/*
	 * Read a tile in decompressed form, but still YCbCr subsampled.
	 */
	szout = TIFFReadEncodedTile(tif,9,buffer,sz);
	if (szout != sz) {
		fprintf( stderr, 
			 "Did not get expected result code from TIFFReadEncodedTile()(%d instead of %d)\n", 
			 (int) szout, (int) sz );
		return 1;
	}

	if( check_cluster( 0, buffer, cluster_0 )
	    || check_cluster( 64, buffer, cluster_64 )
	    || check_cluster( 128, buffer, cluster_128 ) ) {
		exit(1);
	}
	free(buffer);

	/*
	 * Read a tile using the built-in conversion to RGB format provided by the JPEG library.
	 */
	TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);

	sz = TIFFTileSize(tif);
	if( sz != 128*128*3) {
		fprintf(stderr, "tiles are %d bytes\n", (int)sz);
		exit(1);
	}

	buffer = (unsigned char *) malloc(sz);

	szout = TIFFReadEncodedTile(tif,9,buffer,sz);
	if (szout != sz) {
		fprintf( stderr, 
			 "Did not get expected result code from TIFFReadEncodedTile()(%d instead of %d)\n", 
			 (int) szout, (int) sz );
		return 1;
	}

#if JPEG_LIB_VERSION >= 70
	pixel_status |= check_rgb_pixel( 0, 18, 0, 41, buffer );
	pixel_status |= check_rgb_pixel( 64, 0, 0, 0, buffer );
	pixel_status |= check_rgb_pixel( 512, 5, 34, 196, buffer );
#else
	pixel_status |= check_rgb_pixel( 0, 15, 0, 18, buffer );
	pixel_status |= check_rgb_pixel( 64, 0, 0, 2, buffer );
	pixel_status |= check_rgb_pixel( 512, 6, 36, 182, buffer );
#endif

	free( buffer );

	TIFFClose(tif);

	/*
	 * Reopen and test reading using the RGBA interface.
	 */
	tif = TIFFOpen(srcfile,"r");
	
	sz = 128 * 128 * sizeof(uint32);
	rgba_buffer = (uint32 *) malloc(sz);
	
	if (!TIFFReadRGBATile( tif, 1*128, 2*128, rgba_buffer )) {
		fprintf( stderr, "TIFFReadRGBATile() returned failure code.\n" );
		return 1;
	}

	/*
	 * Currently TIFFReadRGBATile() just uses JPEGCOLORMODE_RGB so this
	 * trivally matches the last results.  Eventually we should actually
	 * accomplish it from the YCbCr subsampled buffer ourselves in which
	 * case the results may be subtly different but similar.
	 */
#if JPEG_LIB_VERSION >= 70
	pixel_status |= check_rgba_pixel( 0, 18, 0, 41, 255, rgba_buffer );
	pixel_status |= check_rgba_pixel( 64, 0, 0, 0, 255, rgba_buffer );
	pixel_status |= check_rgba_pixel( 512, 5, 34, 196, 255, rgba_buffer );
#else
	pixel_status |= check_rgba_pixel( 0, 15, 0, 18, 255, rgba_buffer );
	pixel_status |= check_rgba_pixel( 64, 0, 0, 2, 255, rgba_buffer );
	pixel_status |= check_rgba_pixel( 512, 6, 36, 182, 255, rgba_buffer );
#endif

	free( rgba_buffer );
	TIFFClose(tif);

	if (pixel_status) {
		exit(1);
	}
	
	exit( 0 );
}
Example #5
0
bool  TiffDecoder::readData( Mat& img )
{
    bool result = false;
    bool color = img.channels() > 1;
    uchar* data = img.data;
    int step = (int)img.step;

    if( img.depth() != CV_8U && img.depth() != CV_16U && img.depth() != CV_32F && img.depth() != CV_64F )
        return false;

    if( m_tif && m_width && m_height )
    {
        TIFF* tif = (TIFF*)m_tif;
        int tile_width0 = m_width, tile_height0 = 0;
        int x, y, i;
        int is_tiled = TIFFIsTiled(tif);
        int photometric;
        TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric );
        int bpp = 8, ncn = photometric > 1 ? 3 : 1;
        TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp );
        TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn );
        const int bitsPerByte = 8;
        int dst_bpp = (int)(img.elemSize1() * bitsPerByte);

        if(dst_bpp == 8)
        {
            char errmsg[1024];
            if(!TIFFRGBAImageOK( tif, errmsg ))
            {
                close();
                return false;
            }
        }

        if( (!is_tiled) ||
            (is_tiled &&
            TIFFGetField( tif, TIFFTAG_TILEWIDTH, &tile_width0 ) &&
            TIFFGetField( tif, TIFFTAG_TILELENGTH, &tile_height0 )))
        {
            if(!is_tiled)
                TIFFGetField( tif, TIFFTAG_ROWSPERSTRIP, &tile_height0 );

            if( tile_width0 <= 0 )
                tile_width0 = m_width;

            if( tile_height0 <= 0 )
                tile_height0 = m_height;

            AutoBuffer<uchar> _buffer(tile_height0*tile_width0*8);
            uchar* buffer = _buffer;
            ushort* buffer16 = (ushort*)buffer;
            float* buffer32 = (float*)buffer;
            double* buffer64 = (double*)buffer;
            int tileidx = 0;

            for( y = 0; y < m_height; y += tile_height0, data += step*tile_height0 )
            {
                int tile_height = tile_height0;

                if( y + tile_height > m_height )
                    tile_height = m_height - y;

                for( x = 0; x < m_width; x += tile_width0, tileidx++ )
                {
                    int tile_width = tile_width0, ok;

                    if( x + tile_width > m_width )
                        tile_width = m_width - x;

                    switch(dst_bpp)
                    {
                        case 8:
                        {
                            if( !is_tiled )
                                ok = TIFFReadRGBAStrip( tif, y, (uint32*)buffer );
                            else
                                ok = TIFFReadRGBATile( tif, x, y, (uint32*)buffer );

                            if( !ok )
                            {
                                close();
                                return false;
                            }

                            for( i = 0; i < tile_height; i++ )
                                if( color )
                                    icvCvt_BGRA2BGR_8u_C4C3R( buffer + i*tile_width*4, 0,
                                                             data + x*3 + step*(tile_height - i - 1), 0,
                                                             cvSize(tile_width,1), 2 );
                                else
                                    icvCvt_BGRA2Gray_8u_C4C1R( buffer + i*tile_width*4, 0,
                                                              data + x + step*(tile_height - i - 1), 0,
                                                              cvSize(tile_width,1), 2 );
                            break;
                        }

                        case 16:
                        {
                            if( !is_tiled )
                                ok = (int)TIFFReadEncodedStrip( tif, tileidx, (uint32*)buffer, (tsize_t)-1 ) >= 0;
                            else
                                ok = (int)TIFFReadEncodedTile( tif, tileidx, (uint32*)buffer, (tsize_t)-1 ) >= 0;

                            if( !ok )
                            {
                                close();
                                return false;
                            }

                            for( i = 0; i < tile_height; i++ )
                            {
                                if( color )
                                {
                                    if( ncn == 1 )
                                    {
                                        icvCvt_Gray2BGR_16u_C1C3R(buffer16 + i*tile_width*ncn, 0,
                                                                  (ushort*)(data + step*i) + x*3, 0,
                                                                  cvSize(tile_width,1) );
                                    }
                                    else if( ncn == 3 )
                                    {
                                        icvCvt_RGB2BGR_16u_C3R(buffer16 + i*tile_width*ncn, 0,
                                                               (ushort*)(data + step*i) + x*3, 0,
                                                               cvSize(tile_width,1) );
                                    }
                                    else
                                    {
                                        icvCvt_BGRA2BGR_16u_C4C3R(buffer16 + i*tile_width*ncn, 0,
                                                               (ushort*)(data + step*i) + x*3, 0,
                                                               cvSize(tile_width,1), 2 );
                                    }
                                }
                                else
                                {
                                    if( ncn == 1 )
                                    {
                                        memcpy((ushort*)(data + step*i)+x,
                                               buffer16 + i*tile_width*ncn,
                                               tile_width*sizeof(buffer16[0]));
                                    }
                                    else
                                    {
                                        icvCvt_BGRA2Gray_16u_CnC1R(buffer16 + i*tile_width*ncn, 0,
                                                               (ushort*)(data + step*i) + x, 0,
                                                               cvSize(tile_width,1), ncn, 2 );
                                    }
                                }
                            }
                            break;
                        }

                        case 32:
                        case 64:
                        {
                            if( !is_tiled )
                                ok = (int)TIFFReadEncodedStrip( tif, tileidx, buffer, (tsize_t)-1 ) >= 0;
                            else
                                ok = (int)TIFFReadEncodedTile( tif, tileidx, buffer, (tsize_t)-1 ) >= 0;

                            if( !ok || ncn != 1 )
                            {
                                close();
                                return false;
                            }

                            for( i = 0; i < tile_height; i++ )
                            {
                                if(dst_bpp == 32)
                                {
                                    memcpy((float*)(data + step*i)+x,
                                           buffer32 + i*tile_width*ncn,
                                           tile_width*sizeof(buffer32[0]));
                                }
                                else
                                {
                                    memcpy((double*)(data + step*i)+x,
                                         buffer64 + i*tile_width*ncn,
                                         tile_width*sizeof(buffer64[0]));
                                }
                            }

                            break;
                        }
                        default:
                        {
                            close();
                            return false;
                        }
                    }
                }
            }

            result = true;
        }
    }

    close();
    return result;
}
Example #6
0
static int
cvt_by_tile( TIFF *in, TIFF *out )

{
    uint32* raster;			/* retrieve RGBA image */
    uint32  width, height;		/* image width & height */
    uint32  tile_width, tile_height;
    uint32  row, col;
    uint32  *wrk_line;
    int	    ok = 1;

    TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width);
    TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height);

    if( !TIFFGetField(in, TIFFTAG_TILEWIDTH, &tile_width)
        || !TIFFGetField(in, TIFFTAG_TILELENGTH, &tile_height) ) {
        TIFFError(TIFFFileName(in), "Source image not tiled");
        return (0);
    }
    
    TIFFSetField(out, TIFFTAG_TILEWIDTH, tile_width );
    TIFFSetField(out, TIFFTAG_TILELENGTH, tile_height );

    /*
     * Allocate tile buffer
     */
    raster = (uint32*)_TIFFmalloc(tile_width * tile_height * sizeof (uint32));
    if (raster == 0) {
        TIFFError(TIFFFileName(in), "No space for raster buffer");
        return (0);
    }

    /*
     * Allocate a scanline buffer for swapping during the vertical
     * mirroring pass.
     */
    wrk_line = (uint32*)_TIFFmalloc(tile_width * sizeof (uint32));
    if (!wrk_line) {
        TIFFError(TIFFFileName(in), "No space for raster scanline buffer");
        ok = 0;
    }
    
    /*
     * Loop over the tiles.
     */
    for( row = 0; ok && row < height; row += tile_height )
    {
        for( col = 0; ok && col < width; col += tile_width )
        {
            uint32 i_row;

            /* Read the tile into an RGBA array */
            if (!TIFFReadRGBATile(in, col, row, raster)) {
                ok = 0;
                break;
            }

            /*
             * For some reason the TIFFReadRGBATile() function chooses the
             * lower left corner as the origin.  Vertically mirror scanlines.
             */
            for( i_row = 0; i_row < tile_height / 2; i_row++ )
            {
                uint32	*top_line, *bottom_line;

                top_line = raster + tile_width * i_row;
                bottom_line = raster + tile_width * (tile_height-i_row-1);

                _TIFFmemcpy(wrk_line, top_line, 4*tile_width);
                _TIFFmemcpy(top_line, bottom_line, 4*tile_width);
                _TIFFmemcpy(bottom_line, wrk_line, 4*tile_width);
            }

            /*
             * Write out the result in a tile.
             */

            if( TIFFWriteEncodedTile( out,
                                      TIFFComputeTile( out, col, row, 0, 0),
                                      raster,
                                      4 * tile_width * tile_height ) == -1 )
            {
                ok = 0;
                break;
            }
        }
    }

    _TIFFfree( raster );
    _TIFFfree( wrk_line );

    return ok;
}
Example #7
0
int
main(int argc, char **argv)
{
	TIFF		*tif;
	static const char *srcfilerel = "images/quad-tile.jpg.tiff";
	char *srcdir = NULL;
	char srcfile[1024];
	unsigned short h, v;
	int status;
	unsigned char *buffer;
	uint32 *rgba_buffer;
	tsize_t sz, szout;
	unsigned int pixel_status = 0;

        (void) argc;
        (void) argv;

	if ((srcdir = getenv("srcdir")) == NULL) {
		srcdir = ".";
	}
        printf("XXXXXXXX %s",srcdir);
	if ((strlen(srcdir) + 1 + strlen(srcfilerel)) >= sizeof(srcfile)) {
		fprintf( stderr, "srcdir too long %s\n", srcdir);
		exit( 1 );
	}
	strcpy(srcfile,srcdir);
	strcat(srcfile,"/");
	strcat(srcfile,srcfilerel);

	tif = TIFFOpen(srcfile,"r");
	if ( tif == NULL ) {
		fprintf( stderr, "Could not open %s\n", srcfile);
		exit( 1 );
	}

	status = TIFFGetField(tif,TIFFTAG_YCBCRSUBSAMPLING, &h, &v);
	if ( status == 0 || h != 2 || v != 2) {
		fprintf( stderr, "Could not retrieve subsampling tag.\n" );
		exit(1);
	}

	/*
	 * What is the appropriate size of a YCbCr encoded tile?
	 */
	sz = TIFFTileSize(tif);
	if( sz != 24576) {
		fprintf(stderr, "tiles are %d bytes\n", (int)sz);
		exit(1);
	}

	buffer = (unsigned char *) malloc(sz);

	/*
	 * Read a tile in decompressed form, but still YCbCr subsampled.
	 */
	szout = TIFFReadEncodedTile(tif,9,buffer,sz);
	if (szout != sz) {
		fprintf( stderr,
			 "Did not get expected result code from TIFFReadEncodedTile()(%d instead of %d)\n",
			 (int) szout, (int) sz );
		return 1;
	}

	if( check_cluster( 0, buffer, cluster_0 )
	    || check_cluster( 64, buffer, cluster_64 )
	    || check_cluster( 128, buffer, cluster_128 ) ) {
		exit(1);
	}
	free(buffer);

	/*
	 * Read a tile using the built-in conversion to RGB format provided by the JPEG library.
	 */
	TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);

	sz = TIFFTileSize(tif);
	if( sz != 128*128*3) {
		fprintf(stderr, "tiles are %d bytes\n", (int)sz);
		exit(1);
	}

	buffer = (unsigned char *) malloc(sz);

	szout = TIFFReadEncodedTile(tif,9,buffer,sz);
	if (szout != sz) {
		fprintf( stderr,
			 "Did not get expected result code from TIFFReadEncodedTile()(%d instead of %d)\n",
			 (int) szout, (int) sz );
		return 1;
	}

	/*
	 * JPEG decoding is inherently inexact, so we can't test for exact
	 * pixel values.  (Well, if we knew exactly which libjpeg version
	 * we were using, and with what settings, we could expect specific
	 * values ... but it's not worth the trouble to keep track of.)
	 * Hence, use ranges of expected values.  The ranges may need to be
	 * widened over time as more versions of libjpeg appear.
	 */
	pixel_status |= check_rgb_pixel( 0, 15, 18, 0, 0, 18, 41, buffer );
	pixel_status |= check_rgb_pixel( 64, 0, 0, 0, 0, 0, 2, buffer );
	pixel_status |= check_rgb_pixel( 512, 5, 6, 34, 36, 182, 196, buffer );

	free( buffer );

	TIFFClose(tif);

	/*
	 * Reopen and test reading using the RGBA interface.
	 */
	tif = TIFFOpen(srcfile,"r");

	sz = 128 * 128 * sizeof(uint32);
	rgba_buffer = (uint32 *) malloc(sz);

	if (!TIFFReadRGBATile( tif, 1*128, 2*128, rgba_buffer )) {
		fprintf( stderr, "TIFFReadRGBATile() returned failure code.\n" );
		return 1;
	}

	/*
	 * Currently TIFFReadRGBATile() just uses JPEGCOLORMODE_RGB so this
	 * trivally matches the last results.  Eventually we should actually
	 * accomplish it from the YCbCr subsampled buffer ourselves in which
	 * case the results may be subtly different but similar.
	 */
	pixel_status |= check_rgba_pixel( 0, 15, 18, 0, 0, 18, 41, 255, 255,
					  rgba_buffer );
	pixel_status |= check_rgba_pixel( 64, 0, 0, 0, 0, 0, 2, 255, 255,
					  rgba_buffer );
	pixel_status |= check_rgba_pixel( 512, 5, 6, 34, 36, 182, 196, 255, 255,
					  rgba_buffer );

	free( rgba_buffer );
	TIFFClose(tif);

	if (pixel_status) {
		exit(1);
	}

	exit( 0 );
}
static int
cvt_by_tile( TIFF *in, TIFF *out )

{
    uint32* raster;			/* retrieve RGBA image */
    uint32  width, height;		/* image width & height */
    uint32  tile_width, tile_height;
    uint32  row, col;
    uint32  *wrk_line;
    tsize_t raster_size;
    int	    ok = 1;

    TIFFGetField(in, TIFFTAG_IMAGEWIDTH, &width);
    TIFFGetField(in, TIFFTAG_IMAGELENGTH, &height);

    if( !TIFFGetField(in, TIFFTAG_TILEWIDTH, &tile_width)
        || !TIFFGetField(in, TIFFTAG_TILELENGTH, &tile_height) ) {
        TIFFError(TIFFFileName(in), "Source image not tiled");
        return (0);
    }
    
    TIFFSetField(out, TIFFTAG_TILEWIDTH, tile_width );
    TIFFSetField(out, TIFFTAG_TILELENGTH, tile_height );

    /*
     * Allocate tile buffer
     */
    raster_size = multiply(multiply(tile_width, tile_height), sizeof (uint32));
    if (!raster_size) {
	TIFFError(TIFFFileName(in),
		  "Can't allocate buffer for raster of size %lux%lu",
		  (unsigned long) tile_width, (unsigned long) tile_height);
	return (0);
    }
    raster = (uint32*)_TIFFmalloc(raster_size);
    if (raster == 0) {
        TIFFError(TIFFFileName(in), "No space for raster buffer");
        return (0);
    }

    /*
     * Allocate a scanline buffer for swapping during the vertical
     * mirroring pass.  (Request can't overflow given prior checks.)
     */
    wrk_line = (uint32*)_TIFFmalloc(tile_width * sizeof (uint32));
    if (!wrk_line) {
        TIFFError(TIFFFileName(in), "No space for raster scanline buffer");
        ok = 0;
    }
    
    /*
     * Loop over the tiles.
     */
    for( row = 0; ok && row < height; row += tile_height )
    {
        for( col = 0; ok && col < width; col += tile_width )
        {
            uint32 i_row;

            /* Read the tile into an RGBA array */
            if (!TIFFReadRGBATile(in, col, row, raster)) {
                ok = 0;
                break;
            }


	    /*
	     * XXX: raster array has 4-byte unsigned integer type, that is why
	     * we should rearrange it here.
	     */
#if HOST_BIGENDIAN
	    TIFFSwabArrayOfLong(raster, tile_width * tile_height);
#endif

            /*
             * For some reason the TIFFReadRGBATile() function chooses the
             * lower left corner as the origin.  Vertically mirror scanlines.
             */
            for( i_row = 0; i_row < tile_height / 2; i_row++ )
            {
                uint32	*top_line, *bottom_line;

                top_line = raster + tile_width * i_row;
                bottom_line = raster + tile_width * (tile_height-i_row-1);

                _TIFFmemcpy(wrk_line, top_line, 4*tile_width);
                _TIFFmemcpy(top_line, bottom_line, 4*tile_width);
                _TIFFmemcpy(bottom_line, wrk_line, 4*tile_width);
            }

            /*
             * Write out the result in a tile.
             */

            if( TIFFWriteEncodedTile( out,
                                      TIFFComputeTile( out, col, row, 0, 0),
                                      raster,
                                      4 * tile_width * tile_height ) == -1 )
            {
                ok = 0;
                break;
            }
        }
    }

    _TIFFfree( raster );
    _TIFFfree( wrk_line );

    return ok;
}
Example #9
0
void TifReader::readLine(char *buffer, int x0, int x1, int shrink)
{
	if (this->m_info.m_bitsPerSample == 16 && this->m_info.m_samplePerPixel >= 3) {
		std::vector<short> app(4 * (m_info.m_lx));
		readLine(&app[0], x0, x1, shrink);

		TPixel64 *pixin = (TPixel64 *)&app[0];

		TPixel32 *pixout = (TPixel32 *)buffer;
		for (int j = 0; j < x0; j++) {
			pixout++;
			pixin++;
		}

		for (int i = 0; i < (x1 - x0) + 1; i++)
			*pixout++ = PixelConverter<TPixel32>::from(*pixin++);

		return;
	}

	assert(shrink > 0);

	const int pixelSize = 4;
	int stripRowSize = m_rowLength * pixelSize;

	if (m_row < m_info.m_y0 || m_row > m_info.m_y1) {
		memset(buffer, 0, (x1 - x0 + 1) * pixelSize);
		m_row++;
		return;
	}

	int stripIndex = m_row / m_rowsPerStrip;
	if (m_stripIndex != stripIndex) {
		m_stripIndex = stripIndex;

		if (TIFFIsTiled(m_tiff)) {
			uint32 tileWidth = 0, tileHeight = 0;
			TIFFGetField(m_tiff, TIFFTAG_TILEWIDTH, &tileWidth);
			TIFFGetField(m_tiff, TIFFTAG_TILELENGTH, &tileHeight);
			assert(tileWidth > 0 && tileHeight > 0);

			int tileSize = tileWidth * tileHeight;
			std::unique_ptr<uint32[]> tile(new uint32[tileSize]);

			int x = 0;
			int y = tileHeight * m_stripIndex;

			int lastTy = std::min((int)tileHeight, m_info.m_ly - y);

			while (x < m_info.m_lx) {
				int ret = TIFFReadRGBATile(m_tiff, x, y, tile.get());
				assert(ret);

				int tileRowSize = std::min((int)tileWidth, (int)(m_info.m_lx - x)) * pixelSize;

				for (int ty = 0; ty < lastTy; ++ty) {
					memcpy(
						m_stripBuffer + (ty * m_rowLength + x) * pixelSize,
						(UCHAR *)tile.get() + ty * tileWidth * pixelSize,
						tileRowSize);
				}

				x += tileWidth;
			}
		} else {
			int y = m_rowsPerStrip * m_stripIndex;
			int ok = TIFFReadRGBAStrip(m_tiff, y, (uint32 *)m_stripBuffer);
			assert(ok);
		}
	}

	uint16 orient = ORIENTATION_TOPLEFT;
	TIFFGetField(m_tiff, TIFFTAG_ORIENTATION, &orient);

	int r = m_rowsPerStrip - 1 - (m_row % m_rowsPerStrip);
	switch (orient) // Pretty weak check for top/bottom orientation
	{
	case ORIENTATION_TOPLEFT:
	case ORIENTATION_TOPRIGHT:
	case ORIENTATION_LEFTTOP:
	case ORIENTATION_RIGHTTOP:
		// We have to invert the fixed BOTTOM-UP returned by TIFF functions - since this function is
		// supposed to ignore orientation issues (which are managed outside).

		// The last tiles row will actually start at the END OF THE IMAGE (not necessarily at
		// m_rowsPerStrip multiples). So, we must adjust for that.

		r = std::min(m_rowsPerStrip, m_info.m_ly - m_rowsPerStrip * m_stripIndex) - 1 -
			(m_row % m_rowsPerStrip);
		break;

	case ORIENTATION_BOTRIGHT:
	case ORIENTATION_BOTLEFT:
	case ORIENTATION_RIGHTBOT:
	case ORIENTATION_LEFTBOT:
		r = m_row % m_rowsPerStrip;
		break;
	}

	TPixel32 *pix = (TPixel32 *)buffer;
	uint32 *v = (uint32 *)(m_stripBuffer + r * stripRowSize);

	pix += x0;
	v += x0;

	int width = (x1 < x0) ? (m_info.m_lx - 1) / shrink + 1 : (x1 - x0) / shrink + 1;

	for (int i = 0; i < width; i++) {
		uint32 c = *v;
		pix->r = (UCHAR)TIFFGetR(c);
		pix->g = (UCHAR)TIFFGetG(c);
		pix->b = (UCHAR)TIFFGetB(c);
		pix->m = (UCHAR)TIFFGetA(c);

		v += shrink;
		pix += shrink;
	}

	m_row++;
}
bool  TiffDecoder::readData( Mat& img )
{
    bool result = false;
    bool color = img.channels() > 1;
    uchar* data = img.data;
    int step = img.step;

    if( m_tif && m_width && m_height )
    {
        TIFF* tif = (TIFF*)m_tif;
        int tile_width0 = m_width, tile_height0 = 0;
        int x, y, i;
        int is_tiled = TIFFIsTiled(tif);

        if( (!is_tiled &&
            TIFFGetField( tif, TIFFTAG_ROWSPERSTRIP, &tile_height0 )) ||
            (is_tiled &&
            TIFFGetField( tif, TIFFTAG_TILEWIDTH, &tile_width0 ) &&
            TIFFGetField( tif, TIFFTAG_TILELENGTH, &tile_height0 )))
        {
            if( tile_width0 <= 0 )
                tile_width0 = m_width;

            if( tile_height0 <= 0 )
                tile_height0 = m_height;

            AutoBuffer<uchar> _buffer(tile_height0*tile_width0*4);
            uchar* buffer = _buffer;

            for( y = 0; y < m_height; y += tile_height0, data += step*tile_height0 )
            {
                int tile_height = tile_height0;

                if( y + tile_height > m_height )
                    tile_height = m_height - y;

                for( x = 0; x < m_width; x += tile_width0 )
                {
                    int tile_width = tile_width0, ok;

                    if( x + tile_width > m_width )
                        tile_width = m_width - x;

                    if( !is_tiled )
                        ok = TIFFReadRGBAStrip( tif, y, (uint32*)buffer );
                    else
                        ok = TIFFReadRGBATile( tif, x, y, (uint32*)buffer );

                    if( !ok )
                    {
                        close();
                        return false;
                    }

                    for( i = 0; i < tile_height; i++ )
                        if( color )
                            icvCvt_BGRA2BGR_8u_C4C3R( buffer + i*tile_width*4, 0,
                                          data + x*3 + step*(tile_height - i - 1), 0,
                                          cvSize(tile_width,1), 2 );
                        else
                            icvCvt_BGRA2Gray_8u_C4C1R( buffer + i*tile_width*4, 0,
                                           data + x + step*(tile_height - i - 1), 0,
                                           cvSize(tile_width,1), 2 );
                }
            }

            result = true;
        }
    }

    close();
    return result;
}