170 lines
6.3 KiB
C
170 lines
6.3 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: ilreadimage.c /main/3 1995/10/23 15:59:31 rswiston $ */
|
|
/**---------------------------------------------------------------------
|
|
***
|
|
*** (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 "ilpipeint.h"
|
|
#include "ilimage.h"
|
|
#include "ilerrors.h"
|
|
|
|
|
|
/* Private structure for ilRCIExecute(). (RCI = "Read Compressed Image") */
|
|
typedef struct {
|
|
ilImagePtr pImage; /* ptr to src image */
|
|
long strip; /* Init(): index of next strip to write */
|
|
long nLinesWritten; /* Init(): # of lines written so far */
|
|
} ilRCIPrivRec, *ilRCIPrivPtr;
|
|
|
|
|
|
/* ------------------------- ilRCIInit ----------------------------------- */
|
|
/* Init() function for ilRCI().
|
|
*/
|
|
static ilError ilRCIInit (
|
|
ilRCIPrivPtr pPriv,
|
|
ilImageInfo *pSrcImage,
|
|
ilImageInfo *pDstImage
|
|
)
|
|
{
|
|
pPriv->strip = 0; /* init strip index, for first strip */
|
|
pPriv->nLinesWritten = 0;
|
|
return IL_OK;
|
|
}
|
|
|
|
/* --------------------- ilRCIExecute -------------------------- */
|
|
/* Execute() for ilReadImage() producer when the image is compressed.
|
|
*/
|
|
static ilError ilRCIExecute (
|
|
ilExecuteData *pData,
|
|
long dstLine, /* ignored */
|
|
long *pNLines /* ignored on input */
|
|
)
|
|
{
|
|
ilRCIPrivPtr pPriv;
|
|
ilImagePtr pImage;
|
|
long offset;
|
|
|
|
pPriv = (ilRCIPrivPtr)pData->pPrivate;
|
|
pImage = pPriv->pImage;
|
|
|
|
/* Return error if image has never been written to. */
|
|
if (!pImage->pStripOffsets || !pImage->i.plane[0].pPixels)
|
|
return IL_ERROR_NULL_COMPRESSED_IMAGE;
|
|
|
|
/* "write" current strip by patching next filter's offset to offset for
|
|
current strip, and setting its # bytes to size of this strip.
|
|
*/
|
|
offset = pImage->pStripOffsets[pPriv->strip];
|
|
*pData->compressed.pDstOffset = offset;
|
|
pPriv->strip++;
|
|
*pData->compressed.pNBytesWritten = pImage->pStripOffsets[pPriv->strip] - offset;
|
|
|
|
/* If last strip, # of lines is remaining, else is strip height */
|
|
if ((pPriv->nLinesWritten + pImage->stripHeight) > pImage->i.height) {
|
|
*pNLines = pImage->i.height - pPriv->nLinesWritten;
|
|
return IL_ERROR_LAST_STRIP;
|
|
}
|
|
pPriv->nLinesWritten += pImage->stripHeight;
|
|
*pNLines = pImage->stripHeight;
|
|
return IL_OK;
|
|
}
|
|
|
|
|
|
/* ------------------------ ilReadImage ---------------------------------- */
|
|
/* Public function: see spec.
|
|
Adds the given image as a producer of the pipe.
|
|
*/
|
|
ilBool ilReadImage (
|
|
ilPipe pipe,
|
|
ilObject image
|
|
)
|
|
{
|
|
ilImagePtr pImage;
|
|
ilRCIPrivPtr pPriv;
|
|
|
|
/* Validate that pipe and image are such, have same context and pipe empty */
|
|
pImage = (ilImagePtr)image;
|
|
if (pipe->objectType != IL_PIPE) {
|
|
pipe->context->error = IL_ERROR_OBJECT_TYPE;
|
|
return FALSE;
|
|
}
|
|
|
|
if ((pImage->o.p.objectType != IL_INTERNAL_IMAGE)
|
|
&& (pImage->o.p.objectType != IL_CLIENT_IMAGE))
|
|
return ilDeclarePipeInvalid (pipe, IL_ERROR_OBJECT_TYPE);
|
|
|
|
if (pImage->o.p.context != pipe->context)
|
|
return ilDeclarePipeInvalid (pipe, IL_ERROR_CONTEXT_MISMATCH);
|
|
|
|
if (ilGetPipeInfo (pipe, FALSE, (ilPipeInfo *)NULL, (ilImageDes *)NULL,
|
|
(ilImageFormat *)NULL) != IL_PIPE_EMPTY) {
|
|
if (!pipe->context->error)
|
|
ilDeclarePipeInvalid (pipe, IL_ERROR_PIPE_STATE);
|
|
return FALSE;
|
|
}
|
|
|
|
/* If uncompressed, add producer image and exit. stripHeight = image height,
|
|
need producer throttle filter before next element is added.
|
|
*/
|
|
if (pImage->des.compression == IL_UNCOMPRESSED)
|
|
return _ilAddProducerImage (pipe, pImage, IL_PIPE_IMAGE, pImage->i.height,
|
|
pImage->i.height, TRUE, TRUE);
|
|
|
|
/* Image is compressed: if no stripHeight yet, allocate strip offsets array using
|
|
default strip height. Add producer image: constant strips the size of the
|
|
image's strip height. Add producer throttle to feed each strip.
|
|
*/
|
|
if (!pImage->pStripOffsets)
|
|
if (!_ilAllocStripOffsets (pImage, 0))
|
|
return FALSE;
|
|
|
|
if (!_ilAddProducerImage (pipe, pImage, IL_PIPE_IMAGE, pImage->i.height,
|
|
pImage->stripHeight, TRUE, FALSE))
|
|
return FALSE;
|
|
|
|
pPriv = (ilRCIPrivPtr)ilAddPipeElement (pipe, IL_FILTER, sizeof (ilRCIPrivRec),
|
|
IL_ADD_PIPE_NO_DST, (ilSrcElementData *)NULL, (ilDstElementData *)NULL,
|
|
ilRCIInit, IL_NPF, IL_NPF, ilRCIExecute, 0);
|
|
if (!pPriv)
|
|
return FALSE;
|
|
pPriv->pImage = pImage;
|
|
|
|
return TRUE;
|
|
}
|
|
|