cdesktopenv/cde/lib/DtHelp/il/ilreadimage.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;
}