616 lines
23 KiB
C
616 lines
23 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: ilformat.c /main/5 1996/06/19 12:21:36 ageorge $ */
|
|
/**---------------------------------------------------------------------
|
|
***
|
|
*** (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).
|
|
***
|
|
***-------------------------------------------------------------------*/
|
|
|
|
/* /ilc/ilformat.c : Reference by ilConvert in /ilc/ilconvert.c .
|
|
Contains pipe functions and an ilFormatRec, which points to the functions
|
|
and defines how the formatter should be added by ilConvert().
|
|
*/
|
|
#include "ilint.h"
|
|
#include "ilpipelem.h"
|
|
#include "ilconvert.h"
|
|
#include "ilerrors.h"
|
|
|
|
/* ------------------------- ilExecuteBitAlign ------------------------- */
|
|
/* Execute() function: convert the given # of src lines, changing
|
|
the rowBitAlign. Easy; just bcopy each line, bump by src/dstRowBytes,
|
|
which presumably are different because of different bit alignment.
|
|
*/
|
|
static ilError ilExecuteBitAlign (
|
|
ilExecuteData *pData,
|
|
long dstLine,
|
|
long *pNLines
|
|
)
|
|
{
|
|
ilImagePlaneInfo *pImagePlane;
|
|
long srcRowBytes, dstRowBytes;
|
|
long nLinesM1, nBytes;
|
|
ilPtr pSrc, pDst;
|
|
|
|
/* Use bcopy to copy each line; copy the lesser of the src/dstRowBytes.
|
|
Exit if no lines or pixels.
|
|
*/
|
|
pImagePlane = &pData->pSrcImage->plane[0];
|
|
srcRowBytes = pImagePlane->nBytesPerRow;
|
|
pSrc = pImagePlane->pPixels + pData->srcLine * srcRowBytes;
|
|
|
|
pImagePlane = &pData->pDstImage->plane[0];
|
|
dstRowBytes = pImagePlane->nBytesPerRow;
|
|
pDst = pImagePlane->pPixels + dstLine * dstRowBytes;
|
|
|
|
nBytes = (srcRowBytes < dstRowBytes) ? srcRowBytes : dstRowBytes;
|
|
if (nBytes <= 0)
|
|
return IL_OK;
|
|
nLinesM1 = *pNLines;
|
|
if (nLinesM1 <= 0)
|
|
return IL_OK;
|
|
nLinesM1--;
|
|
|
|
do {
|
|
bcopy ((char *)pSrc, (char *)pDst, nBytes);
|
|
pSrc += srcRowBytes;
|
|
pDst += dstRowBytes;
|
|
} while (--nLinesM1 >= 0);
|
|
|
|
return IL_OK;
|
|
}
|
|
|
|
/* Table exported to ilConvert(), declared in /ilc/ilconvert.h .
|
|
*/
|
|
IL_PRIVATE ilFormatRec _ilFormatRowBitAlign = {
|
|
IL_NPF, /* AddElement() */
|
|
0, /* nBytesPrivate */
|
|
IL_NPF, /* Init() */
|
|
IL_NPF, /* Cleanup() */
|
|
IL_NPF, /* Destroy() */
|
|
ilExecuteBitAlign /* Execute() */
|
|
};
|
|
|
|
|
|
/* ------------------------- ilExecute8Bit3PlaneToPixel ------------------------- */
|
|
/* Execute() function: convert the given # of src lines, changing
|
|
format from planar to pixel. Handles 3 planes of 8 bits/pixel only.
|
|
*/
|
|
static ilError ilExecute8Bit3PlaneToPixel (
|
|
ilExecuteData *pData,
|
|
long dstLine,
|
|
long *pNLines
|
|
)
|
|
{
|
|
ilImagePlaneInfo *pImagePlane;
|
|
long src0RowBytes, src1RowBytes, src2RowBytes, dstRowBytes;
|
|
long nPixelsM1Init;
|
|
long nLinesM1, nPixelsM1;
|
|
ilPtr pSrc0Line, pSrc1Line, pSrc2Line, pDstLine;
|
|
ilPtr pSrc0, pSrc1, pSrc2, pDst;
|
|
|
|
/* Get ptr to start of 3 src planes and to dst */
|
|
pImagePlane = pData->pSrcImage->plane;
|
|
src0RowBytes = pImagePlane->nBytesPerRow;
|
|
pSrc0Line = pImagePlane->pPixels + pData->srcLine * src0RowBytes;
|
|
pImagePlane++;
|
|
src1RowBytes = pImagePlane->nBytesPerRow;
|
|
pSrc1Line = pImagePlane->pPixels + pData->srcLine * src1RowBytes;
|
|
pImagePlane++;
|
|
src2RowBytes = pImagePlane->nBytesPerRow;
|
|
pSrc2Line = pImagePlane->pPixels + pData->srcLine * src2RowBytes;
|
|
|
|
pImagePlane = pData->pDstImage->plane;
|
|
dstRowBytes = pImagePlane->nBytesPerRow;
|
|
pDstLine = pImagePlane->pPixels + dstLine * dstRowBytes;
|
|
|
|
/* Exit if no lines or pixels. */
|
|
nPixelsM1Init = pData->pSrcImage->width;
|
|
if (nPixelsM1Init <= 0)
|
|
return IL_OK;
|
|
nPixelsM1Init--;
|
|
nLinesM1 = *pNLines;
|
|
if (nLinesM1 <= 0)
|
|
return IL_OK;
|
|
nLinesM1--;
|
|
|
|
do {
|
|
pSrc0 = pSrc0Line;
|
|
pSrc0Line += src0RowBytes;
|
|
pSrc1 = pSrc1Line;
|
|
pSrc1Line += src1RowBytes;
|
|
pSrc2 = pSrc2Line;
|
|
pSrc2Line += src2RowBytes;
|
|
pDst = pDstLine;
|
|
pDstLine += dstRowBytes;
|
|
nPixelsM1 = nPixelsM1Init;
|
|
do {
|
|
*pDst++ = *pSrc0++;
|
|
*pDst++ = *pSrc1++;
|
|
*pDst++ = *pSrc2++;
|
|
} while (--nPixelsM1 >= 0);
|
|
} while (--nLinesM1 >= 0);
|
|
|
|
return IL_OK;
|
|
}
|
|
|
|
/* Table exported to ilConvert(), declared in /ilc/ilconvert.h .
|
|
*/
|
|
IL_PRIVATE ilFormatRec _ilFormat8Bit3PlaneToPixel = {
|
|
IL_NPF, /* AddElement() */
|
|
0, /* nBytesPrivate */
|
|
IL_NPF, /* Init() */
|
|
IL_NPF, /* Cleanup() */
|
|
IL_NPF, /* Destroy() */
|
|
ilExecute8Bit3PlaneToPixel /* Execute() */
|
|
};
|
|
|
|
/* ------------------------- ilExecute8Bit3PixelToPlane ------------------------- */
|
|
/* Execute() function: convert the given # of src lines, changing
|
|
format from pixel to planar. Handles 3 planes of 8 bits/pixel only.
|
|
*/
|
|
static ilError ilExecute8Bit3PixelToPlane (
|
|
ilExecuteData *pData,
|
|
long dstLine,
|
|
long *pNLines
|
|
)
|
|
{
|
|
ilImagePlaneInfo *pImagePlane;
|
|
long dst0RowBytes, dst1RowBytes, dst2RowBytes, srcRowBytes;
|
|
long nPixelsM1Init;
|
|
long nLinesM1, nPixelsM1;
|
|
ilPtr pDst0Line, pDst1Line, pDst2Line, pSrcLine;
|
|
ilPtr pDst0, pDst1, pDst2, pSrc;
|
|
|
|
/* Get ptr to start src plane and to 3 dst planes */
|
|
pImagePlane = pData->pSrcImage->plane;
|
|
srcRowBytes = pImagePlane->nBytesPerRow;
|
|
pSrcLine = pImagePlane->pPixels + pData->srcLine * srcRowBytes;
|
|
|
|
pImagePlane = pData->pDstImage->plane;
|
|
dst0RowBytes = pImagePlane->nBytesPerRow;
|
|
pDst0Line = pImagePlane->pPixels + dstLine * dst0RowBytes;
|
|
pImagePlane++;
|
|
dst1RowBytes = pImagePlane->nBytesPerRow;
|
|
pDst1Line = pImagePlane->pPixels + dstLine * dst1RowBytes;
|
|
pImagePlane++;
|
|
dst2RowBytes = pImagePlane->nBytesPerRow;
|
|
pDst2Line = pImagePlane->pPixels + dstLine * dst2RowBytes;
|
|
|
|
/* Exit if no lines or pixels. */
|
|
nPixelsM1Init = pData->pSrcImage->width;
|
|
if (nPixelsM1Init <= 0)
|
|
return IL_OK;
|
|
nPixelsM1Init--;
|
|
nLinesM1 = *pNLines;
|
|
if (nLinesM1 <= 0)
|
|
return IL_OK;
|
|
nLinesM1--;
|
|
|
|
do {
|
|
pSrc = pSrcLine;
|
|
pSrcLine += srcRowBytes;
|
|
pDst0 = pDst0Line;
|
|
pDst0Line += dst0RowBytes;
|
|
pDst1 = pDst1Line;
|
|
pDst1Line += dst1RowBytes;
|
|
pDst2 = pDst2Line;
|
|
pDst2Line += dst2RowBytes;
|
|
nPixelsM1 = nPixelsM1Init;
|
|
do {
|
|
*pDst0++ = *pSrc++;
|
|
*pDst1++ = *pSrc++;
|
|
*pDst2++ = *pSrc++;
|
|
} while (--nPixelsM1 >= 0);
|
|
} while (--nLinesM1 >= 0);
|
|
|
|
return IL_OK;
|
|
}
|
|
|
|
/* Table exported to ilConvert(), declared in /ilc/ilconvert.h .
|
|
*/
|
|
IL_PRIVATE ilFormatRec _ilFormat8Bit3PixelToPlane = {
|
|
IL_NPF, /* AddElement() */
|
|
0, /* nBytesPrivate */
|
|
IL_NPF, /* Init() */
|
|
IL_NPF, /* Cleanup() */
|
|
IL_NPF, /* Destroy() */
|
|
ilExecute8Bit3PixelToPlane /* Execute() */
|
|
};
|
|
|
|
|
|
/* ------------------------- ilExecute4To8Bit ------------------------- */
|
|
/* Execute() function: convert the given # of src lines, changing nibbles
|
|
to bytes, by copying the nibbles to the low order of the bytes.
|
|
Handles any number of samples, but pixel order only if multi-sample.
|
|
*/
|
|
static ilError ilExecute4To8Bit (
|
|
ilExecuteData *pData,
|
|
long dstLine,
|
|
long *pNLines
|
|
)
|
|
{
|
|
ilImageInfo *pSrcImage;
|
|
ilImagePlaneInfo *pImagePlane;
|
|
long srcRowBytes, dstRowBytes, nBytesM1Init, nLinesM1;
|
|
ilBool oddNumberOfNibbles;
|
|
ilPtr pSrcLine, pDstLine;
|
|
long nBytesM1;
|
|
ilPtr pSrc, pDst;
|
|
ilByte byte;
|
|
|
|
/* Exit if no lines or pixels. */
|
|
pSrcImage = pData->pSrcImage;
|
|
pImagePlane = &pSrcImage->plane[0];
|
|
srcRowBytes = pImagePlane->nBytesPerRow;
|
|
pSrcLine = pImagePlane->pPixels + pData->srcLine * srcRowBytes;
|
|
|
|
pImagePlane = &pData->pDstImage->plane[0];
|
|
dstRowBytes = pImagePlane->nBytesPerRow;
|
|
pDstLine = pImagePlane->pPixels + dstLine * dstRowBytes;
|
|
|
|
nLinesM1 = *pNLines;
|
|
if (nLinesM1 <= 0)
|
|
return IL_OK;
|
|
nLinesM1--;
|
|
|
|
/* Set "nBytesM1Init" to whole # of src bytes to do (2 nibbles each),
|
|
where the # of nibbles is width * nSamplesPerPixel.
|
|
Set "oddNumberOfNibbles" true if width is odd (do one last nibble).
|
|
Copy each src byte (2 nibbles) to two dst bytes; do optional last nibble.
|
|
*/
|
|
nBytesM1Init = pSrcImage->width * pSrcImage->pDes->nSamplesPerPixel;
|
|
oddNumberOfNibbles = ((nBytesM1Init & 1) != 0);
|
|
nBytesM1Init = (nBytesM1Init >> 1) - 1; /* width/2 - 1 */
|
|
do {
|
|
pSrc = pSrcLine;
|
|
pSrcLine += srcRowBytes;
|
|
pDst = pDstLine;
|
|
pDstLine += dstRowBytes;
|
|
nBytesM1 = nBytesM1Init;
|
|
if (nBytesM1 >= 0) {
|
|
do {
|
|
byte = *pSrc++;
|
|
*pDst++ = byte >> 4;
|
|
*pDst++ = byte & 0xf;
|
|
} while (--nBytesM1 >= 0);
|
|
}
|
|
if (oddNumberOfNibbles) {
|
|
byte = *pSrc++;
|
|
*pDst++ = byte >> 4;
|
|
}
|
|
} while (--nLinesM1 >= 0);
|
|
|
|
return IL_OK;
|
|
}
|
|
|
|
/* Table exported to ilConvert(), declared in /ilc/ilconvert.h .
|
|
*/
|
|
IL_PRIVATE ilFormatRec _ilFormat4To8Bit = {
|
|
IL_NPF, /* AddElement() */
|
|
0, /* nBytesPrivate */
|
|
IL_NPF, /* Init() */
|
|
IL_NPF, /* Cleanup() */
|
|
IL_NPF, /* Destroy() */
|
|
ilExecute4To8Bit /* Execute() */
|
|
};
|
|
|
|
|
|
/* ------------------------- ilExecute8To4Bit ------------------------- */
|
|
/* Pack pipe image which is byte/pixel into nibble/pixel.
|
|
Handles any number of samples, but pixel order only if multi-sample.
|
|
*/
|
|
static ilError ilExecute8To4Bit (
|
|
ilExecuteData *pData,
|
|
long dstLine,
|
|
long *pNLines
|
|
)
|
|
{
|
|
ilImageInfo *pSrcImage;
|
|
ilImagePlaneInfo *pImagePlane;
|
|
long srcRowBytes, dstRowBytes, nBytesM1Init, nLinesM1;
|
|
ilBool oddNumberOfNibbles;
|
|
ilPtr pSrcLine, pDstLine;
|
|
long nBytesM1;
|
|
ilPtr pSrc, pDst;
|
|
ilByte byte0, byte1;
|
|
|
|
/* Exit if no lines or pixels. */
|
|
pSrcImage = pData->pSrcImage;
|
|
pImagePlane = &pSrcImage->plane[0];
|
|
srcRowBytes = pImagePlane->nBytesPerRow;
|
|
pSrcLine = pImagePlane->pPixels + pData->srcLine * srcRowBytes;
|
|
|
|
pImagePlane = &pData->pDstImage->plane[0];
|
|
dstRowBytes = pImagePlane->nBytesPerRow;
|
|
pDstLine = pImagePlane->pPixels + dstLine * dstRowBytes;
|
|
|
|
nLinesM1 = *pNLines;
|
|
if (nLinesM1 <= 0)
|
|
return IL_OK;
|
|
nLinesM1--;
|
|
|
|
/* Set "nBytesM1Init" to whole # of dst bytes to do (2 nibbles each),
|
|
where the # of nibbles is width * nSamplesPerPixel.
|
|
Set "oddNumberOfNibbles" true if width is odd (do one last nibble).
|
|
Pack each pair of src bytes into one dst nibble; do optional last nibble.
|
|
*/
|
|
nBytesM1Init = pSrcImage->width * pSrcImage->pDes->nSamplesPerPixel;
|
|
oddNumberOfNibbles = ((nBytesM1Init & 1) != 0);
|
|
nBytesM1Init = (nBytesM1Init >> 1) - 1; /* width/2 - 1 */
|
|
do {
|
|
pSrc = pSrcLine;
|
|
pSrcLine += srcRowBytes;
|
|
pDst = pDstLine;
|
|
pDstLine += dstRowBytes;
|
|
nBytesM1 = nBytesM1Init;
|
|
if (nBytesM1 >= 0) {
|
|
do {
|
|
byte0 = *pSrc++;
|
|
byte1 = *pSrc++;
|
|
*pDst++ = (byte0 << 4) | (byte1 & 0xf);
|
|
} while (--nBytesM1 >= 0);
|
|
}
|
|
if (oddNumberOfNibbles) {
|
|
byte0 = *pSrc++;
|
|
*pDst++ = byte0 << 4;
|
|
}
|
|
} while (--nLinesM1 >= 0);
|
|
|
|
return IL_OK;
|
|
}
|
|
|
|
/* Table exported to ilConvert(), declared in /ilc/ilconvert.h .
|
|
*/
|
|
IL_PRIVATE ilFormatRec _ilFormat8To4Bit = {
|
|
IL_NPF, /* AddElement() */
|
|
0, /* nBytesPrivate */
|
|
IL_NPF, /* Init() */
|
|
IL_NPF, /* Cleanup() */
|
|
IL_NPF, /* Destroy() */
|
|
ilExecute8To4Bit /* Execute() */
|
|
};
|
|
|
|
|
|
/* ------------------------- ilExecute4To8BitScaled ------------------------- */
|
|
/* Execute() function: convert the given # of src lines, changing nibbles
|
|
to bytes, by copying the nibbles to the low order and high order nibbles
|
|
of the bytes, thus scaling from 0..15 to 0..255.
|
|
Handles any number of samples, but pixel order only if multi-sample.
|
|
*/
|
|
static ilError ilExecute4To8BitScaled (
|
|
ilExecuteData *pData,
|
|
long dstLine,
|
|
long *pNLines
|
|
)
|
|
{
|
|
ilImageInfo *pSrcImage;
|
|
ilImagePlaneInfo *pImagePlane;
|
|
long srcRowBytes, dstRowBytes, nBytesM1Init, nLinesM1;
|
|
ilBool oddNumberOfNibbles;
|
|
ilPtr pSrcLine, pDstLine;
|
|
long nBytesM1;
|
|
ilPtr pSrc, pDst;
|
|
ilByte byte;
|
|
|
|
/* Use bcopy to copy each line; copy the lesser of the src/dstRowBytes.
|
|
Exit if no lines or pixels.
|
|
*/
|
|
pSrcImage = pData->pSrcImage;
|
|
pImagePlane = &pSrcImage->plane[0];
|
|
srcRowBytes = pImagePlane->nBytesPerRow;
|
|
pSrcLine = pImagePlane->pPixels + pData->srcLine * srcRowBytes;
|
|
|
|
pImagePlane = &pData->pDstImage->plane[0];
|
|
dstRowBytes = pImagePlane->nBytesPerRow;
|
|
pDstLine = pImagePlane->pPixels + dstLine * dstRowBytes;
|
|
|
|
nLinesM1 = *pNLines;
|
|
if (nLinesM1 <= 0)
|
|
return IL_OK;
|
|
nLinesM1--;
|
|
|
|
/* Set "nBytesM1Init" to whole # of src bytes to do (2 nibbles each),
|
|
where the # of nibbles is width * nSamplesPerPixel.
|
|
Set "oddNumberOfNibbles" true if width is odd (do one last nibble).
|
|
Make from each src byte (2 nibbles) two dst bytes; do optional last nibble.
|
|
Replicate each src nibble to upper/lower nibble of dst byte, thus scaling
|
|
to new # of levels (from 16 to 256): 0 => 0, 1 => 17, 15 => 255.
|
|
*/
|
|
nBytesM1Init = pSrcImage->width * pSrcImage->pDes->nSamplesPerPixel;
|
|
oddNumberOfNibbles = ((nBytesM1Init & 1) != 0);
|
|
nBytesM1Init = (nBytesM1Init >> 1) - 1; /* width/2 - 1 */
|
|
do {
|
|
pSrc = pSrcLine;
|
|
pSrcLine += srcRowBytes;
|
|
pDst = pDstLine;
|
|
pDstLine += dstRowBytes;
|
|
nBytesM1 = nBytesM1Init;
|
|
if (nBytesM1 >= 0) {
|
|
do {
|
|
byte = *pSrc++;
|
|
*pDst++ = (byte & 0xf0) | (byte >> 4);
|
|
byte &= 0xf;
|
|
*pDst++ = (byte << 4) | byte;
|
|
} while (--nBytesM1 >= 0);
|
|
}
|
|
if (oddNumberOfNibbles) {
|
|
byte = *pSrc++;
|
|
*pDst++ = (byte & 0xf0) | (byte >> 4);
|
|
}
|
|
} while (--nLinesM1 >= 0);
|
|
|
|
return IL_OK;
|
|
}
|
|
|
|
|
|
/* ------------------------- ilExecuteByte16To256Level ---------------------- */
|
|
/* Execute() function: convert the given # of src lines, changing bytes from
|
|
16 levels to 256 levels, by replicating the low-order nibble to the high
|
|
order nibble, thus scaling from 0..15 to 0..255.
|
|
Handles any number of samples, but pixel order only if multi-sample.
|
|
*/
|
|
static ilError ilExecuteByte16To256Level (
|
|
ilExecuteData *pData,
|
|
long dstLine,
|
|
long *pNLines
|
|
)
|
|
{
|
|
ilImageInfo *pSrcImage;
|
|
ilImagePlaneInfo *pImagePlane;
|
|
long srcRowBytes, dstRowBytes, nBytesM1Init, nLinesM1;
|
|
ilPtr pSrcLine, pDstLine;
|
|
long nBytesM1;
|
|
ilPtr pSrc, pDst;
|
|
ilByte byte;
|
|
|
|
/* Use bcopy to copy each line; copy the lesser of the src/dstRowBytes.
|
|
Exit if no lines or pixels.
|
|
*/
|
|
pSrcImage = pData->pSrcImage;
|
|
pImagePlane = &pSrcImage->plane[0];
|
|
srcRowBytes = pImagePlane->nBytesPerRow;
|
|
pSrcLine = pImagePlane->pPixels + pData->srcLine * srcRowBytes;
|
|
|
|
pImagePlane = &pData->pDstImage->plane[0];
|
|
dstRowBytes = pImagePlane->nBytesPerRow;
|
|
pDstLine = pImagePlane->pPixels + dstLine * dstRowBytes;
|
|
|
|
nLinesM1 = *pNLines;
|
|
if (nLinesM1 <= 0)
|
|
return IL_OK;
|
|
nLinesM1--;
|
|
|
|
/* Set "nBytesM1Init" to whole # of src bytes to do, = width * # samples/pixel
|
|
(note that each sample must be a byte!)
|
|
Replicate low-order nibble to upper nibble of dst byte, thus scaling
|
|
to new # of levels (from 16 to 256): 0 => 0, 1 => 17, 15 => 255.
|
|
*/
|
|
nBytesM1Init = pSrcImage->width * pSrcImage->pDes->nSamplesPerPixel - 1;
|
|
if (nBytesM1Init < 0)
|
|
return IL_OK;
|
|
|
|
do {
|
|
pSrc = pSrcLine;
|
|
pSrcLine += srcRowBytes;
|
|
pDst = pDstLine;
|
|
pDstLine += dstRowBytes;
|
|
nBytesM1 = nBytesM1Init;
|
|
do {
|
|
byte = *pSrc++;
|
|
byte &= 0xf;
|
|
*pDst++ = (byte << 4) | byte;
|
|
} while (--nBytesM1 >= 0);
|
|
} while (--nLinesM1 >= 0);
|
|
|
|
return IL_OK;
|
|
}
|
|
|
|
|
|
/* ---------------------- ilAddLevelConversionFilter ------------------------ */
|
|
/* Add a conversion filter to the given pipe which converts from the levels
|
|
in "*pPipeDes" (i.e. the levels of the current pipe image) to those in
|
|
"*pDes" (note - only nLevelsPerSample is reference from pDes).
|
|
If failure, declares pipe invalid (which sets error code) and returns false;
|
|
else returns true and "*pInfo", "*pPipeDes" and "*pFormat" are updated
|
|
with the new pipe state info.
|
|
*/
|
|
IL_PRIVATE ilBool _ilAddLevelConversionFilter (
|
|
ilPipe pipe,
|
|
ilPipeInfo *pInfo,
|
|
ilImageDes *pPipeDes,
|
|
const ilImageDes *pDes,
|
|
ilImageFormat *pFormat
|
|
)
|
|
{
|
|
unsigned int sample;
|
|
ilPtr pPriv;
|
|
ilDstElementData dstData;
|
|
ilError (*executeFunction)();
|
|
ilBool all4Bit, all8Bit;
|
|
|
|
/* Determine if we support requested conversion.
|
|
Currently only support: 4 or 8 bit, 16 level => 8 bit, 256 level, any # of
|
|
samples/pixel, but pixel mode only if # samples > 1.
|
|
*/
|
|
if ((pDes->nSamplesPerPixel > 1) && (pFormat->sampleOrder != IL_SAMPLE_PIXELS))
|
|
return ilDeclarePipeInvalid (pipe, IL_ERROR_CANT_CONVERT);
|
|
|
|
all4Bit = all8Bit = TRUE;
|
|
for (sample = 0; sample < pPipeDes->nSamplesPerPixel; sample++) {
|
|
if ((pPipeDes->nLevelsPerSample[sample] != 16)
|
|
|| (pDes->nLevelsPerSample[sample] != 256))
|
|
return ilDeclarePipeInvalid (pipe, IL_ERROR_CANT_CONVERT);
|
|
pPipeDes->nLevelsPerSample[sample] = 256;
|
|
|
|
if (pFormat->nBitsPerSample[sample] == 4) {
|
|
all8Bit = FALSE;
|
|
pFormat->nBitsPerSample[sample] = 8;
|
|
}
|
|
else if (pFormat->nBitsPerSample[sample] == 8)
|
|
all4Bit = FALSE;
|
|
else return ilDeclarePipeInvalid (pipe, IL_ERROR_CANT_CONVERT);
|
|
}
|
|
|
|
/* All src # levels == 16, dst == 256. If all src formats are 4 bit or 8 bit,
|
|
can handle, else error. pFormat->nBitsPerSample now == 8 for all samples.
|
|
*/
|
|
if (all4Bit)
|
|
executeFunction = ilExecute4To8BitScaled;
|
|
else if (all8Bit)
|
|
executeFunction = ilExecuteByte16To256Level;
|
|
else return ilDeclarePipeInvalid (pipe, IL_ERROR_CANT_CONVERT);
|
|
|
|
/* Update *pPipeDes, *pFormat and add filter or error.
|
|
Update pInfo after successful add; pPipeDes and pFormat already updated.
|
|
*/
|
|
dstData.producerObject = (ilObject)NULL;
|
|
dstData.pDes = pPipeDes;
|
|
dstData.pFormat = pFormat;
|
|
dstData.width = pInfo->width;
|
|
dstData.height = pInfo->height;
|
|
dstData.stripHeight = 0;
|
|
dstData.constantStrip = FALSE;
|
|
dstData.pPalette = pInfo->pPalette;
|
|
dstData.pCompData = pInfo->pCompData;
|
|
pPriv = ilAddPipeElement (pipe, IL_FILTER, 0, 0,
|
|
(ilSrcElementData *)NULL, &dstData,
|
|
IL_NPF, IL_NPF, IL_NPF, executeFunction, NULL, 0);
|
|
if (!pPriv) return FALSE; /* EXIT */
|
|
|
|
ilGetPipeInfo (pipe, FALSE, pInfo, (ilImageDes *)NULL, (ilImageFormat *)NULL);
|
|
return TRUE;
|
|
}
|
|
|
|
|