ilformat.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
  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: ilformat.c /main/5 1996/06/19 12:21:36 ageorge $ */
  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. /* /ilc/ilformat.c : Reference by ilConvert in /ilc/ilconvert.c .
  40. Contains pipe functions and an ilFormatRec, which points to the functions
  41. and defines how the formatter should be added by ilConvert().
  42. */
  43. #include "ilint.h"
  44. #include "ilpipelem.h"
  45. #include "ilconvert.h"
  46. #include "ilerrors.h"
  47. /* ------------------------- ilExecuteBitAlign ------------------------- */
  48. /* Execute() function: convert the given # of src lines, changing
  49. the rowBitAlign. Easy; just bcopy each line, bump by src/dstRowBytes,
  50. which presumably are different because of different bit alignment.
  51. */
  52. static ilError ilExecuteBitAlign (
  53. ilExecuteData *pData,
  54. long dstLine,
  55. long *pNLines
  56. )
  57. {
  58. ilImagePlaneInfo *pImagePlane;
  59. long srcRowBytes, dstRowBytes;
  60. long nLinesM1, nBytes;
  61. ilPtr pSrc, pDst;
  62. /* Use bcopy to copy each line; copy the lesser of the src/dstRowBytes.
  63. Exit if no lines or pixels.
  64. */
  65. pImagePlane = &pData->pSrcImage->plane[0];
  66. srcRowBytes = pImagePlane->nBytesPerRow;
  67. pSrc = pImagePlane->pPixels + pData->srcLine * srcRowBytes;
  68. pImagePlane = &pData->pDstImage->plane[0];
  69. dstRowBytes = pImagePlane->nBytesPerRow;
  70. pDst = pImagePlane->pPixels + dstLine * dstRowBytes;
  71. nBytes = (srcRowBytes < dstRowBytes) ? srcRowBytes : dstRowBytes;
  72. if (nBytes <= 0)
  73. return IL_OK;
  74. nLinesM1 = *pNLines;
  75. if (nLinesM1 <= 0)
  76. return IL_OK;
  77. nLinesM1--;
  78. do {
  79. bcopy ((char *)pSrc, (char *)pDst, nBytes);
  80. pSrc += srcRowBytes;
  81. pDst += dstRowBytes;
  82. } while (--nLinesM1 >= 0);
  83. return IL_OK;
  84. }
  85. /* Table exported to ilConvert(), declared in /ilc/ilconvert.h .
  86. */
  87. IL_PRIVATE ilFormatRec _ilFormatRowBitAlign = {
  88. IL_NPF, /* AddElement() */
  89. 0, /* nBytesPrivate */
  90. IL_NPF, /* Init() */
  91. IL_NPF, /* Cleanup() */
  92. IL_NPF, /* Destroy() */
  93. ilExecuteBitAlign /* Execute() */
  94. };
  95. /* ------------------------- ilExecute8Bit3PlaneToPixel ------------------------- */
  96. /* Execute() function: convert the given # of src lines, changing
  97. format from planar to pixel. Handles 3 planes of 8 bits/pixel only.
  98. */
  99. static ilError ilExecute8Bit3PlaneToPixel (
  100. ilExecuteData *pData,
  101. long dstLine,
  102. long *pNLines
  103. )
  104. {
  105. ilImagePlaneInfo *pImagePlane;
  106. long src0RowBytes, src1RowBytes, src2RowBytes, dstRowBytes;
  107. long nPixelsM1Init;
  108. long nLinesM1, nPixelsM1;
  109. ilPtr pSrc0Line, pSrc1Line, pSrc2Line, pDstLine;
  110. ilPtr pSrc0, pSrc1, pSrc2, pDst;
  111. /* Get ptr to start of 3 src planes and to dst */
  112. pImagePlane = pData->pSrcImage->plane;
  113. src0RowBytes = pImagePlane->nBytesPerRow;
  114. pSrc0Line = pImagePlane->pPixels + pData->srcLine * src0RowBytes;
  115. pImagePlane++;
  116. src1RowBytes = pImagePlane->nBytesPerRow;
  117. pSrc1Line = pImagePlane->pPixels + pData->srcLine * src1RowBytes;
  118. pImagePlane++;
  119. src2RowBytes = pImagePlane->nBytesPerRow;
  120. pSrc2Line = pImagePlane->pPixels + pData->srcLine * src2RowBytes;
  121. pImagePlane = pData->pDstImage->plane;
  122. dstRowBytes = pImagePlane->nBytesPerRow;
  123. pDstLine = pImagePlane->pPixels + dstLine * dstRowBytes;
  124. /* Exit if no lines or pixels. */
  125. nPixelsM1Init = pData->pSrcImage->width;
  126. if (nPixelsM1Init <= 0)
  127. return IL_OK;
  128. nPixelsM1Init--;
  129. nLinesM1 = *pNLines;
  130. if (nLinesM1 <= 0)
  131. return IL_OK;
  132. nLinesM1--;
  133. do {
  134. pSrc0 = pSrc0Line;
  135. pSrc0Line += src0RowBytes;
  136. pSrc1 = pSrc1Line;
  137. pSrc1Line += src1RowBytes;
  138. pSrc2 = pSrc2Line;
  139. pSrc2Line += src2RowBytes;
  140. pDst = pDstLine;
  141. pDstLine += dstRowBytes;
  142. nPixelsM1 = nPixelsM1Init;
  143. do {
  144. *pDst++ = *pSrc0++;
  145. *pDst++ = *pSrc1++;
  146. *pDst++ = *pSrc2++;
  147. } while (--nPixelsM1 >= 0);
  148. } while (--nLinesM1 >= 0);
  149. return IL_OK;
  150. }
  151. /* Table exported to ilConvert(), declared in /ilc/ilconvert.h .
  152. */
  153. IL_PRIVATE ilFormatRec _ilFormat8Bit3PlaneToPixel = {
  154. IL_NPF, /* AddElement() */
  155. 0, /* nBytesPrivate */
  156. IL_NPF, /* Init() */
  157. IL_NPF, /* Cleanup() */
  158. IL_NPF, /* Destroy() */
  159. ilExecute8Bit3PlaneToPixel /* Execute() */
  160. };
  161. /* ------------------------- ilExecute8Bit3PixelToPlane ------------------------- */
  162. /* Execute() function: convert the given # of src lines, changing
  163. format from pixel to planar. Handles 3 planes of 8 bits/pixel only.
  164. */
  165. static ilError ilExecute8Bit3PixelToPlane (
  166. ilExecuteData *pData,
  167. long dstLine,
  168. long *pNLines
  169. )
  170. {
  171. ilImagePlaneInfo *pImagePlane;
  172. long dst0RowBytes, dst1RowBytes, dst2RowBytes, srcRowBytes;
  173. long nPixelsM1Init;
  174. long nLinesM1, nPixelsM1;
  175. ilPtr pDst0Line, pDst1Line, pDst2Line, pSrcLine;
  176. ilPtr pDst0, pDst1, pDst2, pSrc;
  177. /* Get ptr to start src plane and to 3 dst planes */
  178. pImagePlane = pData->pSrcImage->plane;
  179. srcRowBytes = pImagePlane->nBytesPerRow;
  180. pSrcLine = pImagePlane->pPixels + pData->srcLine * srcRowBytes;
  181. pImagePlane = pData->pDstImage->plane;
  182. dst0RowBytes = pImagePlane->nBytesPerRow;
  183. pDst0Line = pImagePlane->pPixels + dstLine * dst0RowBytes;
  184. pImagePlane++;
  185. dst1RowBytes = pImagePlane->nBytesPerRow;
  186. pDst1Line = pImagePlane->pPixels + dstLine * dst1RowBytes;
  187. pImagePlane++;
  188. dst2RowBytes = pImagePlane->nBytesPerRow;
  189. pDst2Line = pImagePlane->pPixels + dstLine * dst2RowBytes;
  190. /* Exit if no lines or pixels. */
  191. nPixelsM1Init = pData->pSrcImage->width;
  192. if (nPixelsM1Init <= 0)
  193. return IL_OK;
  194. nPixelsM1Init--;
  195. nLinesM1 = *pNLines;
  196. if (nLinesM1 <= 0)
  197. return IL_OK;
  198. nLinesM1--;
  199. do {
  200. pSrc = pSrcLine;
  201. pSrcLine += srcRowBytes;
  202. pDst0 = pDst0Line;
  203. pDst0Line += dst0RowBytes;
  204. pDst1 = pDst1Line;
  205. pDst1Line += dst1RowBytes;
  206. pDst2 = pDst2Line;
  207. pDst2Line += dst2RowBytes;
  208. nPixelsM1 = nPixelsM1Init;
  209. do {
  210. *pDst0++ = *pSrc++;
  211. *pDst1++ = *pSrc++;
  212. *pDst2++ = *pSrc++;
  213. } while (--nPixelsM1 >= 0);
  214. } while (--nLinesM1 >= 0);
  215. return IL_OK;
  216. }
  217. /* Table exported to ilConvert(), declared in /ilc/ilconvert.h .
  218. */
  219. IL_PRIVATE ilFormatRec _ilFormat8Bit3PixelToPlane = {
  220. IL_NPF, /* AddElement() */
  221. 0, /* nBytesPrivate */
  222. IL_NPF, /* Init() */
  223. IL_NPF, /* Cleanup() */
  224. IL_NPF, /* Destroy() */
  225. ilExecute8Bit3PixelToPlane /* Execute() */
  226. };
  227. /* ------------------------- ilExecute4To8Bit ------------------------- */
  228. /* Execute() function: convert the given # of src lines, changing nibbles
  229. to bytes, by copying the nibbles to the low order of the bytes.
  230. Handles any number of samples, but pixel order only if multi-sample.
  231. */
  232. static ilError ilExecute4To8Bit (
  233. ilExecuteData *pData,
  234. long dstLine,
  235. long *pNLines
  236. )
  237. {
  238. ilImageInfo *pSrcImage;
  239. ilImagePlaneInfo *pImagePlane;
  240. long srcRowBytes, dstRowBytes, nBytesM1Init, nLinesM1;
  241. ilBool oddNumberOfNibbles;
  242. ilPtr pSrcLine, pDstLine;
  243. long nBytesM1;
  244. ilPtr pSrc, pDst;
  245. ilByte byte;
  246. /* Exit if no lines or pixels. */
  247. pSrcImage = pData->pSrcImage;
  248. pImagePlane = &pSrcImage->plane[0];
  249. srcRowBytes = pImagePlane->nBytesPerRow;
  250. pSrcLine = pImagePlane->pPixels + pData->srcLine * srcRowBytes;
  251. pImagePlane = &pData->pDstImage->plane[0];
  252. dstRowBytes = pImagePlane->nBytesPerRow;
  253. pDstLine = pImagePlane->pPixels + dstLine * dstRowBytes;
  254. nLinesM1 = *pNLines;
  255. if (nLinesM1 <= 0)
  256. return IL_OK;
  257. nLinesM1--;
  258. /* Set "nBytesM1Init" to whole # of src bytes to do (2 nibbles each),
  259. where the # of nibbles is width * nSamplesPerPixel.
  260. Set "oddNumberOfNibbles" true if width is odd (do one last nibble).
  261. Copy each src byte (2 nibbles) to two dst bytes; do optional last nibble.
  262. */
  263. nBytesM1Init = pSrcImage->width * pSrcImage->pDes->nSamplesPerPixel;
  264. oddNumberOfNibbles = ((nBytesM1Init & 1) != 0);
  265. nBytesM1Init = (nBytesM1Init >> 1) - 1; /* width/2 - 1 */
  266. do {
  267. pSrc = pSrcLine;
  268. pSrcLine += srcRowBytes;
  269. pDst = pDstLine;
  270. pDstLine += dstRowBytes;
  271. nBytesM1 = nBytesM1Init;
  272. if (nBytesM1 >= 0) {
  273. do {
  274. byte = *pSrc++;
  275. *pDst++ = byte >> 4;
  276. *pDst++ = byte & 0xf;
  277. } while (--nBytesM1 >= 0);
  278. }
  279. if (oddNumberOfNibbles) {
  280. byte = *pSrc++;
  281. *pDst++ = byte >> 4;
  282. }
  283. } while (--nLinesM1 >= 0);
  284. return IL_OK;
  285. }
  286. /* Table exported to ilConvert(), declared in /ilc/ilconvert.h .
  287. */
  288. IL_PRIVATE ilFormatRec _ilFormat4To8Bit = {
  289. IL_NPF, /* AddElement() */
  290. 0, /* nBytesPrivate */
  291. IL_NPF, /* Init() */
  292. IL_NPF, /* Cleanup() */
  293. IL_NPF, /* Destroy() */
  294. ilExecute4To8Bit /* Execute() */
  295. };
  296. /* ------------------------- ilExecute8To4Bit ------------------------- */
  297. /* Pack pipe image which is byte/pixel into nibble/pixel.
  298. Handles any number of samples, but pixel order only if multi-sample.
  299. */
  300. static ilError ilExecute8To4Bit (
  301. ilExecuteData *pData,
  302. long dstLine,
  303. long *pNLines
  304. )
  305. {
  306. ilImageInfo *pSrcImage;
  307. ilImagePlaneInfo *pImagePlane;
  308. long srcRowBytes, dstRowBytes, nBytesM1Init, nLinesM1;
  309. ilBool oddNumberOfNibbles;
  310. ilPtr pSrcLine, pDstLine;
  311. long nBytesM1;
  312. ilPtr pSrc, pDst;
  313. ilByte byte0, byte1;
  314. /* Exit if no lines or pixels. */
  315. pSrcImage = pData->pSrcImage;
  316. pImagePlane = &pSrcImage->plane[0];
  317. srcRowBytes = pImagePlane->nBytesPerRow;
  318. pSrcLine = pImagePlane->pPixels + pData->srcLine * srcRowBytes;
  319. pImagePlane = &pData->pDstImage->plane[0];
  320. dstRowBytes = pImagePlane->nBytesPerRow;
  321. pDstLine = pImagePlane->pPixels + dstLine * dstRowBytes;
  322. nLinesM1 = *pNLines;
  323. if (nLinesM1 <= 0)
  324. return IL_OK;
  325. nLinesM1--;
  326. /* Set "nBytesM1Init" to whole # of dst bytes to do (2 nibbles each),
  327. where the # of nibbles is width * nSamplesPerPixel.
  328. Set "oddNumberOfNibbles" true if width is odd (do one last nibble).
  329. Pack each pair of src bytes into one dst nibble; do optional last nibble.
  330. */
  331. nBytesM1Init = pSrcImage->width * pSrcImage->pDes->nSamplesPerPixel;
  332. oddNumberOfNibbles = ((nBytesM1Init & 1) != 0);
  333. nBytesM1Init = (nBytesM1Init >> 1) - 1; /* width/2 - 1 */
  334. do {
  335. pSrc = pSrcLine;
  336. pSrcLine += srcRowBytes;
  337. pDst = pDstLine;
  338. pDstLine += dstRowBytes;
  339. nBytesM1 = nBytesM1Init;
  340. if (nBytesM1 >= 0) {
  341. do {
  342. byte0 = *pSrc++;
  343. byte1 = *pSrc++;
  344. *pDst++ = (byte0 << 4) | (byte1 & 0xf);
  345. } while (--nBytesM1 >= 0);
  346. }
  347. if (oddNumberOfNibbles) {
  348. byte0 = *pSrc++;
  349. *pDst++ = byte0 << 4;
  350. }
  351. } while (--nLinesM1 >= 0);
  352. return IL_OK;
  353. }
  354. /* Table exported to ilConvert(), declared in /ilc/ilconvert.h .
  355. */
  356. IL_PRIVATE ilFormatRec _ilFormat8To4Bit = {
  357. IL_NPF, /* AddElement() */
  358. 0, /* nBytesPrivate */
  359. IL_NPF, /* Init() */
  360. IL_NPF, /* Cleanup() */
  361. IL_NPF, /* Destroy() */
  362. ilExecute8To4Bit /* Execute() */
  363. };
  364. /* ------------------------- ilExecute4To8BitScaled ------------------------- */
  365. /* Execute() function: convert the given # of src lines, changing nibbles
  366. to bytes, by copying the nibbles to the low order and high order nibbles
  367. of the bytes, thus scaling from 0..15 to 0..255.
  368. Handles any number of samples, but pixel order only if multi-sample.
  369. */
  370. static ilError ilExecute4To8BitScaled (
  371. ilExecuteData *pData,
  372. long dstLine,
  373. long *pNLines
  374. )
  375. {
  376. ilImageInfo *pSrcImage;
  377. ilImagePlaneInfo *pImagePlane;
  378. long srcRowBytes, dstRowBytes, nBytesM1Init, nLinesM1;
  379. ilBool oddNumberOfNibbles;
  380. ilPtr pSrcLine, pDstLine;
  381. long nBytesM1;
  382. ilPtr pSrc, pDst;
  383. ilByte byte;
  384. /* Use bcopy to copy each line; copy the lesser of the src/dstRowBytes.
  385. Exit if no lines or pixels.
  386. */
  387. pSrcImage = pData->pSrcImage;
  388. pImagePlane = &pSrcImage->plane[0];
  389. srcRowBytes = pImagePlane->nBytesPerRow;
  390. pSrcLine = pImagePlane->pPixels + pData->srcLine * srcRowBytes;
  391. pImagePlane = &pData->pDstImage->plane[0];
  392. dstRowBytes = pImagePlane->nBytesPerRow;
  393. pDstLine = pImagePlane->pPixels + dstLine * dstRowBytes;
  394. nLinesM1 = *pNLines;
  395. if (nLinesM1 <= 0)
  396. return IL_OK;
  397. nLinesM1--;
  398. /* Set "nBytesM1Init" to whole # of src bytes to do (2 nibbles each),
  399. where the # of nibbles is width * nSamplesPerPixel.
  400. Set "oddNumberOfNibbles" true if width is odd (do one last nibble).
  401. Make from each src byte (2 nibbles) two dst bytes; do optional last nibble.
  402. Replicate each src nibble to upper/lower nibble of dst byte, thus scaling
  403. to new # of levels (from 16 to 256): 0 => 0, 1 => 17, 15 => 255.
  404. */
  405. nBytesM1Init = pSrcImage->width * pSrcImage->pDes->nSamplesPerPixel;
  406. oddNumberOfNibbles = ((nBytesM1Init & 1) != 0);
  407. nBytesM1Init = (nBytesM1Init >> 1) - 1; /* width/2 - 1 */
  408. do {
  409. pSrc = pSrcLine;
  410. pSrcLine += srcRowBytes;
  411. pDst = pDstLine;
  412. pDstLine += dstRowBytes;
  413. nBytesM1 = nBytesM1Init;
  414. if (nBytesM1 >= 0) {
  415. do {
  416. byte = *pSrc++;
  417. *pDst++ = (byte & 0xf0) | (byte >> 4);
  418. byte &= 0xf;
  419. *pDst++ = (byte << 4) | byte;
  420. } while (--nBytesM1 >= 0);
  421. }
  422. if (oddNumberOfNibbles) {
  423. byte = *pSrc++;
  424. *pDst++ = (byte & 0xf0) | (byte >> 4);
  425. }
  426. } while (--nLinesM1 >= 0);
  427. return IL_OK;
  428. }
  429. /* ------------------------- ilExecuteByte16To256Level ---------------------- */
  430. /* Execute() function: convert the given # of src lines, changing bytes from
  431. 16 levels to 256 levels, by replicating the low-order nibble to the high
  432. order nibble, thus scaling from 0..15 to 0..255.
  433. Handles any number of samples, but pixel order only if multi-sample.
  434. */
  435. static ilError ilExecuteByte16To256Level (
  436. ilExecuteData *pData,
  437. long dstLine,
  438. long *pNLines
  439. )
  440. {
  441. ilImageInfo *pSrcImage;
  442. ilImagePlaneInfo *pImagePlane;
  443. long srcRowBytes, dstRowBytes, nBytesM1Init, nLinesM1;
  444. ilPtr pSrcLine, pDstLine;
  445. long nBytesM1;
  446. ilPtr pSrc, pDst;
  447. ilByte byte;
  448. /* Use bcopy to copy each line; copy the lesser of the src/dstRowBytes.
  449. Exit if no lines or pixels.
  450. */
  451. pSrcImage = pData->pSrcImage;
  452. pImagePlane = &pSrcImage->plane[0];
  453. srcRowBytes = pImagePlane->nBytesPerRow;
  454. pSrcLine = pImagePlane->pPixels + pData->srcLine * srcRowBytes;
  455. pImagePlane = &pData->pDstImage->plane[0];
  456. dstRowBytes = pImagePlane->nBytesPerRow;
  457. pDstLine = pImagePlane->pPixels + dstLine * dstRowBytes;
  458. nLinesM1 = *pNLines;
  459. if (nLinesM1 <= 0)
  460. return IL_OK;
  461. nLinesM1--;
  462. /* Set "nBytesM1Init" to whole # of src bytes to do, = width * # samples/pixel
  463. (note that each sample must be a byte!)
  464. Replicate low-order nibble to upper nibble of dst byte, thus scaling
  465. to new # of levels (from 16 to 256): 0 => 0, 1 => 17, 15 => 255.
  466. */
  467. nBytesM1Init = pSrcImage->width * pSrcImage->pDes->nSamplesPerPixel - 1;
  468. if (nBytesM1Init < 0)
  469. return IL_OK;
  470. do {
  471. pSrc = pSrcLine;
  472. pSrcLine += srcRowBytes;
  473. pDst = pDstLine;
  474. pDstLine += dstRowBytes;
  475. nBytesM1 = nBytesM1Init;
  476. do {
  477. byte = *pSrc++;
  478. byte &= 0xf;
  479. *pDst++ = (byte << 4) | byte;
  480. } while (--nBytesM1 >= 0);
  481. } while (--nLinesM1 >= 0);
  482. return IL_OK;
  483. }
  484. /* ---------------------- ilAddLevelConversionFilter ------------------------ */
  485. /* Add a conversion filter to the given pipe which converts from the levels
  486. in "*pPipeDes" (i.e. the levels of the current pipe image) to those in
  487. "*pDes" (note - only nLevelsPerSample is reference from pDes).
  488. If failure, declares pipe invalid (which sets error code) and returns false;
  489. else returns true and "*pInfo", "*pPipeDes" and "*pFormat" are updated
  490. with the new pipe state info.
  491. */
  492. IL_PRIVATE ilBool _ilAddLevelConversionFilter (
  493. ilPipe pipe,
  494. ilPipeInfo *pInfo,
  495. ilImageDes *pPipeDes,
  496. const ilImageDes *pDes,
  497. ilImageFormat *pFormat
  498. )
  499. {
  500. unsigned int sample;
  501. ilPtr pPriv;
  502. ilDstElementData dstData;
  503. ilError (*executeFunction)();
  504. ilBool all4Bit, all8Bit;
  505. /* Determine if we support requested conversion.
  506. Currently only support: 4 or 8 bit, 16 level => 8 bit, 256 level, any # of
  507. samples/pixel, but pixel mode only if # samples > 1.
  508. */
  509. if ((pDes->nSamplesPerPixel > 1) && (pFormat->sampleOrder != IL_SAMPLE_PIXELS))
  510. return ilDeclarePipeInvalid (pipe, IL_ERROR_CANT_CONVERT);
  511. all4Bit = all8Bit = TRUE;
  512. for (sample = 0; sample < pPipeDes->nSamplesPerPixel; sample++) {
  513. if ((pPipeDes->nLevelsPerSample[sample] != 16)
  514. || (pDes->nLevelsPerSample[sample] != 256))
  515. return ilDeclarePipeInvalid (pipe, IL_ERROR_CANT_CONVERT);
  516. pPipeDes->nLevelsPerSample[sample] = 256;
  517. if (pFormat->nBitsPerSample[sample] == 4) {
  518. all8Bit = FALSE;
  519. pFormat->nBitsPerSample[sample] = 8;
  520. }
  521. else if (pFormat->nBitsPerSample[sample] == 8)
  522. all4Bit = FALSE;
  523. else return ilDeclarePipeInvalid (pipe, IL_ERROR_CANT_CONVERT);
  524. }
  525. /* All src # levels == 16, dst == 256. If all src formats are 4 bit or 8 bit,
  526. can handle, else error. pFormat->nBitsPerSample now == 8 for all samples.
  527. */
  528. if (all4Bit)
  529. executeFunction = ilExecute4To8BitScaled;
  530. else if (all8Bit)
  531. executeFunction = ilExecuteByte16To256Level;
  532. else return ilDeclarePipeInvalid (pipe, IL_ERROR_CANT_CONVERT);
  533. /* Update *pPipeDes, *pFormat and add filter or error.
  534. Update pInfo after successful add; pPipeDes and pFormat already updated.
  535. */
  536. dstData.producerObject = (ilObject)NULL;
  537. dstData.pDes = pPipeDes;
  538. dstData.pFormat = pFormat;
  539. dstData.width = pInfo->width;
  540. dstData.height = pInfo->height;
  541. dstData.stripHeight = 0;
  542. dstData.constantStrip = FALSE;
  543. dstData.pPalette = pInfo->pPalette;
  544. dstData.pCompData = pInfo->pCompData;
  545. pPriv = ilAddPipeElement (pipe, IL_FILTER, 0, 0,
  546. (ilSrcElementData *)NULL, &dstData,
  547. IL_NPF, IL_NPF, IL_NPF, executeFunction, NULL, 0);
  548. if (!pPriv) return FALSE; /* EXIT */
  549. ilGetPipeInfo (pipe, FALSE, pInfo, (ilImageDes *)NULL, (ilImageFormat *)NULL);
  550. return TRUE;
  551. }