Blame contrib/pds/tif_imageiter.c

Packit 7838c8
/* $Header: /cvs/maptools/cvsroot/libtiff/contrib/pds/tif_imageiter.c,v 1.4 2010-06-08 18:55:15 bfriesen Exp $ */
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Copyright (c) 1991-1996 Sam Leffler
Packit 7838c8
 * Copyright (c) 1991-1996 Silicon Graphics, Inc.
Packit 7838c8
 *
Packit 7838c8
 * Permission to use, copy, modify, distribute, and sell this software and 
Packit 7838c8
 * its documentation for any purpose is hereby granted without fee, provided
Packit 7838c8
 * that (i) the above copyright notices and this permission notice appear in
Packit 7838c8
 * all copies of the software and related documentation, and (ii) the names of
Packit 7838c8
 * Sam Leffler and Silicon Graphics may not be used in any advertising or
Packit 7838c8
 * publicity relating to the software without the specific, prior written
Packit 7838c8
 * permission of Sam Leffler and Silicon Graphics.
Packit 7838c8
 * 
Packit 7838c8
 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
Packit 7838c8
 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
Packit 7838c8
 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
Packit 7838c8
 * 
Packit 7838c8
 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
Packit 7838c8
 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
Packit 7838c8
 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
Packit 7838c8
 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
Packit 7838c8
 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
Packit 7838c8
 * OF THIS SOFTWARE.
Packit 7838c8
 */
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * TIFF Library
Packit 7838c8
 *
Packit 7838c8
 * Written by Conrad J. Poelman, PL/WSAT, Kirtland AFB, NM on 26 Mar 96.
Packit 7838c8
 *
Packit 7838c8
 * This file contains code to allow a calling program to "iterate" over each
Packit 7838c8
 * pixels in an image as it is read from the file. The iterator takes care of
Packit 7838c8
 * reading strips versus (possibly clipped) tiles, decoding the information
Packit 7838c8
 * according to the decoding method, and so on, so that calling program can
Packit 7838c8
 * ignore those details. The calling program does, however, need to be
Packit 7838c8
 * conscious of the type of the pixel data that it is receiving.
Packit 7838c8
 *
Packit 7838c8
 * For reasons of efficiency, the callback function actually gets called for 
Packit 7838c8
 * "blocks" of pixels rather than for individual pixels. The format of the
Packit 7838c8
 * callback arguments is given below.
Packit 7838c8
 *
Packit 7838c8
 * This code was taken from TIFFReadRGBAImage() in tif_getimage.c of the original
Packit 7838c8
 * TIFF distribution, and simplified and generalized to provide this general
Packit 7838c8
 * iteration capability. Those routines could certainly be re-implemented in terms
Packit 7838c8
 * of a TIFFImageIter if desired.
Packit 7838c8
 *
Packit 7838c8
 */
