2
0

ilhplrotate.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* $XConsortium: ilhplrotate.c /main/3 1995/10/23 15:48:20 rswiston $ */
  24. /**---------------------------------------------------------------------
  25. ***
  26. *** (c)Copyright 1991 Hewlett-Packard Co.
  27. ***
  28. *** RESTRICTED RIGHTS LEGEND
  29. *** Use, duplication, or disclosure by the U.S. Government is subject to
  30. *** restrictions as set forth in sub-paragraph (c)(1)(ii) of the Rights in
  31. *** Technical Data and Computer Software clause in DFARS 252.227-7013.
  32. *** Hewlett-Packard Company
  33. *** 3000 Hanover Street
  34. *** Palo Alto, CA 94304 U.S.A.
  35. *** Rights for non-DOD U.S. Government Departments and Agencies are as set
  36. *** forth in FAR 52.227-19(c)(1,2).
  37. ***
  38. ***-------------------------------------------------------------------*/
  39. /* =============================================================================================================================
  40. /ilc/ilhplrotate.c : Images Library arbitrary rotation routines. using HP-LABs
  41. image rotation code
  42. ============================================================================================================================= */
  43. #include "ilint.h"
  44. #include "ilpipelem.h"
  45. #include "ilerrors.h"
  46. #include "ilhplrotation.h"
  47. typedef struct {
  48. DATA_IN_PTR data_in; /* pointer to where to put input data */
  49. DATA_OUT_PTR buf;
  50. ilBool restart; /* TRUE on pipe re-execution */
  51. short in_w; /* Arguments to IR_Rotate_Image_Begin */
  52. short in_h;
  53. short in_nSPP;
  54. short mode;
  55. float degrees;
  56. unsigned char bg_r, bg_g, bg_b;
  57. } ilRotatePriv, *ilRotatePrivptr;
  58. /* =============================================================================================================================
  59. ilRotateInit - Init for Rotation for images
  60. ============================================================================================================================= */
  61. static ilError ilRotateInit2(
  62. ilRotatePrivptr p,
  63. ilImageInfo *pSrcImage,
  64. ilImageInfo *pDstImage
  65. )
  66. {
  67. DATA_IN_PTR data_in;
  68. DATA_OUT_PTR buf;
  69. short out_w, out_h;
  70. /* Re-Initialize rotation code if necessary */
  71. if (p->restart) {
  72. data_in = _il_Rotate_Image_Begin (p->in_w , p->in_h, p->in_nSPP, p->mode,
  73. p->degrees, p->bg_r, p->bg_g, p->bg_b, &out_w, &out_h);
  74. buf = (DATA_OUT_PTR) malloc(out_w * p->in_nSPP);
  75. if (!buf) {
  76. return FALSE;
  77. }
  78. p->buf = buf;
  79. p->data_in = data_in;
  80. }
  81. else
  82. p->restart = TRUE;
  83. return IL_OK;
  84. }
  85. /* =============================================================================================================================
  86. ilRotateCleanup - Cleanup for Rotation for images
  87. ============================================================================================================================= */
  88. static ilError ilRotateCleanup (
  89. ilRotatePrivptr pPriv,
  90. ilBool aborting
  91. )
  92. {
  93. free (pPriv->buf);
  94. _il_Rotate_Image_End();
  95. return IL_OK;
  96. }
  97. /* =============================================================================================================================
  98. ilRotateExecute - Rotation for images
  99. ============================================================================================================================= */
  100. static ilError ilRotateExecute (
  101. ilExecuteData *pData,
  102. unsigned long dstLine,
  103. unsigned long *pNLines
  104. )
  105. {
  106. unsigned char *psrc, *pdst, *psrcline, *pdstline;
  107. unsigned long srcnbytes, dstnbytes;
  108. ilImagePlaneInfo *pplane;
  109. ilRotatePrivptr pPriv;
  110. int nrows, nlines, nlinesout;
  111. if (*pNLines <= 0) return IL_OK;
  112. pplane = &pData->pSrcImage->plane[0];
  113. srcnbytes = pplane->nBytesPerRow;
  114. psrcline = (unsigned char *) (pplane->pPixels) + pData->srcLine * srcnbytes;
  115. pplane = &pData->pDstImage->plane[0];
  116. dstnbytes = pplane->nBytesPerRow;
  117. pdstline = (unsigned char *) (pplane->pPixels) + dstLine * dstnbytes;
  118. pPriv = (ilRotatePrivptr) pData->pPrivate;
  119. nlines = *pNLines;
  120. nlinesout = 0;
  121. for (nlines = *pNLines; nlines > 0; nlines--){
  122. bcopy ((char *) psrcline, (char *) pPriv->data_in, (int) srcnbytes);
  123. for (nrows = _il_Rotate_Send_Row(&pPriv->data_in);
  124. nrows > 0; --nrows) {
  125. _il_Rotate_Get_Row(pPriv->buf);
  126. bcopy ((char *) pPriv->buf, (char *) pdstline, (int) dstnbytes);
  127. pdstline += dstnbytes;
  128. nlinesout++;
  129. }
  130. psrcline += srcnbytes;
  131. }
  132. *pNLines = nlinesout;
  133. return IL_OK;
  134. }
  135. /* =============================================================================================================================
  136. ilRotate - Add a rotate filter to an existing pipe for 0 - 90 degree rotations - checking
  137. for format types and doing an explicit conversion if necessary. Positive factors
  138. cause clockwise rotations - negative counter clockwise.
  139. ============================================================================================================================= */
  140. ilBool ilRotate(
  141. ilPipe pipe,
  142. int degrees,
  143. int interpMode,
  144. unsigned long bg_color[]
  145. )
  146. {
  147. unsigned int state;
  148. ilPipeInfo info;
  149. ilRotatePrivptr pPriv;
  150. ilDstElementData dstdata;
  151. ilImageDes imdes;
  152. ilImageFormat imformat;
  153. ilBool convert;
  154. unsigned int rtype;
  155. short out_w, out_h, nrows;
  156. DATA_IN_PTR data_in;
  157. DATA_OUT_PTR buf;
  158. #define PIPE_FLAGS
  159. /* Get ptr to pipe info and check state */
  160. state = ilGetPipeInfo(pipe, TRUE, &info, &imdes, &imformat);
  161. if(state != IL_PIPE_FORMING) {
  162. if (!pipe->context->error)
  163. ilDeclarePipeInvalid(pipe, IL_ERROR_PIPE_STATE);
  164. return FALSE;
  165. }
  166. /* Check for valid Formats */
  167. convert = FALSE;
  168. switch (imdes.nSamplesPerPixel) {
  169. case 3: /* RGB or YUV */
  170. if(imformat.sampleOrder != IL_SAMPLE_PIXELS) {
  171. imformat.sampleOrder = IL_SAMPLE_PIXELS;
  172. convert = TRUE;
  173. }
  174. if((imformat.nBitsPerSample[0] != 8) ||
  175. (imformat.nBitsPerSample[1] != 8) ||
  176. (imformat.nBitsPerSample[2] != 8)) {
  177. imformat.nBitsPerSample[0] = 8;
  178. imformat.nBitsPerSample[1] = 8;
  179. imformat.nBitsPerSample[2] = 8;
  180. convert = TRUE;
  181. }
  182. break;
  183. case 1:
  184. switch (imformat.nBitsPerSample[0]) {
  185. case 8: /* Byte per pixel */
  186. if (imdes.type == IL_PALETTE &&
  187. interpMode != IL_ROTATE_SIMPLE) {
  188. imdes.type = IL_RGB;
  189. convert = TRUE;
  190. }
  191. break;
  192. case 1: /* Bitonal */
  193. return ilDeclarePipeInvalid
  194. (pipe, IL_ERROR_NOT_IMPLEMENTED);
  195. break;
  196. default: /* something other than 1 - try 8 */
  197. imformat.nBitsPerSample[0] = 8;
  198. convert = TRUE;
  199. }
  200. break;
  201. default:
  202. return ilDeclarePipeInvalid(pipe, IL_ERROR_NOT_IMPLEMENTED);
  203. }
  204. if(convert) {
  205. if (!ilConvert(pipe, &imdes, &imformat, 0, NULL))
  206. return FALSE;
  207. ilGetPipeInfo (pipe, FALSE, &info, (ilImageDes *)NULL, (ilImageFormat *)NULL);
  208. }
  209. /* Determine rotation type */
  210. degrees %= 360;
  211. if (degrees < 0) degrees += 360;
  212. /*
  213. * temporarily, special code can only handle 0 - 90 rotation
  214. * also, code rotates ccw, but we want to rotate clockwise.
  215. */
  216. if (!ilRotate90(pipe, (degrees+89)/90)) return FALSE;
  217. ilGetPipeInfo (pipe, FALSE, &info, (ilImageDes *)NULL, (ilImageFormat *)NULL);
  218. degrees = 90 - (degrees % 90);
  219. /* check if 90 deg rotations is sufficient */
  220. if (degrees == 90) {pipe->context->error = IL_OK; return TRUE;}
  221. data_in = _il_Rotate_Image_Begin ( (short) info.width, (short) info.height,
  222. (short) imdes.nSamplesPerPixel, (short) interpMode,
  223. (float) degrees,
  224. (unsigned char) bg_color[0], (unsigned char) bg_color[1], (unsigned char) bg_color[2],
  225. &out_w, &out_h);
  226. dstdata.producerObject = (ilObject) NULL;
  227. dstdata.pDes = (ilImageDes *) NULL;
  228. dstdata.pFormat = (ilImageFormat *) NULL;
  229. dstdata.pPalette = info.pPalette;
  230. dstdata.width = out_w;
  231. dstdata.height = out_h;
  232. /* set output strip height */
  233. dstdata.stripHeight = dstdata.height;
  234. dstdata.constantStrip = FALSE;
  235. pPriv = (ilRotatePrivptr) ilAddPipeElement (pipe, IL_FILTER,
  236. sizeof(ilRotatePriv), IL_ADD_PIPE_HOLD_DST,
  237. (ilSrcElementData *) NULL, &dstdata, ilRotateInit2,
  238. ilRotateCleanup, IL_NPF, ilRotateExecute, 0);
  239. if(!pPriv)
  240. return FALSE;
  241. buf = (DATA_OUT_PTR) malloc(out_w * (short) imdes.nSamplesPerPixel);
  242. if (!buf) {
  243. pipe->context->error = IL_ERROR_MALLOC;
  244. free(pPriv);
  245. return FALSE;
  246. }
  247. pPriv->buf = buf;
  248. pPriv->data_in = data_in;
  249. pPriv->restart = FALSE;
  250. /* Arguments to IR_Rotate_Image_Begin */
  251. pPriv->in_w = (short) info.width ;
  252. pPriv->in_h = (short) info.height;
  253. pPriv->in_nSPP = (short) imdes.nSamplesPerPixel;
  254. pPriv->mode = (short) interpMode;
  255. pPriv->degrees = (float) degrees;
  256. pPriv->bg_r = (unsigned char) bg_color[0];
  257. pPriv->bg_g = (unsigned char) bg_color[1];
  258. pPriv->bg_b = (unsigned char) bg_color[2];
  259. pipe->context->error = IL_OK;
  260. return TRUE;
  261. }