123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332 |
- /*
- * 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: ilhplrotate.c /main/3 1995/10/23 15:48:20 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).
- ***
- ***-------------------------------------------------------------------*/
- /* =============================================================================================================================
- /ilc/ilhplrotate.c : Images Library arbitrary rotation routines. using HP-LABs
- image rotation code
- ============================================================================================================================= */
- #include "ilint.h"
- #include "ilpipelem.h"
- #include "ilerrors.h"
- #include "ilhplrotation.h"
- typedef struct {
- DATA_IN_PTR data_in; /* pointer to where to put input data */
- DATA_OUT_PTR buf;
- ilBool restart; /* TRUE on pipe re-execution */
- short in_w; /* Arguments to IR_Rotate_Image_Begin */
- short in_h;
- short in_nSPP;
- short mode;
- float degrees;
- unsigned char bg_r, bg_g, bg_b;
- } ilRotatePriv, *ilRotatePrivptr;
- /* =============================================================================================================================
- ilRotateInit - Init for Rotation for images
- ============================================================================================================================= */
- static ilError ilRotateInit2(
- ilRotatePrivptr p,
- ilImageInfo *pSrcImage,
- ilImageInfo *pDstImage
- )
-
- {
- DATA_IN_PTR data_in;
- DATA_OUT_PTR buf;
- short out_w, out_h;
- /* Re-Initialize rotation code if necessary */
- if (p->restart) {
- data_in = _il_Rotate_Image_Begin (p->in_w , p->in_h, p->in_nSPP, p->mode,
- p->degrees, p->bg_r, p->bg_g, p->bg_b, &out_w, &out_h);
- buf = (DATA_OUT_PTR) malloc(out_w * p->in_nSPP);
- if (!buf) {
- return FALSE;
- }
-
- p->buf = buf;
- p->data_in = data_in;
- }
- else
- p->restart = TRUE;
- return IL_OK;
- }
-
- /* =============================================================================================================================
- ilRotateCleanup - Cleanup for Rotation for images
- ============================================================================================================================= */
- static ilError ilRotateCleanup (
- ilRotatePrivptr pPriv,
- ilBool aborting
- )
- {
- free (pPriv->buf);
- _il_Rotate_Image_End();
- return IL_OK;
- }
- /* =============================================================================================================================
- ilRotateExecute - Rotation for images
- ============================================================================================================================= */
- static ilError ilRotateExecute (
- ilExecuteData *pData,
- unsigned long dstLine,
- unsigned long *pNLines
- )
- {
- unsigned char *psrc, *pdst, *psrcline, *pdstline;
- unsigned long srcnbytes, dstnbytes;
- ilImagePlaneInfo *pplane;
- ilRotatePrivptr pPriv;
- int nrows, nlines, nlinesout;
- if (*pNLines <= 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 = (ilRotatePrivptr) pData->pPrivate;
-
- nlines = *pNLines;
- nlinesout = 0;
- for (nlines = *pNLines; nlines > 0; nlines--){
- bcopy ((char *) psrcline, (char *) pPriv->data_in, (int) srcnbytes);
- for (nrows = _il_Rotate_Send_Row(&pPriv->data_in);
- nrows > 0; --nrows) {
- _il_Rotate_Get_Row(pPriv->buf);
- bcopy ((char *) pPriv->buf, (char *) pdstline, (int) dstnbytes);
- pdstline += dstnbytes;
- nlinesout++;
- }
- psrcline += srcnbytes;
- }
- *pNLines = nlinesout;
- return IL_OK;
- }
- /* =============================================================================================================================
- ilRotate - Add a rotate filter to an existing pipe for 0 - 90 degree rotations - checking
- for format types and doing an explicit conversion if necessary. Positive factors
- cause clockwise rotations - negative counter clockwise.
- ============================================================================================================================= */
- ilBool ilRotate(
- ilPipe pipe,
- int degrees,
- int interpMode,
- unsigned long bg_color[]
- )
- {
- unsigned int state;
- ilPipeInfo info;
- ilRotatePrivptr pPriv;
- ilDstElementData dstdata;
- ilImageDes imdes;
- ilImageFormat imformat;
- ilBool convert;
- unsigned int rtype;
- short out_w, out_h, nrows;
- DATA_IN_PTR data_in;
- DATA_OUT_PTR buf;
- #define PIPE_FLAGS
- /* 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;
- }
- /* 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 */
- if (imdes.type == IL_PALETTE &&
- interpMode != IL_ROTATE_SIMPLE) {
- imdes.type = IL_RGB;
- convert = TRUE;
- }
- break;
- case 1: /* Bitonal */
- return ilDeclarePipeInvalid
- (pipe, IL_ERROR_NOT_IMPLEMENTED);
- 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);
- }
-
- /* Determine rotation type */
- degrees %= 360;
- if (degrees < 0) degrees += 360;
- /*
- * temporarily, special code can only handle 0 - 90 rotation
- * also, code rotates ccw, but we want to rotate clockwise.
- */
- if (!ilRotate90(pipe, (degrees+89)/90)) return FALSE;
- ilGetPipeInfo (pipe, FALSE, &info, (ilImageDes *)NULL, (ilImageFormat *)NULL);
- degrees = 90 - (degrees % 90);
- /* check if 90 deg rotations is sufficient */
- if (degrees == 90) {pipe->context->error = IL_OK; return TRUE;}
- data_in = _il_Rotate_Image_Begin ( (short) info.width, (short) info.height,
- (short) imdes.nSamplesPerPixel, (short) interpMode,
- (float) degrees,
- (unsigned char) bg_color[0], (unsigned char) bg_color[1], (unsigned char) bg_color[2],
- &out_w, &out_h);
- dstdata.producerObject = (ilObject) NULL;
- dstdata.pDes = (ilImageDes *) NULL;
- dstdata.pFormat = (ilImageFormat *) NULL;
- dstdata.pPalette = info.pPalette;
- dstdata.width = out_w;
- dstdata.height = out_h;
- /* set output strip height */
- dstdata.stripHeight = dstdata.height;
- dstdata.constantStrip = FALSE;
- pPriv = (ilRotatePrivptr) ilAddPipeElement (pipe, IL_FILTER,
- sizeof(ilRotatePriv), IL_ADD_PIPE_HOLD_DST,
- (ilSrcElementData *) NULL, &dstdata, ilRotateInit2,
- ilRotateCleanup, IL_NPF, ilRotateExecute, 0);
- if(!pPriv)
- return FALSE;
- buf = (DATA_OUT_PTR) malloc(out_w * (short) imdes.nSamplesPerPixel);
- if (!buf) {
- pipe->context->error = IL_ERROR_MALLOC;
- free(pPriv);
- return FALSE;
- }
-
- pPriv->buf = buf;
- pPriv->data_in = data_in;
- pPriv->restart = FALSE;
- /* Arguments to IR_Rotate_Image_Begin */
- pPriv->in_w = (short) info.width ;
- pPriv->in_h = (short) info.height;
- pPriv->in_nSPP = (short) imdes.nSamplesPerPixel;
- pPriv->mode = (short) interpMode;
- pPriv->degrees = (float) degrees;
- pPriv->bg_r = (unsigned char) bg_color[0];
- pPriv->bg_g = (unsigned char) bg_color[1];
- pPriv->bg_b = (unsigned char) bg_color[2];
-
- pipe->context->error = IL_OK;
- return TRUE;
- }
|