Packit 7838c8
#include "tiffiop.h"
Packit 7838c8
#include "tif_imageiter.h"
Packit 7838c8
#include <assert.h>
Packit 7838c8
#include <stdio.h>
Packit 7838c8
Packit 7838c8
static	int gtTileContig(TIFFImageIter*, void *udata, uint32, uint32);
Packit 7838c8
static	int gtTileSeparate(TIFFImageIter*, void *udata, uint32, uint32);
Packit 7838c8
static	int gtStripContig(TIFFImageIter*, void *udata, uint32, uint32);
Packit 7838c8
static	int gtStripSeparate(TIFFImageIter*, void *udata, uint32, uint32);
Packit 7838c8
Packit 7838c8
static	const char photoTag[] = "PhotometricInterpretation";
Packit 7838c8
Packit 7838c8
static int
Packit 7838c8
isCCITTCompression(TIFF* tif)
Packit 7838c8
{
Packit 7838c8
    uint16 compress;
Packit 7838c8
    TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
Packit 7838c8
    return (compress == COMPRESSION_CCITTFAX3 ||
Packit 7838c8
	    compress == COMPRESSION_CCITTFAX4 ||
Packit 7838c8
	    compress == COMPRESSION_CCITTRLE ||
Packit 7838c8
	    compress == COMPRESSION_CCITTRLEW);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
int
Packit 7838c8
TIFFImageIterBegin(TIFFImageIter* img, TIFF* tif, int stop, char emsg[1024])
Packit 7838c8
{
Packit 7838c8
    uint16* sampleinfo;
Packit 7838c8
    uint16 extrasamples;
Packit 7838c8
    uint16 planarconfig;
Packit 7838c8
    int colorchannels;
Packit 7838c8
Packit 7838c8
    img->tif = tif;
Packit 7838c8
    img->stoponerr = stop;
Packit 7838c8
    TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
Packit 7838c8
    img->alpha = 0;
Packit 7838c8
    TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
Packit 7838c8
    TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
Packit 7838c8
	&extrasamples, &sampleinfo);
Packit 7838c8
    if (extrasamples == 1)
Packit 7838c8
	switch (sampleinfo[0]) {
Packit 7838c8
	case EXTRASAMPLE_ASSOCALPHA:	/* data is pre-multiplied */
Packit 7838c8
	case EXTRASAMPLE_UNASSALPHA:	/* data is not pre-multiplied */
Packit 7838c8
	    img->alpha = sampleinfo[0];
Packit 7838c8
	    break;
Packit 7838c8
	}
Packit 7838c8
    colorchannels = img->samplesperpixel - extrasamples;
Packit 7838c8
    TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
Packit 7838c8
    if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
Packit 7838c8
	switch (colorchannels) {
Packit 7838c8
	case 1:
Packit 7838c8
	    if (isCCITTCompression(tif))
Packit 7838c8
		img->photometric = PHOTOMETRIC_MINISWHITE;
Packit 7838c8
	    else
Packit 7838c8
		img->photometric = PHOTOMETRIC_MINISBLACK;
Packit 7838c8
	    break;
Packit 7838c8
	case 3:
Packit 7838c8
	    img->photometric = PHOTOMETRIC_RGB;
Packit 7838c8
	    break;
Packit 7838c8
	default:
Packit 7838c8
	    sprintf(emsg, "Missing needed %s tag", photoTag);
Packit 7838c8
	    return (0);
Packit 7838c8
	}
Packit 7838c8
    }
Packit 7838c8
    switch (img->photometric) {
Packit 7838c8
    case PHOTOMETRIC_PALETTE:
Packit 7838c8
	if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
Packit 7838c8
	    &img->redcmap, &img->greencmap, &img->bluecmap)) {
Packit 7838c8
		TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Missing required \"Colormap\" tag");
Packit 7838c8
	    return (0);
Packit 7838c8
	}
Packit 7838c8
	/* fall thru... */
Packit 7838c8
    case PHOTOMETRIC_MINISWHITE:
Packit 7838c8
    case PHOTOMETRIC_MINISBLACK:
Packit 7838c8
/* This should work now so skip the check - BSR
Packit 7838c8
	if (planarconfig == PLANARCONFIG_CONTIG && img->samplesperpixel != 1) {
Packit 7838c8
	    sprintf(emsg,
Packit 7838c8
		"Sorry, can not handle contiguous data with %s=%d, and %s=%d",
Packit 7838c8
		photoTag, img->photometric,
Packit 7838c8
		"Samples/pixel", img->samplesperpixel);
Packit 7838c8
	    return (0);
Packit 7838c8
	}
Packit 7838c8
 */
Packit 7838c8
	break;
Packit 7838c8
    case PHOTOMETRIC_YCBCR:
Packit 7838c8
	if (planarconfig != PLANARCONFIG_CONTIG) {
Packit 7838c8
	    sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d",
Packit 7838c8
		"Planarconfiguration", planarconfig);
Packit 7838c8
	    return (0);
Packit 7838c8
	}
Packit 7838c8
	/* It would probably be nice to have a reality check here. */
