cdesktopenv/cde/lib/DtHelp/il/ilscale.c

965 lines
32 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
/* $XConsortium: ilscale.c /main/6 1996/09/24 17:13:24 drk $ */
/**---------------------------------------------------------------------
***
*** (c)Copyright 1991 Hewlett-Packard Co.
***
*** RESTRICTED RIGHTS LEGEND
*** Use, duplication, or disclosure by the U.S. Government is subject to
*** restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in
*** Technical Data and Computer Software clause in DFARS 252.227-7013.
*** Hewlett-Packard Company
*** 3000 Hanover Street
*** Palo Alto, CA 94304 U.S.A.
*** Rights for non-DOD U.S. Government Departments and Agencies are as set
*** forth in FAR 52.227-19(c)(1,2).
***
***-------------------------------------------------------------------*/
#include "ilint.h"
#include "ilpipelem.h"
#include "ilscaleint.h"
#include "ilerrors.h"
#include "ilconvert.h"
#define LONGSZ 4
#ifdef LSB_BIT_ORDER
# define SPECIAL_MASK_BIT 0x00000001 /* for LSB bit order */
# define SHIFT_MASK(m) ((m) <<= 1)
#else
# define SPECIAL_MASK_BIT 0x80000000 /* for MSB bit order */
# define SHIFT_MASK(m) ((m) >>= 1)
#endif
typedef struct {
long ilScaleAccDown; /* accumulator value used in scale down algorithm */
long ilScaleAccUp; /* accumulator value used in scale up algorithm */
long ilScaleDstheight; /* destination height value saved to avoid strip sizes */
long ilScaleSrcheight; /* src height value saved to avoid strip sizes */
} ilScalePriv, *ilScalePrivptr;
#ifdef LSB_BIT_ORDER
extern void flip_bits(ilPtr start, unsigned n);
#else
# define flip_bits(start,n) /*EMPTY*/
#endif
/* =============================================================================================================================
ilScaleInit - Initialization function for a scale filter performed with the
method of replication/decimation. This gets called when the pipe
is executed for the first time.
============================================================================================================================= */
static ilError ilScaleInit(
ilScalePrivptr pPrivate,
ilImageInfo *pSrcImage,
ilImageInfo *pDstImage
)
{
pPrivate->ilScaleAccDown = pPrivate->ilScaleSrcheight - pPrivate->ilScaleDstheight;
pPrivate->ilScaleAccUp = pPrivate->ilScaleDstheight - pPrivate->ilScaleSrcheight;
return IL_OK;
}
/* =============================================================================================================================
ilswbitdown - Routine to scale down the width of an image by decimation.
Operates on bitonal images.
============================================================================================================================= */
static void ilswbitdown(
CARD32 *psrcline,
CARD32 *pdstline,
unsigned long srcwidth,
unsigned long dstwidth
)
{
int acc, nbits;
CARD32 srcMask;
CARD32 srcLong;
CARD32 dstLong;
ilBool copy;
ilBool Lastbit;
srcMask = SPECIAL_MASK_BIT;
srcLong = *psrcline++;
dstLong = 1;
Lastbit = FALSE;
acc = srcwidth - dstwidth;
copy = (acc == 0) ? TRUE : FALSE;
nbits = dstwidth;
if(copy == TRUE) { /* degenerate case optimized */
while (nbits-- ) {
/* copy bit logic */
dstLong <<= 1;
if (srcMask & srcLong) dstLong++;
if(Lastbit) {
flip_bits((ilPtr)&dstLong, sizeof(dstLong));
*pdstline++ = dstLong;
dstLong = 1;
Lastbit = FALSE;
}
/* See if the last bit in the word is coming */
if( (INT32) dstLong < 0) Lastbit = TRUE;
SHIFT_MASK(srcMask);
if (!srcMask) { /* after 32 bits reset mask and get new srcline */
srcMask = SPECIAL_MASK_BIT;
srcLong = *psrcline++;
}
} /* End While */
}
else { /* scale down algorithm */
while (nbits-- ) {
for(; acc > 0; acc -= dstwidth) { /* skip bits according to scale ratio */
SHIFT_MASK(srcMask);
if (!srcMask) { /* after 32 bits reset mask and get new srcline */
srcMask = SPECIAL_MASK_BIT;
srcLong = *psrcline++;
}
}
acc += (srcwidth - dstwidth);
/* copy bit logic */
dstLong <<= 1;
if (srcMask & srcLong) dstLong++;
if(Lastbit) {
flip_bits((ilPtr)&dstLong, sizeof(dstLong));
*pdstline++ = dstLong;
dstLong = 1;
Lastbit = FALSE;
}
/* See if the last bit in the word is coming */
if( (INT32) dstLong < 0) Lastbit = TRUE;
SHIFT_MASK(srcMask);
if (!srcMask) { /* after 32 bits reset mask and get new srcline */
srcMask = SPECIAL_MASK_BIT;
srcLong = *psrcline++;
}
} /* End While */
}
/* Shift up and write out any last bits */
if (dstLong != 1) { /* has data not copied to pdstline */
while ( (INT32) dstLong > 0) dstLong <<= 1; /* shift up */
dstLong <<= 1;
flip_bits((ilPtr)&dstLong, sizeof(dstLong));
*pdstline++ = dstLong;
}
}
/* =============================================================================================================================
ilswbitup - Routine to scale up the width of an image by replication.
Operates on bitonal images.
============================================================================================================================= */
static void ilswbitup(
CARD32 *psrcline,
CARD32 *pdstline,
unsigned long srcwidth,
unsigned long dstwidth
)
{
int acc, nbits;
CARD32 srcMask;
CARD32 srcLong;
CARD32 dstLong;
ilBool Lastbit;
srcMask = SPECIAL_MASK_BIT;
srcLong = *psrcline++;
dstLong = 1;
Lastbit = FALSE;
acc = dstwidth - srcwidth;
nbits = srcwidth;
while (nbits-- ) {
for(; acc >= 0; acc -= srcwidth) { /* keep copying */
/* copy bit logic */
dstLong <<= 1;
if (srcMask & srcLong) dstLong++;
if(Lastbit) {
flip_bits((ilPtr)&dstLong, sizeof(dstLong));
*pdstline++ = dstLong;
dstLong = 1;
Lastbit = FALSE;
}
/* See if the last bit in the word is coming */
if( (INT32) dstLong < 0) Lastbit = TRUE;
}
acc += dstwidth;
/* increment the mask to the next src bit */
SHIFT_MASK(srcMask);
if (!srcMask) { /* after 32 bits reset mask and get new srcline */
srcMask = SPECIAL_MASK_BIT;
srcLong = *psrcline++;
}
} /* End While */
/* Shift up and write out any last bits */
if (dstLong != 1) { /* has data not copied to pdstline */
while ( (INT32) dstLong > 0) dstLong <<= 1; /* shift up */
dstLong <<= 1;
flip_bits((ilPtr)&dstLong, sizeof(dstLong));
*pdstline++ = dstLong;
}
}
/* =============================================================================================================================
ilsw3bytedown - Routine to scale down the width of an image by decimation.
Operates on 24 bit images.
============================================================================================================================= */
static void ilsw3bytedown(
unsigned char *psrcline,
unsigned char *pdstline,
unsigned long srcwidth,
unsigned long dstwidth
)
{
int acc, n3bytes;
ilBool copy;
acc = srcwidth - dstwidth;
copy = (acc == 0) ? TRUE : FALSE;
n3bytes = dstwidth;
if(copy == TRUE) { /* degenerate case optimized */
while (n3bytes--) {
*pdstline++ = *psrcline++; /* 3 Bytes to copy */
*pdstline++ = *psrcline++;
*pdstline++ = *psrcline++;
}
}
else { /* scale down algorithm */
while (n3bytes--) {
for(; acc > 0; acc -= dstwidth) psrcline += 3;
acc += (srcwidth - dstwidth);
*pdstline++ = *psrcline++; /* 3 Bytes to copy */
*pdstline++ = *psrcline++;
*pdstline++ = *psrcline++;
}
}
}
/* =============================================================================================================================
ilsw3byteup - Routine to scale up the width of an image by replication.
Operates on 24 bit images.
============================================================================================================================= */
static void ilsw3byteup(
unsigned char *psrcline,
unsigned char *pdstline,
unsigned long srcwidth,
unsigned long dstwidth
)
{
int acc, n3bytes;
acc = dstwidth - srcwidth;
n3bytes = srcwidth;
while (n3bytes--) {
for(; acc >= 0; acc -= srcwidth) {
*pdstline++ = *psrcline;
*pdstline++ = *(psrcline + 1);
*pdstline++ = *(psrcline + 2);
}
acc += dstwidth;
psrcline += 3;
}
}
/* =============================================================================================================================
ilswbytedown - Routine to scale down the width of an image by decimation.
Operates on 8 bit images.
============================================================================================================================= */
static void ilswbytedown(
unsigned char *psrcline,
unsigned char *pdstline,
unsigned long srcwidth,
unsigned long dstwidth
)
{
int acc, nbytes;
ilBool copy;
acc = srcwidth - dstwidth;
copy = (acc == 0) ? TRUE : FALSE;
nbytes = dstwidth;
if(copy == TRUE) { /* degenerate case optimized */
while (nbytes-- ) *pdstline++ = *psrcline++;
}
else { /* scale down algorithm */
while (nbytes-- ) {
for(; acc > 0; acc -= dstwidth) psrcline++;
acc += (srcwidth - dstwidth);
*pdstline++ = *psrcline++;
}
}
}
/* =============================================================================================================================
ilswbyteup - Routine to scale up the width of an image by replication.
Operates on 8 bit images.
============================================================================================================================= */
static void ilswbyteup(
unsigned char *psrcline,
unsigned char *pdstline,
unsigned long srcwidth,
unsigned long dstwidth
)
{
int acc, nbytes;
acc = dstwidth - srcwidth;
nbytes = srcwidth;
while (nbytes--) {
for(; acc >= 0; acc -= srcwidth) *pdstline++ = *psrcline;
acc += dstwidth;
psrcline++;
}
}
/* =============================================================================================================================
ilScaleBitonalExecute - Scale processing for images with bit per pixel format .
This function that will get called at least once when the
pipe is executed. This routine loops through the number of
lines, scaling the height and calls the appropriate function
to scale the width.
============================================================================================================================= */
static ilError ilScaleBitonalExecute (
ilExecuteData *pData,
unsigned long dstLine,
unsigned long *pNLines
)
{
CARD32 *psrcline, *pdstline;
unsigned long srcnwords, dstnwords;
long nlines;
unsigned long srcwidth, dstwidth;
ilImagePlaneInfo *pplane;
unsigned long local_noDstLine;
ilScalePrivptr pPriv;
nlines = *pNLines;
if (nlines <= 0) return IL_OK;
pplane = &pData->pSrcImage->plane[0];
srcnwords = (pplane->nBytesPerRow + LONGSZ - 1)/LONGSZ;
psrcline = (CARD32 *) (pplane->pPixels) + pData->srcLine * srcnwords;
pplane = &pData->pDstImage->plane[0];
dstnwords = (pplane->nBytesPerRow + LONGSZ - 1)/LONGSZ;
pdstline = (CARD32 *) (pplane->pPixels) + dstLine * dstnwords;
pPriv = (ilScalePrivptr) pData->pPrivate;
srcwidth = pData->pSrcImage->width;
dstwidth = pData->pDstImage->width;
local_noDstLine = 0;
if (pPriv->ilScaleSrcheight == pPriv->ilScaleDstheight) { /* copy case optimized */
while (nlines-- > 0) {
if(srcwidth >= dstwidth)
ilswbitdown (psrcline, pdstline, srcwidth, dstwidth);
else if (srcwidth < dstwidth)
ilswbitup (psrcline, pdstline, srcwidth, dstwidth);
local_noDstLine++;
psrcline += srcnwords;
pdstline += dstnwords;
}
}
else if (pPriv->ilScaleSrcheight > pPriv->ilScaleDstheight) { /* scale height down */
while (TRUE) {
while (pPriv->ilScaleAccDown > 0) {
if (nlines-- <= 0)
break;
pPriv->ilScaleAccDown -= pPriv->ilScaleDstheight;
psrcline += srcnwords;
}
if (nlines-- <= 0)
break;
pPriv->ilScaleAccDown += (pPriv->ilScaleSrcheight - pPriv->ilScaleDstheight);
if(srcwidth >= dstwidth)
ilswbitdown (psrcline, pdstline, srcwidth, dstwidth);
else if (srcwidth < dstwidth)
ilswbitup (psrcline, pdstline, srcwidth, dstwidth);
local_noDstLine++;
psrcline += srcnwords;
pdstline += dstnwords;
}
}
else if (pPriv->ilScaleSrcheight < pPriv->ilScaleDstheight) { /* scale height up */
while (nlines-- > 0) {
for(; pPriv->ilScaleAccUp >= 0; pPriv->ilScaleAccUp -= pPriv->ilScaleSrcheight) {
if(srcwidth >= dstwidth)
ilswbitdown (psrcline, pdstline, srcwidth, dstwidth);
else if (srcwidth < dstwidth)
ilswbitup (psrcline, pdstline, srcwidth, dstwidth);
local_noDstLine++;
pdstline += dstnwords;
}
pPriv->ilScaleAccUp += pPriv->ilScaleDstheight;
psrcline += srcnwords;
}
}
*pNLines = local_noDstLine;
return IL_OK;
}
/* =============================================================================================================================
ilScale3ByteExecute - Scale processing for images with 24 bits per pixel format .
This function that will get called at least once when the
pipe is executed. This routine loops through the number of
lines, scaling the height and calls the appropriate function
to scale the width.
============================================================================================================================= */
static ilError ilScale3ByteExecute (
ilExecuteData *pData,
unsigned long dstLine,
unsigned long *pNLines
)
{
unsigned char *psrcline, *pdstline;
unsigned long srcnbytes, dstnbytes;
long nlines;
unsigned long srcwidth, dstwidth;
ilImagePlaneInfo *pplane;
unsigned long local_noDstLine;
ilScalePrivptr pPriv;
nlines = *pNLines;
if (nlines <= 0) return IL_OK;
pplane = &pData->pSrcImage->plane[0];
srcnbytes = pplane->nBytesPerRow;
psrcline = (unsigned char *) (pplane->pPixels) + pData->srcLine * srcnbytes;
pplane = &pData->pDstImage->plane[0];
dstnbytes = pplane->nBytesPerRow;
pdstline = (unsigned char *) (pplane->pPixels) + dstLine * dstnbytes;
pPriv = (ilScalePrivptr) pData->pPrivate;
srcwidth = pData->pSrcImage->width;
dstwidth = pData->pDstImage->width;
local_noDstLine = 0;
if (pPriv->ilScaleSrcheight == pPriv->ilScaleDstheight) { /* copy case optimized */
while (nlines-- > 0) {
if(srcwidth >= dstwidth)
ilsw3bytedown (psrcline, pdstline, srcwidth, dstwidth);
else if (srcwidth < dstwidth)
ilsw3byteup (psrcline, pdstline, srcwidth, dstwidth);
local_noDstLine++;
psrcline += srcnbytes;
pdstline += dstnbytes;
}
}
else if (pPriv->ilScaleSrcheight > pPriv->ilScaleDstheight) { /* scale height down */
while (TRUE) {
while (pPriv->ilScaleAccDown > 0) {
if (nlines-- <= 0)
break;
pPriv->ilScaleAccDown -= pPriv->ilScaleDstheight;
psrcline += srcnbytes;
}
if (nlines-- <= 0)
break;
pPriv->ilScaleAccDown += (pPriv->ilScaleSrcheight - pPriv->ilScaleDstheight);
if(srcwidth >= dstwidth)
ilsw3bytedown (psrcline, pdstline, srcwidth, dstwidth);
else if (srcwidth < dstwidth)
ilsw3byteup (psrcline, pdstline, srcwidth, dstwidth);
local_noDstLine++;
psrcline += srcnbytes;
pdstline += dstnbytes;
}
}
else if (pPriv->ilScaleSrcheight < pPriv->ilScaleDstheight) { /* scale height up */
while (nlines-- > 0) {
for(; pPriv->ilScaleAccUp >= 0; pPriv->ilScaleAccUp -= pPriv->ilScaleSrcheight) {
if(srcwidth >= dstwidth)
ilsw3bytedown (psrcline, pdstline, srcwidth, dstwidth);
else if (srcwidth < dstwidth)
ilsw3byteup (psrcline, pdstline, srcwidth, dstwidth);
local_noDstLine++;
pdstline += dstnbytes;
}
pPriv->ilScaleAccUp += pPriv->ilScaleDstheight;
psrcline += srcnbytes;
}
}
*pNLines = local_noDstLine;
return IL_OK;
}
/* =============================================================================================================================
ilScaleByteExecute - Scale processing for images with byte per pixel format .
This function that will get called at least once when the
pipe is executed. This routine loops through the number of
lines, scaling the height and calls the appropriate function
to scale the width.
============================================================================================================================= */
static ilError ilScaleByteExecute (
ilExecuteData *pData,
unsigned long dstLine,
unsigned long *pNLines
)
{
unsigned char *psrcline, *pdstline;
unsigned long srcnbytes, dstnbytes;
long nlines;
unsigned long srcwidth, dstwidth;
ilImagePlaneInfo *pplane;
unsigned long local_noDstLine;
ilScalePrivptr pPriv;
nlines = *pNLines;
if (nlines <= 0) return IL_OK;
pplane = &pData->pSrcImage->plane[0];
srcnbytes = pplane->nBytesPerRow;
psrcline = (unsigned char *) (pplane->pPixels) + pData->srcLine * srcnbytes;
pplane = &pData->pDstImage->plane[0];
dstnbytes = pplane->nBytesPerRow;
pdstline = (unsigned char *) (pplane->pPixels) + dstLine * dstnbytes;
pPriv = (ilScalePrivptr) pData->pPrivate;
srcwidth = pData->pSrcImage->width;
dstwidth = pData->pDstImage->width;
local_noDstLine = 0;
if (pPriv->ilScaleSrcheight == pPriv->ilScaleDstheight) { /* copy case optimized */
while (nlines-- > 0) {
if(srcwidth >= dstwidth)
ilswbytedown (psrcline, pdstline, srcwidth, dstwidth);
else if (srcwidth < dstwidth)
ilswbyteup (psrcline, pdstline, srcwidth, dstwidth);
local_noDstLine++;
psrcline += srcnbytes;
pdstline += dstnbytes;
}
}
else if (pPriv->ilScaleSrcheight > pPriv->ilScaleDstheight ) { /* scale height down */
while (TRUE) {
while (pPriv->ilScaleAccDown > 0) {
if (nlines-- <= 0)
break;
pPriv->ilScaleAccDown -= pPriv->ilScaleDstheight;
psrcline += srcnbytes;
}
if (nlines-- <= 0)
break;
pPriv->ilScaleAccDown += (pPriv->ilScaleSrcheight - pPriv->ilScaleDstheight);
if(srcwidth >= dstwidth)
ilswbytedown (psrcline, pdstline, srcwidth, dstwidth);
else if (srcwidth < dstwidth)
ilswbyteup (psrcline, pdstline, srcwidth, dstwidth);
local_noDstLine++;
psrcline += srcnbytes;
pdstline += dstnbytes;
}
}
else if (pPriv->ilScaleSrcheight < pPriv->ilScaleDstheight ) { /* scale height up */
while (nlines-- > 0) {
for(; pPriv->ilScaleAccUp >= 0; pPriv->ilScaleAccUp -= pPriv->ilScaleSrcheight) {
if(srcwidth >= dstwidth)
ilswbytedown (psrcline, pdstline, srcwidth, dstwidth);
else if (srcwidth < dstwidth)
ilswbyteup (psrcline, pdstline, srcwidth, dstwidth);
local_noDstLine++;
pdstline += dstnbytes;
}
pPriv->ilScaleAccUp += pPriv->ilScaleDstheight ;
psrcline += srcnbytes;
}
}
*pNLines = local_noDstLine;
return IL_OK;
}
/* =============================================================================================================================
ilScale - This is the pipe constructor function that is called by the
application to Add a scale filter to an existing pipe.
This routine will check for format types and do an explicit
conversion if necessary.
============================================================================================================================= */
ilBool ilScale (
ilPipe pipe,
long dstWidth,
long dstHeight,
int option,
void *pOptionData
)
{
unsigned int state;
ilPipeInfo info;
ilScalePrivptr pPriv = NULL;
ilDstElementData dstdata;
ilImageDes imdes;
ilImageFormat imformat;
ilBool convert;
ilBool bitonal;
static unsigned long defaultNGrays = 256;
static unsigned long defaultBitonalThreshold = 192;
/* Get ptr to pipe info and check state */
state = ilGetPipeInfo(pipe, TRUE, &info, &imdes, &imformat);
if(state != IL_PIPE_FORMING) {
if (!pipe->context->error)
ilDeclarePipeInvalid(pipe, IL_ERROR_PIPE_STATE);
return FALSE;
}
/* if scale is by exactly 2x or 4x, try to use fast scale code */
if (option == IL_SCALE_SAMPLE) {
int scaleFactor;
if (((info.width << 1) == dstWidth) && ((info.height << 1) == dstHeight))
scaleFactor = 1;
else if (((info.width << 2) == dstWidth) && ((info.height << 2) == dstHeight))
scaleFactor = 2;
else scaleFactor = 0;
if (scaleFactor) {
if (_ilFastUpsample (pipe, &info, &imdes, &imformat, scaleFactor))
return TRUE; /* scale filter added; exit */
else if (pipe->context->error)
return FALSE; /* error occurred; exit */
}
}
bitonal = FALSE;
/* Check for valid Formats */
convert = FALSE;
switch (imdes.nSamplesPerPixel) {
case 3: /* RGB or YUV */
if(imformat.sampleOrder != IL_SAMPLE_PIXELS) {
imformat.sampleOrder = IL_SAMPLE_PIXELS;
convert = TRUE;
}
if((imformat.nBitsPerSample[0] != 8) ||
(imformat.nBitsPerSample[1] != 8) ||
(imformat.nBitsPerSample[2] != 8)) {
imformat.nBitsPerSample[0] = 8;
imformat.nBitsPerSample[1] = 8;
imformat.nBitsPerSample[2] = 8;
convert = TRUE;
}
break;
case 1:
switch (imformat.nBitsPerSample[0]) {
case 8: /* Byte per pixel */
break;
case 1: /* Bitonal */
bitonal = TRUE;
if (imformat.rowBitAlign != 32) {
imformat.rowBitAlign = 32;
convert = TRUE;
}
break;
default: /* something other than 1 - try 8 */
imformat.nBitsPerSample[0] = 8;
convert = TRUE;
}
break;
default:
return ilDeclarePipeInvalid(pipe, IL_ERROR_NOT_IMPLEMENTED);
}
if(convert) {
if (!ilConvert(pipe, &imdes, &imformat, 0, NULL))
return FALSE;
ilGetPipeInfo (pipe, FALSE, &info, (ilImageDes *)NULL, (ilImageFormat *)NULL);
}
if((dstWidth <= 0) || (dstHeight <= 0))
return ilDeclarePipeInvalid(pipe, IL_ERROR_ZERO_SIZE_IMAGE);
switch (option) {
case IL_SCALE_SIMPLE:
if ((dstWidth == info.width) && (dstHeight == info.height)) return TRUE;
break;
case IL_SCALE_SAMPLE:
/* demotion to simple if not scaling down */
if ((info.width < dstWidth) || (info.height < dstHeight)) break;
if ( ((dstWidth == info.width) && (dstHeight == info.height)) &&
((!bitonal) || (!pOptionData)) ) return TRUE;
/* if a palette image first convert to RGB */
if (imdes.type == IL_PALETTE) {
if (!ilConvert (pipe, IL_DES_RGB, IL_FORMAT_3BYTE_PIXEL, 0, (ilPtr)NULL))
return FALSE;
ilGetPipeInfo (pipe, FALSE, &info, &imdes, &imformat);
}
if (bitonal) {
/* Use default threshold if not supplied */
if (!pOptionData) pOptionData = &defaultBitonalThreshold;
_ilAreaScaleBitonal (pipe, dstWidth, dstHeight, (int *)pOptionData, &info);
}
else
_ilScaleSample (pipe, imdes.nSamplesPerPixel, dstWidth, dstHeight,
256, imdes.blackIsZero, &info);
return (pipe->context->error) ? FALSE : TRUE;
case IL_SCALE_BITONAL_TO_GRAY:
/* Error condition if not scaling down (no demotion) or if the image
is not bitonal. If pOptionData is null, default to 256 levels of gray.
*/
if (!pOptionData) pOptionData = &defaultNGrays;
if ((info.width < dstWidth) || (info.height < dstHeight) || !bitonal)
return ilDeclarePipeInvalid(pipe, IL_ERROR_SCALE_BITONAL_TO_GRAY);
_ilScaleBitonalToGray (pipe, dstWidth, dstHeight,
*((unsigned long *)pOptionData), imdes.blackIsZero, &info);
return (pipe->context->error) ? FALSE : TRUE;
default:
return ilDeclarePipeInvalid(pipe, IL_ERROR_INVALID_OPTION);
}
dstdata.producerObject = (ilObject) NULL;
dstdata.pDes = (ilImageDes *) NULL;
dstdata.pFormat = (ilImageFormat *) NULL;
dstdata.width = dstWidth;
dstdata.height = dstHeight;
dstdata.pPalette = info.pPalette;;
/* set output strip height */
dstdata.stripHeight = (dstHeight * info.recommendedStripHeight)/info.height + 1;
dstdata.constantStrip = FALSE;
switch (imdes.nSamplesPerPixel) {
case 3:
pPriv = (ilScalePrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilScalePriv), 0, (ilSrcElementData *) NULL,
&dstdata, ilScaleInit, IL_NPF, IL_NPF, ilScale3ByteExecute, NULL, 0);
break;
case 1:
if(bitonal)
pPriv = (ilScalePrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilScalePriv), 0, (ilSrcElementData *) NULL,
&dstdata, ilScaleInit, IL_NPF, IL_NPF, ilScaleBitonalExecute, NULL, 0);
else
pPriv = (ilScalePrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilScalePriv), 0, (ilSrcElementData *) NULL,
&dstdata, ilScaleInit, IL_NPF, IL_NPF, ilScaleByteExecute, NULL, 0);
}
if(!pPriv)
return FALSE;
/* Save away true heights */
pPriv->ilScaleDstheight = dstHeight;
pPriv->ilScaleSrcheight = info.height;
pipe->context->error = IL_OK;
return TRUE;
}