ilrotate.c 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  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: ilrotate.c /main/4 1996/01/08 12:16:56 lehors $ */
  24. /* =============================================================================================================================
  25. /ilc/ilrotate.c : Images Library rotation routines.
  26. Date Mail-ID Description
  27. -------- ----------- -------------------------------------------------------------------
  28. 07/2/91 larsson Initial Coding.
  29. 11/4/91 voegelin moved ilBitReverseTable to ildata.c
  30. ============================================================================================================================= */
  31. #include "ilint.h"
  32. #include "ilpipelem.h"
  33. #include "ilerrors.h"
  34. #define LONGSZ 4
  35. #define WORDPOS 32
  36. #define BYTESIZE 8
  37. #define LEFT_BIT_ON 0x80000000
  38. #define ROT90 1
  39. #define ROT180 2
  40. #define ROT270 3
  41. typedef struct {
  42. int illinecount; /* running line count as pipe strips are executed */
  43. int ilXCenter; /* center of image width */
  44. int ilYCenter; /* center of image height */
  45. int ilRotateDstheight; /* destination height value saved to avoid strip sizes */
  46. int ilRotateSrcheight; /* src height value saved to avoid strip sizes */
  47. unsigned long dstMask; /* destination bit mask for 90 degree rotations (bitonal) */
  48. int rtype; /* rotation type used for setting dstMask */
  49. ilBool Lastbit; /* Flag indicating leftmost bit of current word is written */
  50. } ilRotatePriv, *ilRotatePrivptr;
  51. /* =============================================================================================================================
  52. ============================================================================================================================= */
  53. static ilError ilRotateInit(
  54. ilRotatePrivptr pPrivate,
  55. ilImageInfo *pSrcImage,
  56. ilImageInfo *pDstImage
  57. )
  58. {
  59. unsigned char *pdstline;
  60. ilImagePlaneInfo *pplane;
  61. int bitoff;
  62. /* Initialize counters */
  63. pPrivate->illinecount = 1;
  64. pPrivate->ilXCenter = pSrcImage->width/2;
  65. pPrivate->ilYCenter = pPrivate->ilRotateSrcheight/2;
  66. /* Zero out destination memory for bitonal format handling */
  67. pplane = &pDstImage->plane[0];
  68. pdstline = (unsigned char *) (pplane->pPixels);
  69. bitoff = (pplane->nBytesPerRow * 8) - pDstImage->width;
  70. if ( pPrivate->rtype == ROT90) pPrivate->dstMask = 1 << bitoff;
  71. else pPrivate->dstMask = LEFT_BIT_ON;
  72. if ( (long) pPrivate->dstMask < 0 ) pPrivate->Lastbit = TRUE;
  73. else pPrivate->Lastbit = FALSE;
  74. bzero((char *)pdstline,
  75. (pplane->nBytesPerRow * pPrivate->ilRotateDstheight));
  76. return IL_OK;
  77. }
  78. /* =============================================================================================================================
  79. ilRotate90BitonalExecute - 90 degree cw Rotation for images with bit per pixel format .
  80. ============================================================================================================================= */
  81. static ilError ilRotate90BitonalExecute (
  82. ilExecuteData *pData,
  83. unsigned long dstLine,
  84. unsigned long *pNLines
  85. )
  86. {
  87. unsigned long *psrc, *pdst, *psrcline, *pdstline;
  88. unsigned long srcnwords, dstnwords;
  89. ilImagePlaneInfo *pplane;
  90. int x, y, xoffset, lastcount;
  91. ilRotatePrivptr pPriv;
  92. unsigned long srcMask;
  93. unsigned long srcLong;
  94. ilBool shortwidth;
  95. if (*pNLines <= 0) return IL_OK;
  96. pplane = &pData->pSrcImage->plane[0];
  97. srcnwords = (pplane->nBytesPerRow + LONGSZ - 1)/LONGSZ;
  98. psrcline = (unsigned long *) (pplane->pPixels) + pData->srcLine * srcnwords;
  99. pplane = &pData->pDstImage->plane[0];
  100. dstnwords = (pplane->nBytesPerRow + LONGSZ - 1)/LONGSZ;
  101. pdstline = (unsigned long *) (pplane->pPixels) + dstLine * dstnwords;
  102. pPriv = (ilRotatePrivptr) pData->pPrivate;
  103. /* Rotate cw 90 degrees map (x,y) to (-y,x) about its center [ width-y, x ] */
  104. psrc = psrcline;
  105. srcLong = *psrc++;
  106. srcMask = LEFT_BIT_ON;
  107. shortwidth = (((srcnwords * WORDPOS) - pData->pSrcImage->width) > 0) ? TRUE : FALSE;
  108. lastcount = pPriv->illinecount - 1;
  109. for (y = pPriv->illinecount; y <= (lastcount + *pNLines); y++, pPriv->illinecount++ ) {
  110. xoffset = (pData->pDstImage->width - y)/WORDPOS;
  111. for ( x = 0; x < pData->pSrcImage->width; x++) {
  112. if ( srcLong & srcMask ) { /* Copy bit */
  113. pdst = pdstline + (dstnwords * x) + xoffset;
  114. *pdst = *pdst | pPriv->dstMask;
  115. }
  116. srcMask >>= 1; /* Shift to next pixel */
  117. if ( !srcMask ) {
  118. srcLong = *psrc++;
  119. srcMask = LEFT_BIT_ON;
  120. }
  121. }
  122. if ( !pPriv->Lastbit ) pPriv->dstMask <<= 1;
  123. else {
  124. pPriv->dstMask = 1;
  125. pPriv->Lastbit = FALSE;
  126. }
  127. if ( (long) pPriv->dstMask < 0 ) pPriv->Lastbit = TRUE;
  128. if(shortwidth) {
  129. srcLong = *psrc++;
  130. srcMask = LEFT_BIT_ON;
  131. }
  132. }
  133. /* No. of lines written is the destination height */
  134. if ( pPriv->illinecount <= pPriv->ilRotateSrcheight ) *pNLines = 0;
  135. else *pNLines = pPriv->ilRotateDstheight;
  136. return IL_OK;
  137. }
  138. /* =============================================================================================================================
  139. ilRotate180BitonalExecute - 180 degree Rotation for images with bit per pixel format .
  140. ============================================================================================================================= */
  141. static ilError ilRotate180BitonalExecute (
  142. ilExecuteData *pData,
  143. unsigned long dstLine,
  144. unsigned long *pNLines
  145. )
  146. {
  147. unsigned char *psrc, *pdst, *psrcline, *psrcbefore, *pdstline;
  148. unsigned char srcbyte;
  149. ilImagePlaneInfo *pplane;
  150. int x, y, lastcount, loffset, roffset;
  151. int srcnbytes, dstnbytes, widthbytes;
  152. ilRotatePrivptr pPriv;
  153. if (*pNLines <= 0) return IL_OK;
  154. pplane = &pData->pSrcImage->plane[0];
  155. srcnbytes = pplane->nBytesPerRow;
  156. psrcline = (unsigned char *) (pplane->pPixels) + pData->srcLine * srcnbytes;
  157. pplane = &pData->pDstImage->plane[0];
  158. dstnbytes = pplane->nBytesPerRow;
  159. pdstline = (unsigned char *) (pplane->pPixels) + dstLine * dstnbytes;
  160. pPriv = (ilRotatePrivptr) pData->pPrivate;
  161. loffset = pData->pSrcImage->width % BYTESIZE;
  162. roffset = BYTESIZE - loffset;
  163. widthbytes = pData->pSrcImage->width / BYTESIZE;
  164. if ( loffset > 0 ) widthbytes++;
  165. /* Rotate 180 degrees map (x,y) to (-x,-y) about its center [ width-x, height-y ] */
  166. lastcount = pPriv->illinecount - 1;
  167. for (y = pPriv->illinecount; y <= (lastcount + *pNLines); y++, pPriv->illinecount++ ) {
  168. psrc = psrcline + widthbytes - 1;
  169. psrcbefore = psrc - 1;
  170. pdst = pdstline + (dstnbytes * (pPriv->ilRotateSrcheight - y));
  171. if ( loffset == 0 )
  172. for ( x = 0; x < widthbytes; x++) *pdst++ = ilBitReverseTable[ *psrc-- ];
  173. else {
  174. for ( x = 0; x < widthbytes; x++) {
  175. if ( psrcbefore < psrcline ) srcbyte = (*psrc >> roffset);
  176. else srcbyte = (*psrcbefore << loffset) | (*psrc >> roffset);
  177. *pdst++ = ilBitReverseTable[srcbyte];
  178. psrc--;
  179. psrcbefore--;
  180. }
  181. }
  182. psrcline += srcnbytes;
  183. }
  184. /* No. of lines written is the destination height */
  185. if ( pPriv->illinecount <= pPriv->ilRotateSrcheight ) *pNLines = 0;
  186. else *pNLines = pPriv->ilRotateDstheight;
  187. return IL_OK;
  188. }
  189. /* =============================================================================================================================
  190. ilRotate270BitonalExecute - 270 degree cw Rotation for images with bit per pixel format .
  191. ============================================================================================================================= */
  192. static ilError ilRotate270BitonalExecute (
  193. ilExecuteData *pData,
  194. unsigned long dstLine,
  195. unsigned long *pNLines
  196. )
  197. {
  198. unsigned long *psrc, *pdst, *psrcline, *pdstline;
  199. unsigned long srcnwords, dstnwords;
  200. ilImagePlaneInfo *pplane;
  201. int x, y, xoffset, lastcount;
  202. ilRotatePrivptr pPriv;
  203. unsigned long srcMask, dstMask;
  204. unsigned long srcLong, dstLong;
  205. ilBool shortwidth;
  206. if (*pNLines <= 0) return IL_OK;
  207. pplane = &pData->pSrcImage->plane[0];
  208. srcnwords = (pplane->nBytesPerRow + LONGSZ - 1)/LONGSZ;
  209. psrcline = (unsigned long *) (pplane->pPixels) + pData->srcLine * srcnwords;
  210. pplane = &pData->pDstImage->plane[0];
  211. dstnwords = (pplane->nBytesPerRow + LONGSZ - 1)/LONGSZ;
  212. pdstline = (unsigned long *) (pplane->pPixels) + dstLine * dstnwords;
  213. pPriv = (ilRotatePrivptr) pData->pPrivate;
  214. /* Rotate cw 270 degrees map (x,y) to (y,-x) about its center [ y, height-x ] */
  215. psrc = psrcline;
  216. srcLong = *psrc++;
  217. srcMask = LEFT_BIT_ON;
  218. shortwidth = (((srcnwords * WORDPOS) - pData->pSrcImage->width) > 0) ? TRUE : FALSE;
  219. lastcount = pPriv->illinecount - 1;
  220. for (y = pPriv->illinecount; y <= (lastcount + *pNLines); y++, pPriv->illinecount++ ) {
  221. xoffset = (y - 1)/WORDPOS;
  222. for ( x = 1; x <= pData->pSrcImage->width; x++) {
  223. if ( srcLong & srcMask ) { /* perform copy */
  224. pdst = pdstline + (dstnwords * (pPriv->ilRotateDstheight - x)) + xoffset;
  225. *pdst = *pdst | pPriv->dstMask;
  226. }
  227. /* shift to next pixel */
  228. srcMask >>= 1;
  229. if ( !srcMask ) {
  230. srcLong = *psrc++;
  231. srcMask = LEFT_BIT_ON;
  232. }
  233. }
  234. pPriv->dstMask >>= 1;
  235. if( !pPriv->dstMask ) pPriv->dstMask = LEFT_BIT_ON;
  236. if(shortwidth) {
  237. srcLong = *psrc++;
  238. srcMask = LEFT_BIT_ON;
  239. }
  240. }
  241. /* No. of lines written is the destination height */
  242. if ( pPriv->illinecount <= pPriv->ilRotateSrcheight ) *pNLines = 0;
  243. else *pNLines = pPriv->ilRotateDstheight;
  244. return IL_OK;
  245. }
  246. /* =============================================================================================================================
  247. ilRotate903ByteExecute - 90 degree cw Rotation for images with 24 bits per pixel format .
  248. ============================================================================================================================= */
  249. static ilError ilRotate903ByteExecute (
  250. ilExecuteData *pData,
  251. unsigned long dstLine,
  252. unsigned long *pNLines
  253. )
  254. {
  255. unsigned char *psrc, *pdst, *psrcline, *pdstline;
  256. unsigned long srcnbytes, dstnbytes;
  257. ilImagePlaneInfo *pplane;
  258. int x, y, xoffset, lastcount;
  259. ilRotatePrivptr pPriv;
  260. if (*pNLines <= 0) return IL_OK;
  261. pplane = &pData->pSrcImage->plane[0];
  262. srcnbytes = pplane->nBytesPerRow;
  263. psrcline = (unsigned char *) (pplane->pPixels) + pData->srcLine * srcnbytes;
  264. pplane = &pData->pDstImage->plane[0];
  265. dstnbytes = pplane->nBytesPerRow;
  266. pdstline = (unsigned char *) (pplane->pPixels) + dstLine * dstnbytes;
  267. pPriv = (ilRotatePrivptr) pData->pPrivate;
  268. /* Rotate cw 90 degrees map (x,y) to (-y,x) about its center [ width-y, x ] */
  269. lastcount = pPriv->illinecount - 1;
  270. for (y = pPriv->illinecount; y <= (lastcount + *pNLines); y++, pPriv->illinecount++ ) {
  271. psrc = psrcline;
  272. xoffset = (pData->pDstImage->width - y) * 3;
  273. for ( x = 0; x < pData->pSrcImage->width; x++) {
  274. pdst = pdstline + (dstnbytes * x) + xoffset;
  275. *pdst++ = *psrc++;
  276. *pdst++ = *psrc++;
  277. *pdst = *psrc++;
  278. }
  279. psrcline += srcnbytes;
  280. }
  281. /* No. of lines written is the destination height */
  282. if ( pPriv->illinecount <= pPriv->ilRotateSrcheight ) *pNLines = 0;
  283. else *pNLines = pPriv->ilRotateDstheight;
  284. return IL_OK;
  285. }
  286. /* =============================================================================================================================
  287. ilRotate1803ByteExecute - 180 degree Rotation for images with 24 bits per pixel format .
  288. ============================================================================================================================= */
  289. static ilError ilRotate1803ByteExecute (
  290. ilExecuteData *pData,
  291. unsigned long dstLine,
  292. unsigned long *pNLines
  293. )
  294. {
  295. unsigned char *psrc, *pdst, *psrcline, *pdstline;
  296. unsigned long srcnbytes, dstnbytes;
  297. ilImagePlaneInfo *pplane;
  298. int x, y, xoffset, lastcount;
  299. ilRotatePrivptr pPriv;
  300. if (*pNLines <= 0) return IL_OK;
  301. pplane = &pData->pSrcImage->plane[0];
  302. srcnbytes = pplane->nBytesPerRow;
  303. psrcline = (unsigned char *) (pplane->pPixels) + pData->srcLine * srcnbytes;
  304. pplane = &pData->pDstImage->plane[0];
  305. dstnbytes = pplane->nBytesPerRow;
  306. pdstline = (unsigned char *) (pplane->pPixels) + dstLine * dstnbytes;
  307. pPriv = (ilRotatePrivptr) pData->pPrivate;
  308. /* Rotate 180 degrees map (x,y) to (-x,-y) about its center [ width-x, height-y ] */
  309. xoffset = pData->pSrcImage->width * 3;
  310. lastcount = pPriv->illinecount - 1;
  311. for (y = pPriv->illinecount; y <= (lastcount + *pNLines); y++, pPriv->illinecount++ ) {
  312. psrc = psrcline + 2;
  313. pdst = pdstline + (dstnbytes * (pPriv->ilRotateSrcheight - y)) + xoffset - 1;
  314. for ( x = 0; x < pData->pSrcImage->width; x++, psrc += 5) {
  315. *pdst-- = *psrc--;
  316. *pdst-- = *psrc--;
  317. *pdst-- = *psrc;
  318. }
  319. psrcline += srcnbytes;
  320. }
  321. /* No. of lines written is the destination height */
  322. if ( pPriv->illinecount <= pPriv->ilRotateSrcheight ) *pNLines = 0;
  323. else *pNLines = pPriv->ilRotateDstheight;
  324. return IL_OK;
  325. }
  326. /* =============================================================================================================================
  327. ilRotate2703ByteExecute - 270 degree cw Rotation for images with 24 bits per pixel format .
  328. ============================================================================================================================= */
  329. static ilError ilRotate2703ByteExecute (
  330. ilExecuteData *pData,
  331. unsigned long dstLine,
  332. unsigned long *pNLines
  333. )
  334. {
  335. unsigned char *psrc, *pdst, *psrcline, *pdstline;
  336. unsigned long srcnbytes, dstnbytes;
  337. ilImagePlaneInfo *pplane;
  338. int x, y, lastcount, xoffset;
  339. ilRotatePrivptr pPriv;
  340. if (*pNLines <= 0) return IL_OK;
  341. pplane = &pData->pSrcImage->plane[0];
  342. srcnbytes = pplane->nBytesPerRow;
  343. psrcline = (unsigned char *) (pplane->pPixels) + pData->srcLine * srcnbytes;
  344. pplane = &pData->pDstImage->plane[0];
  345. dstnbytes = pplane->nBytesPerRow;
  346. pdstline = (unsigned char *) (pplane->pPixels) + dstLine * dstnbytes;
  347. pPriv = (ilRotatePrivptr) pData->pPrivate;
  348. /* Rotate cw 270 degrees map (x,y) to (y,-x) about its center [ y, height-x ] */
  349. lastcount = pPriv->illinecount - 1;
  350. for (y = pPriv->illinecount; y <= (lastcount + *pNLines); y++, pPriv->illinecount++ ) {
  351. psrc = psrcline;
  352. xoffset = 3 * (y-1);
  353. for ( x = 1; x <= pData->pSrcImage->width; x++) {
  354. pdst = pdstline + (dstnbytes * (pPriv->ilRotateDstheight - x)) + xoffset;
  355. *pdst++ = *psrc++;
  356. *pdst++ = *psrc++;
  357. *pdst = *psrc++;
  358. }
  359. psrcline += srcnbytes;
  360. }
  361. /* No. of lines written is the destination height */
  362. if ( pPriv->illinecount <= pPriv->ilRotateSrcheight ) *pNLines = 0;
  363. else *pNLines = pPriv->ilRotateDstheight;
  364. return IL_OK;
  365. }
  366. /* =============================================================================================================================
  367. ilRotate90ByteExecute - 90 degree cw Rotation for images with byte per pixel format .
  368. ============================================================================================================================= */
  369. static ilError ilRotate90ByteExecute (
  370. ilExecuteData *pData,
  371. unsigned long dstLine,
  372. unsigned long *pNLines
  373. )
  374. {
  375. unsigned char *psrc, *pdst, *psrcline, *pdstline;
  376. unsigned long srcnbytes, dstnbytes;
  377. ilImagePlaneInfo *pplane;
  378. int x, y, xoffset, lastcount;
  379. unsigned int dstrowpixels;
  380. ilRotatePrivptr pPriv;
  381. if (*pNLines <= 0) return IL_OK;
  382. pplane = &pData->pSrcImage->plane[0];
  383. srcnbytes = pplane->nBytesPerRow;
  384. psrcline = (unsigned char *) (pplane->pPixels) + pData->srcLine * srcnbytes;
  385. pplane = &pData->pDstImage->plane[0];
  386. dstnbytes = pplane->nBytesPerRow;
  387. pdstline = (unsigned char *) (pplane->pPixels) + dstLine * dstnbytes;
  388. pPriv = (ilRotatePrivptr) pData->pPrivate;
  389. /* Rotate cw 90 degrees map (x,y) to (-y,x) about its center [ width-y, x ] */
  390. lastcount = pPriv->illinecount - 1;
  391. for (y = pPriv->illinecount; y <= (lastcount + *pNLines); y++, pPriv->illinecount++ ) {
  392. psrc = psrcline;
  393. xoffset = pData->pDstImage->width - y;
  394. for ( x = 0; x < pData->pSrcImage->width; x++) {
  395. pdst = pdstline + (dstnbytes * x) + xoffset;
  396. *pdst = *psrc++;
  397. }
  398. psrcline += srcnbytes;
  399. }
  400. /* No. of lines written is the destination height */
  401. if ( pPriv->illinecount <= pPriv->ilRotateSrcheight ) *pNLines = 0;
  402. else *pNLines = pPriv->ilRotateDstheight;
  403. return IL_OK;
  404. }
  405. /* =============================================================================================================================
  406. ilRotate180ByteExecute - 180 degree Rotation for images with byte per pixel format .
  407. ============================================================================================================================= */
  408. static ilError ilRotate180ByteExecute (
  409. ilExecuteData *pData,
  410. unsigned long dstLine,
  411. unsigned long *pNLines
  412. )
  413. {
  414. unsigned char *psrc, *pdst, *psrcline, *pdstline;
  415. unsigned long srcnbytes, dstnbytes;
  416. ilImagePlaneInfo *pplane;
  417. int x, y, lastcount;
  418. ilRotatePrivptr pPriv;
  419. if (*pNLines <= 0) return IL_OK;
  420. pplane = &pData->pSrcImage->plane[0];
  421. srcnbytes = pplane->nBytesPerRow;
  422. psrcline = (unsigned char *) (pplane->pPixels) + pData->srcLine * srcnbytes;
  423. pplane = &pData->pDstImage->plane[0];
  424. dstnbytes = pplane->nBytesPerRow;
  425. pdstline = (unsigned char *) (pplane->pPixels) + dstLine * dstnbytes;
  426. pPriv = (ilRotatePrivptr) pData->pPrivate;
  427. /* Rotate 180 degrees map (x,y) to (-x,-y) about its center [ width-x, height-y ] */
  428. lastcount = pPriv->illinecount - 1;
  429. for (y = pPriv->illinecount; y <= (lastcount + *pNLines); y++, pPriv->illinecount++ ) {
  430. psrc = psrcline;
  431. pdst = pdstline + (dstnbytes * (pPriv->ilRotateSrcheight - y)) + srcnbytes - 1;
  432. for ( x = 0; x < pData->pSrcImage->width; x++) *pdst-- = *psrc++;
  433. psrcline += srcnbytes;
  434. }
  435. /* No. of lines written is the destination height */
  436. if ( pPriv->illinecount <= pPriv->ilRotateSrcheight ) *pNLines = 0;
  437. else *pNLines = pPriv->ilRotateDstheight;
  438. return IL_OK;
  439. }
  440. /* =============================================================================================================================
  441. ilRotate270ByteExecute - 270 degree cw Rotation for images with byte per pixel format .
  442. ============================================================================================================================= */
  443. static ilError ilRotate270ByteExecute (
  444. ilExecuteData *pData,
  445. unsigned long dstLine,
  446. unsigned long *pNLines
  447. )
  448. {
  449. unsigned char *psrc, *pdst, *psrcline, *pdstline;
  450. unsigned long srcnbytes, dstnbytes;
  451. ilImagePlaneInfo *pplane;
  452. int x, y, lastcount, xoffset;
  453. ilRotatePrivptr pPriv;
  454. if (*pNLines <= 0) return IL_OK;
  455. pplane = &pData->pSrcImage->plane[0];
  456. srcnbytes = pplane->nBytesPerRow;
  457. psrcline = (unsigned char *) (pplane->pPixels) + pData->srcLine * srcnbytes;
  458. pplane = &pData->pDstImage->plane[0];
  459. dstnbytes = pplane->nBytesPerRow;
  460. pdstline = (unsigned char *) (pplane->pPixels) + dstLine * dstnbytes;
  461. pPriv = (ilRotatePrivptr) pData->pPrivate;
  462. /* Rotate cw 270 degrees map (x,y) to (y,-x) about its center [ y, height-x ] */
  463. lastcount = pPriv->illinecount - 1;
  464. for (y = pPriv->illinecount; y <= (lastcount + *pNLines); y++, pPriv->illinecount++ ) {
  465. psrc = psrcline;
  466. for ( x = 1; x <= pData->pSrcImage->width; x++) {
  467. pdst = pdstline + (dstnbytes * (pPriv->ilRotateDstheight - x)) + (y-1);
  468. *pdst = *psrc++;
  469. }
  470. psrcline += srcnbytes;
  471. }
  472. /* No. of lines written is the destination height */
  473. if ( pPriv->illinecount <= pPriv->ilRotateSrcheight ) *pNLines = 0;
  474. else *pNLines = pPriv->ilRotateDstheight;
  475. return IL_OK;
  476. }
  477. /* =============================================================================================================================
  478. ilRotate90 - Add a rotate filter to an existing pipe for 90 degree rotations - checking
  479. for format types and doing an explicit conversion if necessary. Positive factors
  480. cause clockwise rotations - negative counter clockwise.
  481. ============================================================================================================================= */
  482. ilBool ilRotate90 (
  483. ilPipe pipe,
  484. int factor
  485. )
  486. {
  487. unsigned int state;
  488. ilPipeInfo info;
  489. ilRotatePrivptr pPriv;
  490. ilDstElementData dstdata;
  491. ilImageDes imdes;
  492. ilImageFormat imformat;
  493. ilBool convert;
  494. ilBool bitonal;
  495. ilBool cw;
  496. unsigned int rtype;
  497. #define PIPE_FLAGS
  498. /* Get ptr to pipe info and check state */
  499. state = ilGetPipeInfo(pipe, TRUE, &info, &imdes, &imformat);
  500. if(state != IL_PIPE_FORMING) {
  501. if (!pipe->context->error)
  502. ilDeclarePipeInvalid(pipe, IL_ERROR_PIPE_STATE);
  503. return FALSE;
  504. }
  505. bitonal = FALSE;
  506. /* Check for valid Formats */
  507. convert = FALSE;
  508. switch (imdes.nSamplesPerPixel) {
  509. case 3: /* RGB or YUV */
  510. if(imformat.sampleOrder != IL_SAMPLE_PIXELS) {
  511. imformat.sampleOrder = IL_SAMPLE_PIXELS;
  512. convert = TRUE;
  513. }
  514. if((imformat.nBitsPerSample[0] != 8) ||
  515. (imformat.nBitsPerSample[1] != 8) ||
  516. (imformat.nBitsPerSample[2] != 8)) {
  517. imformat.nBitsPerSample[0] = 8;
  518. imformat.nBitsPerSample[1] = 8;
  519. imformat.nBitsPerSample[2] = 8;
  520. convert = TRUE;
  521. }
  522. break;
  523. case 1:
  524. switch (imformat.nBitsPerSample[0]) {
  525. case 8: /* Byte per pixel */
  526. break;
  527. case 1: /* Bitonal */
  528. bitonal = TRUE;
  529. if (imformat.rowBitAlign != 32) {
  530. imformat.rowBitAlign = 32;
  531. convert = TRUE;
  532. }
  533. break;
  534. default: /* something other than 1 - try 8 */
  535. imformat.nBitsPerSample[0] = 8;
  536. convert = TRUE;
  537. }
  538. break;
  539. default:
  540. return ilDeclarePipeInvalid(pipe, IL_ERROR_NOT_IMPLEMENTED);
  541. }
  542. if(convert) {
  543. if (!ilConvert(pipe, &imdes, &imformat, 0, NULL))
  544. return FALSE;
  545. ilGetPipeInfo (pipe, FALSE, &info, (ilImageDes *)NULL, (ilImageFormat *)NULL);
  546. }
  547. /* Determine rotation type */
  548. cw = (factor > 0) ? TRUE : FALSE;
  549. switch ( abs(factor) % 4) {
  550. case 0:
  551. pipe->context->error = IL_OK; /* 0 Rotation - nothing required. */
  552. return TRUE;
  553. case 1:
  554. rtype = (cw) ? ROT90 : ROT270;
  555. break;
  556. case 2:
  557. rtype = ROT180;
  558. break;
  559. case 3:
  560. rtype = (cw) ? ROT270 : ROT90;
  561. }
  562. dstdata.producerObject = (ilObject) NULL;
  563. dstdata.pDes = (ilImageDes *) NULL;
  564. dstdata.pFormat = (ilImageFormat *) NULL;
  565. dstdata.pPalette = info.pPalette;
  566. /* flip-flop image if necessary */
  567. if(rtype != ROT180) {
  568. dstdata.width = info.height;
  569. dstdata.height = info.width;
  570. }
  571. else {
  572. dstdata.width = info.width;
  573. dstdata.height = info.height;
  574. }
  575. /* set output strip height */
  576. dstdata.stripHeight = dstdata.height;
  577. dstdata.constantStrip = TRUE;
  578. switch (imdes.nSamplesPerPixel) {
  579. case 3:
  580. switch (rtype) {
  581. case ROT90:
  582. pPriv = (ilRotatePrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilRotatePriv), IL_ADD_PIPE_HOLD_DST, (ilSrcElementData *) NULL,
  583. &dstdata, ilRotateInit, IL_NPF, IL_NPF, ilRotate903ByteExecute, 0);
  584. break;
  585. case ROT180:
  586. pPriv = (ilRotatePrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilRotatePriv), IL_ADD_PIPE_HOLD_DST, (ilSrcElementData *) NULL,
  587. &dstdata, ilRotateInit, IL_NPF, IL_NPF, ilRotate1803ByteExecute, 0);
  588. break;
  589. case ROT270:
  590. pPriv = (ilRotatePrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilRotatePriv), IL_ADD_PIPE_HOLD_DST, (ilSrcElementData *) NULL,
  591. &dstdata, ilRotateInit, IL_NPF, IL_NPF, ilRotate2703ByteExecute, 0);
  592. break;
  593. }
  594. break;
  595. case 1:
  596. if(bitonal) {
  597. switch (rtype) {
  598. case ROT90:
  599. pPriv = (ilRotatePrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilRotatePriv), IL_ADD_PIPE_HOLD_DST, (ilSrcElementData *) NULL,
  600. &dstdata, ilRotateInit, IL_NPF, IL_NPF, ilRotate90BitonalExecute, 0);
  601. break;
  602. case ROT180:
  603. pPriv = (ilRotatePrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilRotatePriv), IL_ADD_PIPE_HOLD_DST, (ilSrcElementData *) NULL,
  604. &dstdata, ilRotateInit, IL_NPF, IL_NPF, ilRotate180BitonalExecute, 0);
  605. break;
  606. case ROT270:
  607. pPriv = (ilRotatePrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilRotatePriv), IL_ADD_PIPE_HOLD_DST, (ilSrcElementData *) NULL,
  608. &dstdata, ilRotateInit, IL_NPF, IL_NPF, ilRotate270BitonalExecute, 0);
  609. break;
  610. }
  611. }
  612. else {
  613. switch (rtype) {
  614. case ROT90:
  615. pPriv = (ilRotatePrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilRotatePriv), IL_ADD_PIPE_HOLD_DST, (ilSrcElementData *) NULL,
  616. &dstdata, ilRotateInit, IL_NPF, IL_NPF, ilRotate90ByteExecute, 0);
  617. break;
  618. case ROT180:
  619. pPriv = (ilRotatePrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilRotatePriv), IL_ADD_PIPE_HOLD_DST, (ilSrcElementData *) NULL,
  620. &dstdata, ilRotateInit, IL_NPF, IL_NPF, ilRotate180ByteExecute, 0);
  621. break;
  622. case ROT270:
  623. pPriv = (ilRotatePrivptr) ilAddPipeElement(pipe, IL_FILTER, sizeof(ilRotatePriv), IL_ADD_PIPE_HOLD_DST, (ilSrcElementData *) NULL,
  624. &dstdata, ilRotateInit, IL_NPF, IL_NPF, ilRotate270ByteExecute, 0);
  625. break;
  626. }
  627. }
  628. }
  629. if(!pPriv)
  630. return FALSE;
  631. /* Save away true heights */
  632. pPriv->ilRotateDstheight = dstdata.height;
  633. pPriv->ilRotateSrcheight = info.height;
  634. pPriv->rtype = rtype;
  635. pipe->context->error = IL_OK;
  636. return TRUE;
  637. }