Packit 7838c8
	{ uint16 compress;
Packit 7838c8
	  TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
Packit 7838c8
	  if (compress == COMPRESSION_JPEG && planarconfig == PLANARCONFIG_CONTIG) {
Packit 7838c8
	    /* can rely on libjpeg to convert to RGB */
Packit 7838c8
	    /* XXX should restore current state on exit */
Packit 7838c8
	    TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
Packit 7838c8
	    img->photometric = PHOTOMETRIC_RGB;
Packit 7838c8
	  }
Packit 7838c8
	}
Packit 7838c8
	break;
Packit 7838c8
    case PHOTOMETRIC_RGB: 
Packit 7838c8
	if (colorchannels < 3) {
Packit 7838c8
	    sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
Packit 7838c8
		"Color channels", colorchannels);
Packit 7838c8
	    return (0);
Packit 7838c8
	}
Packit 7838c8
	break;
Packit 7838c8
    case PHOTOMETRIC_SEPARATED: {
Packit 7838c8
	uint16 inkset;
Packit 7838c8
	TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
Packit 7838c8
	if (inkset != INKSET_CMYK) {
Packit 7838c8
	    sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
Packit 7838c8
		"InkSet", inkset);
Packit 7838c8
	    return (0);
Packit 7838c8
	}
Packit 7838c8
	if (img->samplesperpixel != 4) {
Packit 7838c8
	    sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
Packit 7838c8
		"Samples/pixel", img->samplesperpixel);
Packit 7838c8
	    return (0);
Packit 7838c8
	}
Packit 7838c8
	break;
Packit 7838c8
    }
Packit 7838c8
    default:
Packit 7838c8
	sprintf(emsg, "Sorry, can not handle image with %s=%d",
Packit 7838c8
	    photoTag, img->photometric);
Packit 7838c8
	return (0);
Packit 7838c8
    }
Packit 7838c8
    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
Packit 7838c8
    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
Packit 7838c8
Packit 7838c8
    TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
Packit 7838c8
    switch (img->orientation) {
Packit 7838c8
    case ORIENTATION_BOTRIGHT:
Packit 7838c8
    case ORIENTATION_RIGHTBOT:	/* XXX */
Packit 7838c8
    case ORIENTATION_LEFTBOT:	/* XXX */
Packit 7838c8
	TIFFWarning(TIFFFileName(tif), "using bottom-left orientation");
Packit 7838c8
	img->orientation = ORIENTATION_BOTLEFT;
Packit 7838c8
	/* fall thru... */
Packit 7838c8
    case ORIENTATION_BOTLEFT:
Packit 7838c8
	break;
Packit 7838c8
    case ORIENTATION_TOPRIGHT:
Packit 7838c8
    case ORIENTATION_RIGHTTOP:	/* XXX */
Packit 7838c8
    case ORIENTATION_LEFTTOP:	/* XXX */
Packit 7838c8
    default:
Packit 7838c8
	TIFFWarning(TIFFFileName(tif), "using top-left orientation");
Packit 7838c8
	img->orientation = ORIENTATION_TOPLEFT;
Packit 7838c8
	/* fall thru... */
Packit 7838c8
    case ORIENTATION_TOPLEFT:
Packit 7838c8
	break;
Packit 7838c8
    }
Packit 7838c8
Packit 7838c8
    img->isContig =
Packit 7838c8
	!(planarconfig == PLANARCONFIG_SEPARATE && colorchannels > 1);
Packit 7838c8
    if (img->isContig) {
Packit 7838c8
	img->get = TIFFIsTiled(tif) ? gtTileContig : gtStripContig;
Packit 7838c8
    } else {
Packit 7838c8
	img->get = TIFFIsTiled(tif) ? gtTileSeparate : gtStripSeparate;
Packit 7838c8
    }
Packit 7838c8
    return (1);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
int
Packit 7838c8
TIFFImageIterGet(TIFFImageIter* img, void *udata, uint32 w, uint32 h)
Packit 7838c8
{
Packit 7838c8
    if (img->get == NULL) {
Packit 7838c8
	TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No \"get\" routine setup");
Packit 7838c8
	return (0);
Packit 7838c8
    }
Packit 7838c8
    if (img->callback.any == NULL) {
Packit 7838c8
	TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
Packit 7838c8
		"No \"put\" routine setupl; probably can not handle image format");
Packit 7838c8
	return (0);
Packit 7838c8
    }
Packit 7838c8
    return (*img->get)(img, udata, w, h);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
TIFFImageIterEnd(TIFFImageIter* img)
Packit 7838c8
{
Packit 7838c8
    /* Nothing to free... ? */
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Read the specified image into an ABGR-format raster.
Packit 7838c8
 */
Packit 7838c8
int
Packit 7838c8
TIFFReadImageIter(TIFF* tif,
Packit 7838c8
    uint32 rwidth, uint32 rheight, uint8* raster, int stop)
Packit 7838c8
{
Packit 7838c8
    char emsg[1024];
Packit 7838c8
    TIFFImageIter img;
Packit 7838c8
    int ok;
Packit 7838c8
Packit 7838c8
    if (TIFFImageIterBegin(&img, tif, stop, emsg)) {
Packit 7838c8
	/* XXX verify rwidth and rheight against width and height */
Packit 7838c8
	ok = TIFFImageIterGet(&img, raster, rwidth, img.height);
Packit 7838c8
	TIFFImageIterEnd(&img;;
Packit 7838c8
    } else {
Packit 7838c8
	TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), emsg);
Packit 7838c8
	ok = 0;
Packit 7838c8
    }
Packit 7838c8
    return (ok);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Get an tile-organized image that has
Packit 7838c8
 *	PlanarConfiguration contiguous if SamplesPerPixel > 1
Packit 7838c8
 * or
Packit 7838c8
 *	SamplesPerPixel == 1
Packit 7838c8
 */	
Packit 7838c8
static int
Packit 7838c8
gtTileContig(TIFFImageIter* img, void *udata, uint32 w, uint32 h)
Packit 7838c8
{
Packit 7838c8
    TIFF* tif = img->tif;
Packit 7838c8
    ImageIterTileContigRoutine callback = img->callback.contig;
Packit 7838c8
    uint16 orientation;
Packit 7838c8
    uint32 col, row;
Packit 7838c8
    uint32 tw, th;
Packit 7838c8
    u_char* buf;
Packit 7838c8
    int32 fromskew;
Packit 7838c8
    uint32 nrow;
Packit 7838c8
Packit 7838c8
    buf = (u_char*) _TIFFmalloc(TIFFTileSize(tif));
Packit 7838c8
    if (buf == 0) {
Packit 7838c8
	TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
Packit 7838c8
	return (0);
Packit 7838c8
    }
Packit 7838c8
    TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
Packit 7838c8
    TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
Packit 7838c8
    orientation = img->orientation;
Packit 7838c8
    for (row = 0; row < h; row += th) {
Packit 7838c8
	nrow = (row + th > h ? h - row : th);
Packit 7838c8
	for (col = 0; col < w; col += tw) {
Packit 7838c8
	    if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0 && img->stoponerr)
Packit 7838c8
		break;
Packit 7838c8
	    if (col + tw > w) {
Packit 7838c8
		/*
Packit 7838c8
		 * Tile is clipped horizontally.  Calculate
Packit 7838c8
		 * visible portion and skewing factors.
Packit 7838c8
		 */
Packit 7838c8
		uint32 npix = w - col;
Packit 7838c8
		fromskew = tw - npix;
Packit 7838c8
		(*callback)(img, udata, col, row, npix, nrow, fromskew, buf);
Packit 7838c8
	    } else {
Packit 7838c8
		(*callback)(img, udata, col, row, tw, nrow, 0, buf);
Packit 7838c8
	    }
Packit 7838c8
	}
Packit 7838c8
    }
Packit 7838c8
    _TIFFfree(buf);
Packit 7838c8
    return (1);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Get an tile-organized image that has
Packit 7838c8
 *	 SamplesPerPixel > 1
Packit 7838c8
 *	 PlanarConfiguration separated
Packit 7838c8
 * We assume that all such images are RGB.
Packit 7838c8
 */	
Packit 7838c8
static int
Packit 7838c8
gtTileSeparate(TIFFImageIter* img, void *udata, uint32 w, uint32 h)
Packit 7838c8
{
Packit 7838c8
    TIFF* tif = img->tif;
Packit 7838c8
    ImageIterTileSeparateRoutine callback = img->callback.separate;
Packit 7838c8
    uint16 orientation;
Packit 7838c8
    uint32 col, row;
Packit 7838c8
    uint32 tw, th;
Packit 7838c8
    u_char* buf;
Packit 7838c8
    u_char* r;
Packit 7838c8
    u_char* g;
Packit 7838c8
    u_char* b;
Packit 7838c8
    u_char* a;
Packit 7838c8
    tsize_t tilesize;
Packit 7838c8
    int32 fromskew;
Packit 7838c8
    int alpha = img->alpha;
Packit 7838c8
    uint32 nrow;
Packit 7838c8
Packit 7838c8
    tilesize = TIFFTileSize(tif);
Packit 7838c8
    buf = (u_char*) _TIFFmalloc(4*tilesize);
Packit 7838c8
    if (buf == 0) {
Packit 7838c8
	TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
Packit 7838c8
	return (0);
Packit 7838c8
    }
Packit 7838c8
    r = buf;
Packit 7838c8
    g = r + tilesize;
Packit 7838c8
    b = g + tilesize;
Packit 7838c8
    a = b + tilesize;
Packit 7838c8
    if (!alpha)
Packit 7838c8
	memset(a, 0xff, tilesize);
Packit 7838c8
    TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
Packit 7838c8
    TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
Packit 7838c8
    orientation = img->orientation;
Packit 7838c8
    for (row = 0; row < h; row += th) {
Packit 7838c8
	nrow = (row + th > h ? h - row : th);
Packit 7838c8
	for (col = 0; col < w; col += tw) {
Packit 7838c8
	    if (TIFFReadTile(tif, r, col, row,0,0) < 0 && img->stoponerr)
Packit 7838c8
		break;
Packit 7838c8
	    if (TIFFReadTile(tif, g, col, row,0,1) < 0 && img->stoponerr)
Packit 7838c8
		break;
Packit 7838c8
	    if (TIFFReadTile(tif, b, col, row,0,2) < 0 && img->stoponerr)
Packit 7838c8
		break;
Packit 7838c8
	    if (alpha && TIFFReadTile(tif,a,col,row,0,3) < 0 && img->stoponerr)
Packit 7838c8
		break;
Packit 7838c8
	    if (col + tw > w) {
Packit 7838c8
		/*
Packit 7838c8
		 * Tile is clipped horizontally.  Calculate
Packit 7838c8
		 * visible portion and skewing factors.
Packit 7838c8
		 */
Packit 7838c8
		uint32 npix = w - col;
Packit 7838c8
		fromskew = tw - npix;
Packit 7838c8
		(*callback)(img, udata, col, row, npix, nrow, fromskew, r, g, b, a);
Packit 7838c8
	    } else {
Packit 7838c8
		(*callback)(img, udata, col, row, tw, nrow, 0, r, g, b, a);
Packit 7838c8
	    }
Packit 7838c8
	}
Packit 7838c8
    }
Packit 7838c8
    _TIFFfree(buf);
Packit 7838c8
    return (1);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Get a strip-organized image that has
Packit 7838c8
 *	PlanarConfiguration contiguous if SamplesPerPixel > 1
Packit 7838c8
 * or
Packit 7838c8
 *	SamplesPerPixel == 1
Packit 7838c8
 */	
Packit 7838c8
static int
Packit 7838c8
gtStripContig(TIFFImageIter* img, void *udata, uint32 w, uint32 h)
Packit 7838c8
{
Packit 7838c8
    TIFF* tif = img->tif;
Packit 7838c8
    ImageIterTileContigRoutine callback = img->callback.contig;
Packit 7838c8
    uint16 orientation;
Packit 7838c8
    uint32 row, nrow;
Packit 7838c8
    u_char* buf;
Packit 7838c8
    uint32 rowsperstrip;
Packit 7838c8
    uint32 imagewidth = img->width;
Packit 7838c8
    tsize_t scanline;
Packit 7838c8
    int32 fromskew;
Packit 7838c8
Packit 7838c8
    buf = (u_char*) _TIFFmalloc(TIFFStripSize(tif));
Packit 7838c8
    if (buf == 0) {
Packit 7838c8
	TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
Packit 7838c8
	return (0);
Packit 7838c8
    }
Packit 7838c8
    orientation = img->orientation;
Packit 7838c8
    TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
Packit 7838c8
    scanline = TIFFScanlineSize(tif);
Packit 7838c8
    fromskew = (w < imagewidth ? imagewidth - w : 0);
Packit 7838c8
    for (row = 0; row < h; row += rowsperstrip) {
Packit 7838c8
	nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
Packit 7838c8
	if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
Packit 7838c8
	    buf, nrow*scanline) < 0 && img->stoponerr)
Packit 7838c8
		break;
Packit 7838c8
	(*callback)(img, udata, 0, row, w, nrow, fromskew, buf);
Packit 7838c8
    }
Packit 7838c8
    _TIFFfree(buf);
Packit 7838c8
    return (1);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
/*
Packit 7838c8
 * Get a strip-organized image with
Packit 7838c8
 *	 SamplesPerPixel > 1
Packit 7838c8
 *	 PlanarConfiguration separated
Packit 7838c8
 * We assume that all such images are RGB.
Packit 7838c8
 */
Packit 7838c8
static int
Packit 7838c8
gtStripSeparate(TIFFImageIter* img, void *udata, uint32 w, uint32 h)
Packit 7838c8
{
Packit 7838c8
    TIFF* tif = img->tif;
Packit 7838c8
    ImageIterTileSeparateRoutine callback = img->callback.separate;
Packit 7838c8
    uint16 orientation;
Packit 7838c8
    u_char *buf;
Packit 7838c8
    u_char *r, *g, *b, *a;
Packit 7838c8
    uint32 row, nrow;
Packit 7838c8
    tsize_t scanline;
Packit 7838c8
    uint32 rowsperstrip;
Packit 7838c8
    uint32 imagewidth = img->width;
Packit 7838c8
    tsize_t stripsize;
Packit 7838c8
    int32 fromskew;
Packit 7838c8
    int alpha = img->alpha;
Packit 7838c8
Packit 7838c8
    stripsize = TIFFStripSize(tif);
Packit 7838c8
    r = buf = (u_char *)_TIFFmalloc(4*stripsize);
Packit 7838c8
    if (buf == 0) {
Packit 7838c8
	TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
Packit 7838c8
	return (0);
Packit 7838c8
    }
Packit 7838c8
    g = r + stripsize;
Packit 7838c8
    b = g + stripsize;
Packit 7838c8
    a = b + stripsize;
Packit 7838c8
    if (!alpha)
Packit 7838c8
	memset(a, 0xff, stripsize);
Packit 7838c8
    orientation = img->orientation;
Packit 7838c8
    TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
Packit 7838c8
    scanline = TIFFScanlineSize(tif);
Packit 7838c8
    fromskew = (w < imagewidth ? imagewidth - w : 0);
Packit 7838c8
    for (row = 0; row < h; row += rowsperstrip) {
Packit 7838c8
	nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
Packit 7838c8
	if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
Packit 7838c8
	    r, nrow*scanline) < 0 && img->stoponerr)
Packit 7838c8
	    break;
Packit 7838c8
	if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 1),
Packit 7838c8
	    g, nrow*scanline) < 0 && img->stoponerr)
Packit 7838c8
	    break;
Packit 7838c8
	if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 2),
Packit 7838c8
	    b, nrow*scanline) < 0 && img->stoponerr)
Packit 7838c8
	    break;
Packit 7838c8
	if (alpha &&
Packit 7838c8
	    (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 3),
Packit 7838c8
	    a, nrow*scanline) < 0 && img->stoponerr))
Packit 7838c8
	    break;
Packit 7838c8
	(*callback)(img, udata, 0, row, w, nrow, fromskew, r, g, b, a);
Packit 7838c8
    }
Packit 7838c8
    _TIFFfree(buf);
Packit 7838c8
    return (1);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
DECLAREContigCallbackFunc(TestContigCallback)
Packit 7838c8
{
Packit 7838c8
    printf("Contig Callback called with x = %d, y = %d, w = %d, h = %d, fromskew = %d\n",
Packit 7838c8
	   x, y, w, h, fromskew);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
Packit 7838c8
DECLARESepCallbackFunc(TestSepCallback)
Packit 7838c8
{
Packit 7838c8
    printf("Sep Callback called with x = %d, y = %d, w = %d, h = %d, fromskew = %d\n",
Packit 7838c8
	   x, y, w, h, fromskew);
Packit 7838c8
}
Packit 7838c8
Packit 7838c8
Packit 7838c8
#ifdef MAIN
Packit 7838c8
main(int argc, char **argv)
Packit 7838c8
{
Packit 7838c8
    char emsg[1024];
Packit 7838c8
    TIFFImageIter img;
Packit 7838c8
    int ok;
Packit 7838c8
    int stop = 1;
Packit 7838c8
Packit 7838c8
    TIFF *tif;
Packit 7838c8
    unsigned long nx, ny;
Packit 7838c8
    unsigned short BitsPerSample, SamplesPerPixel;
Packit 7838c8
    int isColorMapped, isPliFile;
Packit 7838c8
    unsigned char *ColorMap;
Packit 7838c8
    unsigned char *data;
Packit 7838c8
Packit 7838c8
    if (argc < 2) {
Packit 7838c8
	fprintf(stderr,"usage: %s tiff_file\n",argv[0]);
Packit 7838c8
	exit(1);
Packit 7838c8
    }
Packit 7838c8
    tif = (TIFF *)PLIGetImage(argv[1], (void *) &data, &ColorMap, 
Packit 7838c8
			      &nx, &ny, &BitsPerSample, &SamplesPerPixel, 
Packit 7838c8
			      &isColorMapped, &isPliFile);
Packit 7838c8
    if (tif != NULL) {
Packit 7838c8
Packit 7838c8
	if (TIFFImageIterBegin(&img, tif, stop, emsg)) {
Packit 7838c8
	    /* Here need to set data and callback function! */
Packit 7838c8
	    if (img.isContig) {
Packit 7838c8
		img.callback = TestContigCallback;
Packit 7838c8
	    } else {
Packit 7838c8
		img.callback = TestSepCallback;
Packit 7838c8
	    }
Packit 7838c8
	    ok = TIFFImageIterGet(&img, NULL, img.width, img.height);
Packit 7838c8
	    TIFFImageIterEnd(&img;;
Packit 7838c8
	} else {
Packit 7838c8
	    TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), emsg);
Packit 7838c8
	}
Packit 7838c8
    }
Packit 7838c8
    
Packit 7838c8
}
Packit 7838c8
#endif
Packit 7838c8
/*
Packit 7838c8
 * Local Variables:
Packit 7838c8
 * mode: c
Packit 7838c8
 * c-basic-offset: 8
Packit 7838c8
 * fill-column: 78
Packit 7838c8
 * End:
Packit 7838c8
 */