PageRenderTime 60ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 2ms

/lib/cximage-6.0/mng/libmng_pixels.c

http://github.com/xbmc/xbmc
C | 13878 lines | 11466 code | 1525 blank | 887 comment | 1488 complexity | bb712b345ae5b5ba9c95d4b8afc68903 MD5 | raw file
Possible License(s): GPL-3.0, CC-BY-SA-3.0, LGPL-2.0, 0BSD, Unlicense, GPL-2.0, AGPL-1.0, BSD-3-Clause, LGPL-2.1, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

  1. /* ************************************************************************** */
  2. /* * For conditions of distribution and use, * */
  3. /* * see copyright notice in libmng.h * */
  4. /* ************************************************************************** */
  5. /* * * */
  6. /* * project : libmng * */
  7. /* * file : libmng_pixels.c copyright (c) 2000-2005 G.Juyn * */
  8. /* * version : 1.0.10 * */
  9. /* * * */
  10. /* * purpose : Pixel-row management routines (implementation) * */
  11. /* * * */
  12. /* * author : G.Juyn * */
  13. /* * * */
  14. /* * comment : implementation of the pixel-row management routines * */
  15. /* * * */
  16. /* * the dual alpha-composing for RGBA/BGRA/etc output-canvas' * */
  17. /* * is based on the Note on Compositing chapter of the * */
  18. /* * DOH-3 draft, noted to me by Adam M. Costello * */
  19. /* * * */
  20. /* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
  21. /* * - changed strict-ANSI stuff * */
  22. /* * 0.5.1 - 05/11/2000 - G.Juyn * */
  23. /* * - added callback error-reporting support * */
  24. /* * 0.5.1 - 05/12/2000 - G.Juyn * */
  25. /* * - changed trace to macro for callback error-reporting * */
  26. /* * * */
  27. /* * 0.5.2 - 05/22/2000 - G.Juyn * */
  28. /* * - added JNG support * */
  29. /* * 0.5.2 - 05/30/2000 - G.Juyn * */
  30. /* * - fixed minor bugs 16-bit pixel-handling * */
  31. /* * - added delta-image row-processing routines * */
  32. /* * 0.5.2 - 06/02/2000 - G.Juyn * */
  33. /* * - fixed endian support (hopefully) * */
  34. /* * 0.5.2 - 06/03/2000 - G.Juyn * */
  35. /* * - fixed makeup for Linux gcc compile * */
  36. /* * 0.5.2 - 06/05/2000 - G.Juyn * */
  37. /* * - implemented app bkgd restore routines * */
  38. /* * - implemented RGBA8, ARGB8, BGRA8 & ABGR8 display routines * */
  39. /* * - added support for RGB8_A8 canvasstyle * */
  40. /* * 0.5.2 - 06/09/2000 - G.Juyn * */
  41. /* * - fixed alpha-handling for alpha canvasstyles * */
  42. /* * * */
  43. /* * 0.5.3 - 06/16/2000 - G.Juyn * */
  44. /* * - changed progressive-display processing * */
  45. /* * 0.5.3 - 06/17/2000 - G.Juyn * */
  46. /* * - changed to support delta-images * */
  47. /* * - optimized some store_xxx routines * */
  48. /* * 0.5.3 - 06/20/2000 - G.Juyn * */
  49. /* * - fixed nasty bug with embedded PNG after delta-image * */
  50. /* * 0.5.3 - 06/24/2000 - G.Juyn * */
  51. /* * - fixed problem with 16-bit GA format * */
  52. /* * 0.5.3 - 06/25/2000 - G.Juyn * */
  53. /* * - fixed problem with cheap transparency for 4-bit gray * */
  54. /* * - fixed display_xxxx routines for interlaced images * */
  55. /* * 0.5.3 - 06/28/2000 - G.Juyn * */
  56. /* * - fixed compiler-warning for non-initialized iB variable * */
  57. /* * * */
  58. /* * 0.9.1 - 07/05/2000 - G.Juyn * */
  59. /* * - fixed mandatory BACK color to be opaque * */
  60. /* * * */
  61. /* * 0.9.2 - 07/31/2000 - G.Juyn * */
  62. /* * - B110547 - fixed bug in interlace code * */
  63. /* * 0.9.2 - 08/05/2000 - G.Juyn * */
  64. /* * - changed file-prefixes * */
  65. /* * * */
  66. /* * 0.9.3 - 08/20/2000 - G.Juyn * */
  67. /* * - fixed app-supplied background restore * */
  68. /* * 0.9.3 - 08/26/2000 - G.Juyn * */
  69. /* * - added MAGN chunk * */
  70. /* * 0.9.3 - 09/07/2000 - G.Juyn * */
  71. /* * - added support for new filter_types * */
  72. /* * 0.9.3 - 09/30/2000 - G.Juyn * */
  73. /* * - fixed MAGN rounding errors (thanks Matthias!) * */
  74. /* * 0.9.3 - 10/10/2000 - G.Juyn * */
  75. /* * - fixed alpha-blending for RGBA canvasstyle * */
  76. /* * 0.9.3 - 10/11/2000 - G.Juyn * */
  77. /* * - fixed alpha-blending for other alpha-canvasstyles * */
  78. /* * 0.9.3 - 10/16/2000 - G.Juyn * */
  79. /* * - added optional support for bKGD for PNG images * */
  80. /* * - added support for JDAA * */
  81. /* * 0.9.3 - 10/17/2000 - G.Juyn * */
  82. /* * - fixed support for bKGD * */
  83. /* * 0.9.3 - 10/19/2000 - G.Juyn * */
  84. /* * - implemented delayed delta-processing * */
  85. /* * 0.9.3 - 10/28/2000 - G.Juyn * */
  86. /* * - fixed tRNS processing for gray-image < 8-bits * */
  87. /* * * */
  88. /* * 0.9.4 - 12/16/2000 - G.Juyn * */
  89. /* * - fixed mixup of data- & function-pointers (thanks Dimitri)* */
  90. /* * 0.9.4 - 1/18/2001 - G.Juyn * */
  91. /* * - removed "old" MAGN methods 3 & 4 * */
  92. /* * - added "new" MAGN methods 3, 4 & 5 * */
  93. /* * - removed test filter-methods 1 & 65 * */
  94. /* * * */
  95. /* * 1.0.1 - 04/21/2001 - G.Juyn (code by G.Kelly) * */
  96. /* * - added BGRA8 canvas with premultiplied alpha * */
  97. /* * 1.0.1 - 04/25/2001 - G.Juyn * */
  98. /* * - moved mng_clear_cms to libmng_cms * */
  99. /* * * */
  100. /* * 1.0.2 - 06/25/2001 - G.Juyn * */
  101. /* * - added option to turn off progressive refresh * */
  102. /* * * */
  103. /* * 1.0.4 - 11/04/2001 - G.Juyn * */
  104. /* * - fixed possible compile-problem in cleanup_rowproc * */
  105. /* * 1.0.4 - 06/22/2002 - G.Juyn * */
  106. /* * - B558212 - off by one error * */
  107. /* * - MNG subimage alpha composite wrong for rgba8 images * */
  108. /* * * */
  109. /* * 1.0.5 - 08/07/2002 - G.Juyn * */
  110. /* * - added test-option for PNG filter method 193 (=no filter) * */
  111. /* * 1.0.5 - 08/15/2002 - G.Juyn * */
  112. /* * - completed PROM support * */
  113. /* * - completed delta-image support * */
  114. /* * 1.0.5 - 08/16/2002 - G.Juyn * */
  115. /* * - completed MAGN support (16-bit functions) * */
  116. /* * 1.0.5 - 08/19/2002 - G.Juyn * */
  117. /* * - B597134 - libmng pollutes the linker namespace * */
  118. /* * 1.0.5 - 09/19/2002 - G.Juyn * */
  119. /* * - optimized restore-background for bKGD cases * */
  120. /* * 1.0.5 - 09/20/2002 - G.Juyn * */
  121. /* * - finished support for BACK image & tiling * */
  122. /* * 1.0.5 - 09/22/2002 - G.Juyn * */
  123. /* * - added bgrx8 canvas (filler byte) * */
  124. /* * 1.0.5 - 09/23/2002 - G.Juyn * */
  125. /* * - added compose over/under routines for PAST processing * */
  126. /* * - added flip & tile routines for PAST processing * */
  127. /* * * */
  128. /* * 1.0.6 - 03/09/2003 - G.Juyn * */
  129. /* * - hiding 12-bit JPEG stuff * */
  130. /* * 1.0.6 - 05/11/2003 - Glenn RP * */
  131. /* * - added size-optimization COMPOSE routine usage * */
  132. /* * 1.0.6 - 05/11/2003 - G. Juyn * */
  133. /* * - added conditionals around canvas update routines * */
  134. /* * 1.0.6 - 05/25/2003 - Glenn RP * */
  135. /* * - added size-optimization DIV255B8 routine usage * */
  136. /* * 1.0.6 - 06/09/2003 - G. R-P * */
  137. /* * - added conditionals around 8-bit magn routines * */
  138. /* * 1.0.6 - 07/07/2003 - G. R-P * */
  139. /* * - removed conditionals around 8-bit magn routines * */
  140. /* * - added MNG_NO_16BIT_SUPPORT and MNG_NO_DELTA_PNG * */
  141. /* * conditionals * */
  142. /* * - reversed many loops to use decrementing counter * */
  143. /* * - combined init functions * */
  144. /* * - converted some switches to array references * */
  145. /* * 1.0.6 - 07/29/2003 - G.Juyn * */
  146. /* * - fixed duplicate for-loop * */
  147. /* * 1.0.6 - 07/29/2003 - G.R-P * */
  148. /* * - added SKIPCHUNK conditionals around PAST chunk support * */
  149. /* * - fixed "FOOTPRINT_COMPOSEIV" typo (now "FOOTPRINT_DIV") * */
  150. /* * 1.0.6 - 08/17/2003 - G.R-P * */
  151. /* * - added more conditionals around "promote" functions * */
  152. /* * * */
  153. /* * 1.0.7 - 11/27/2003 - R.A * */
  154. /* * - added CANVAS_RGB565 and CANVAS_BGR565 * */
  155. /* * 1.0.7 - 12/06/2003 - R.A * */
  156. /* * - added CANVAS_RGBA565 and CANVAS_BGRA565 * */
  157. /* * 1.0.7 - 01/25/2004 - J.S * */
  158. /* * - added premultiplied alpha canvas' for RGBA, ARGB, ABGR * */
  159. /* * 1.0.7 - 03/08/2004 - G.R-P * */
  160. /* * - added more conditionals around 16-bit-supporting code * */
  161. /* * 1.0.7 - 03/09/2004 - G.Juyn * */
  162. /* * - fixed bug in promote_g8_g8 with 16bit support off * */
  163. /* * 1.0.7 - 03/09/2004 - G.R-P * */
  164. /* * - more optimizations with 16bit support off * */
  165. /* * 1.0.7 - 03/10/2004 - G.Juyn * */
  166. /* * - fixed some warnings for 16bit optimizations * */
  167. /* * 1.0.7 - 03/21/2004 - G.Juyn * */
  168. /* * - fixed some 64-bit platform compiler warnings * */
  169. /* * * */
  170. /* * 1.0.8 - 06/20/2004 - G.Juyn * */
  171. /* * - some speed optimizations (thanks to John Stiles) * */
  172. /* * 1.0.8 - 08/01/2004 - G.Juyn * */
  173. /* * - added support for 3+byte pixelsize for JPEG's * */
  174. /* * * */
  175. /* * 1.0.9 - 10/10/2004 - G.R-P. * */
  176. /* * - added MNG_NO_1_2_4BIT_SUPPORT * */
  177. /* * 1.0.9 - 10/14/2004 - G.Juyn * */
  178. /* * - added bgr565_a8 canvas-style (thanks to J. Elvander) * */
  179. /* * 1.0.9 - 12/05/2004 - G.Juyn * */
  180. /* * - added LITTLEENDIAN/BIGENDIAN fixtures (thanks J.Stiles) * */
  181. /* * - fixed MNG_NO_1_2_4BIT_SUPPORT for TBBN1G04.PNG * */
  182. /* * 1.0.9 - 12/31/2004 - G.R-P. * */
  183. /* * - fixed warnings about C++ style (//) comments * */
  184. /* * * */
  185. /* * 1.0.10 - 07/06/2005 - G.R-P. * */
  186. /* * - added MORE MNG_NO_1_2_4BIT_SUPPORT * */
  187. /* * 1.0.10 - 10/06/2005 - G.R-P. * */
  188. /* * - alloc more memory for MNG_NO_1_2_4BIT_SUPPORT * */
  189. /* * 1.0.10 - 12/07/2005 - G.R-P. * */
  190. /* * - optimized footprint of 16bit support * */
  191. /* * 1.0.10 - 03/07/2006 - (thanks to W. Manthey) * */
  192. /* * - added CANVAS_RGB555 and CANVAS_BGR555 * */
  193. /* * * */
  194. /* ************************************************************************** */
  195. #include "libmng.h"
  196. #include "libmng_data.h"
  197. #include "libmng_error.h"
  198. #include "libmng_trace.h"
  199. #ifdef __BORLANDC__
  200. #pragma hdrstop
  201. #endif
  202. #include "libmng_objects.h"
  203. #include "libmng_object_prc.h"
  204. #include "libmng_memory.h"
  205. #include "libmng_cms.h"
  206. #include "libmng_filter.h"
  207. #include "libmng_pixels.h"
  208. #if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
  209. #pragma option -A /* force ANSI-C */
  210. #endif
  211. /* ************************************************************************** */
  212. #ifdef MNG_INCLUDE_DISPLAY_PROCS
  213. /* TODO: magnification & canvas-positioning/-clipping */
  214. /* TODO: major optimization of pixel-loops by using assembler (?) */
  215. /* ************************************************************************** */
  216. /* * * */
  217. /* * Interlace tables * */
  218. /* * * */
  219. /* ************************************************************************** */
  220. MNG_LOCAL mng_uint32 const interlace_row [7] = { 0, 0, 4, 0, 2, 0, 1 };
  221. MNG_LOCAL mng_uint32 const interlace_rowskip [7] = { 8, 8, 8, 4, 4, 2, 2 };
  222. MNG_LOCAL mng_uint32 const interlace_col [7] = { 0, 4, 0, 2, 0, 1, 0 };
  223. MNG_LOCAL mng_uint32 const interlace_colskip [7] = { 8, 8, 4, 4, 2, 2, 1 };
  224. MNG_LOCAL mng_uint32 const interlace_roundoff [7] = { 7, 7, 3, 3, 1, 1, 0 };
  225. MNG_LOCAL mng_uint32 const interlace_divider [7] = { 3, 3, 2, 2, 1, 1, 0 };
  226. /* ************************************************************************** */
  227. /* * * */
  228. /* * Alpha composing macros * */
  229. /* * the code below is slightly modified from the libpng package * */
  230. /* * the original was last optimized by Greg Roelofs & Mark Adler * */
  231. /* * * */
  232. /* ************************************************************************** */
  233. #define MNG_COMPOSE8(RET,FG,ALPHA,BG) { \
  234. mng_uint16 iH = (mng_uint16)((mng_uint16)(FG) * (mng_uint16)(ALPHA) \
  235. + (mng_uint16)(BG)*(mng_uint16)(255 - \
  236. (mng_uint16)(ALPHA)) + (mng_uint16)128); \
  237. (RET) = (mng_uint8)((iH + (iH >> 8)) >> 8); }
  238. #define MNG_COMPOSE16(RET,FG,ALPHA,BG) { \
  239. mng_uint32 iH = (mng_uint32)((mng_uint32)(FG) * (mng_uint32)(ALPHA) \
  240. + (mng_uint32)(BG)*(mng_uint32)(65535L - \
  241. (mng_uint32)(ALPHA)) + (mng_uint32)32768L); \
  242. (RET) = (mng_uint16)((iH + (iH >> 16)) >> 16); }
  243. /* ************************************************************************** */
  244. /* * * */
  245. /* * Alpha blending macros * */
  246. /* * this code is based on Adam Costello's "Note on Compositing" from the * */
  247. /* * mng-list which gives the following formula: * */
  248. /* * * */
  249. /* * top pixel = (Rt, Gt, Bt, At) * */
  250. /* * bottom pixel = (Rb, Gb, Bb, Ab) * */
  251. /* * composite pixel = (Rc, Gc, Bc, Ac) * */
  252. /* * * */
  253. /* * all values in the range 0..1 * */
  254. /* * * */
  255. /* * Ac = 1 - (1 - At)(1 - Ab) * */
  256. /* * s = At / Ac * */
  257. /* * t = (1 - At) Ab / Ac * */
  258. /* * Rc = s Rt + t Rb * */
  259. /* * Gc = s Gt + t Gb * */
  260. /* * Bc = s Bt + t Bb * */
  261. /* * * */
  262. /* * (I just hope I coded it correctly in integer arithmetic...) * */
  263. /* * * */
  264. /* ************************************************************************** */
  265. #define MNG_BLEND8(RT, GT, BT, AT, RB, GB, BB, AB, RC, GC, BC, AC) { \
  266. mng_uint32 S, T; \
  267. (AC) = (mng_uint8)((mng_uint32)255 - \
  268. ((((mng_uint32)255 - (mng_uint32)(AT)) * \
  269. ((mng_uint32)255 - (mng_uint32)(AB)) ) >> 8)); \
  270. S = (mng_uint32)(((mng_uint32)(AT) << 8) / \
  271. (mng_uint32)(AC)); \
  272. T = (mng_uint32)(((mng_uint32)255 - (mng_uint32)(AT)) * \
  273. (mng_uint32)(AB) / (mng_uint32)(AC)); \
  274. (RC) = (mng_uint8)((S * (mng_uint32)(RT) + \
  275. T * (mng_uint32)(RB) + (mng_uint32)127) >> 8); \
  276. (GC) = (mng_uint8)((S * (mng_uint32)(GT) + \
  277. T * (mng_uint32)(GB) + (mng_uint32)127) >> 8); \
  278. (BC) = (mng_uint8)((S * (mng_uint32)(BT) + \
  279. T * (mng_uint32)(BB) + (mng_uint32)127) >> 8); }
  280. #define MNG_BLEND16(RT, GT, BT, AT, RB, GB, BB, AB, RC, GC, BC, AC) { \
  281. mng_uint32 S, T; \
  282. (AC) = (mng_uint16)((mng_uint32)65535 - \
  283. ((((mng_uint32)65535 - (mng_uint32)(AT)) * \
  284. ((mng_uint32)65535 - (mng_uint32)(AB)) ) >> 16)); \
  285. S = (mng_uint32)(((mng_uint32)(AT) << 16) / \
  286. (mng_uint32)(AC)); \
  287. T = (mng_uint32)(((mng_uint32)65535 - (mng_uint32)(AT)) * \
  288. (mng_uint32)(AB) / (mng_uint32)(AC)); \
  289. (RC) = (mng_uint16)((S * (mng_uint32)(RT) + \
  290. T * (mng_uint32)(RB) + (mng_uint32)32767) >> 16); \
  291. (GC) = (mng_uint16)((S * (mng_uint32)(GT) + \
  292. T * (mng_uint32)(GB) + (mng_uint32)32767) >> 16); \
  293. (BC) = (mng_uint16)((S * (mng_uint32)(BT) + \
  294. T * (mng_uint32)(BB) + (mng_uint32)32767) >> 16); }
  295. /* ************************************************************************** */
  296. /* note a good optimizing compiler will optimize this */
  297. #define DIV255B8(x) (mng_uint8)(((x) + 127) / 255)
  298. #define DIV255B16(x) (mng_uint16)(((x) + 32767) / 65535)
  299. /* ************************************************************************** */
  300. /* * * */
  301. /* * Progressive display check - checks to see if progressive display is * */
  302. /* * in order & indicates so * */
  303. /* * * */
  304. /* * The routine is called after a call to one of the display_xxx routines * */
  305. /* * if appropriate * */
  306. /* * * */
  307. /* * The refresh is warrented in the read_chunk routine (mng_read.c) * */
  308. /* * and only during read&display processing, since there's not much point * */
  309. /* * doing it from memory! * */
  310. /* * * */
  311. /* ************************************************************************** */
  312. mng_retcode mng_display_progressive_check (mng_datap pData)
  313. {
  314. if ((pData->bDoProgressive) && /* need progressive display? */
  315. ((pData->eImagetype != mng_it_mng) || (pData->iDataheight > 300)) &&
  316. (pData->iDestb - pData->iDestt > 50) && (!pData->pCurraniobj))
  317. {
  318. mng_int32 iC = pData->iRow + pData->iDestt - pData->iSourcet;
  319. if (iC % 20 == 0) /* every 20th line */
  320. pData->bNeedrefresh = MNG_TRUE;
  321. }
  322. return MNG_NOERROR;
  323. }
  324. /* ************************************************************************** */
  325. /* * * */
  326. /* * Display routines - convert rowdata (which is already color-corrected) * */
  327. /* * to the output canvas, respecting the opacity information * */
  328. /* * * */
  329. /* ************************************************************************** */
  330. MNG_LOCAL void check_update_region (mng_datap pData)
  331. { /* determine actual canvas row */
  332. mng_int32 iRow = pData->iRow + pData->iDestt - pData->iSourcet;
  333. /* check for change in update-region */
  334. if ((pData->iDestl < (mng_int32)pData->iUpdateleft) || (pData->iUpdateright == 0))
  335. pData->iUpdateleft = pData->iDestl;
  336. if (pData->iDestr > (mng_int32)pData->iUpdateright)
  337. pData->iUpdateright = pData->iDestr;
  338. if ((iRow < (mng_int32)pData->iUpdatetop) || (pData->iUpdatebottom == 0))
  339. pData->iUpdatetop = iRow;
  340. if (iRow+1 > (mng_int32)pData->iUpdatebottom)
  341. pData->iUpdatebottom = iRow+1;
  342. return;
  343. }
  344. /* ************************************************************************** */
  345. #ifndef MNG_SKIPCANVAS_RGB8
  346. #ifndef MNG_NO_16BIT_SUPPORT
  347. #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
  348. mng_retcode mng_display_rgb8 (mng_datap pData)
  349. {
  350. mng_uint8p pScanline;
  351. mng_uint8p pDataline;
  352. mng_int32 iX;
  353. mng_uint16 iA16;
  354. mng_uint16 iFGr16, iFGg16, iFGb16;
  355. mng_uint16 iBGr16, iBGg16, iBGb16;
  356. mng_uint8 iA8;
  357. #ifdef MNG_SUPPORT_TRACE
  358. MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_START);
  359. #endif
  360. /* viewable row ? */
  361. if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
  362. { /* address destination row */
  363. pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
  364. pData->iRow + pData->iDestt -
  365. pData->iSourcet);
  366. /* adjust destination row starting-point */
  367. pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
  368. pDataline = pData->pRGBArow; /* address source row */
  369. if (pData->bIsRGBA16) /* adjust source row starting-point */
  370. pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
  371. else
  372. pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
  373. if (pData->bIsOpaque) /* forget about transparency ? */
  374. {
  375. if (pData->bIsRGBA16) /* 16-bit input row ? */
  376. {
  377. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  378. iX += pData->iColinc)
  379. { /* scale down by dropping the LSB */
  380. *pScanline = *pDataline;
  381. *(pScanline+1) = *(pDataline+2);
  382. *(pScanline+2) = *(pDataline+4);
  383. pScanline += (pData->iColinc * 3);
  384. pDataline += 8;
  385. }
  386. }
  387. else
  388. {
  389. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  390. iX += pData->iColinc)
  391. { /* copy the values */
  392. *pScanline = *pDataline;
  393. *(pScanline+1) = *(pDataline+1);
  394. *(pScanline+2) = *(pDataline+2);
  395. pScanline += (pData->iColinc * 3);
  396. pDataline += 4;
  397. }
  398. }
  399. }
  400. else
  401. {
  402. if (pData->bIsRGBA16) /* 16-bit input row ? */
  403. {
  404. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  405. iX += pData->iColinc)
  406. {
  407. iA16 = mng_get_uint16 (pDataline+6);
  408. if (iA16) /* any opacity at all ? */
  409. {
  410. if (iA16 == 0xFFFF) /* fully opaque ? */
  411. { /* scale down by dropping the LSB */
  412. *pScanline = *pDataline;
  413. *(pScanline+1) = *(pDataline+2);
  414. *(pScanline+2) = *(pDataline+4);
  415. }
  416. else
  417. { /* get the proper values */
  418. iFGr16 = mng_get_uint16 (pDataline );
  419. iFGg16 = mng_get_uint16 (pDataline+2);
  420. iFGb16 = mng_get_uint16 (pDataline+4);
  421. /* scale background up */
  422. iBGr16 = (mng_uint16)(*pScanline );
  423. iBGg16 = (mng_uint16)(*(pScanline+1));
  424. iBGb16 = (mng_uint16)(*(pScanline+2));
  425. iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
  426. iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
  427. iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
  428. /* now compose */
  429. MNG_COMPOSE16(iFGr16, iFGr16, iA16, iBGr16);
  430. MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
  431. MNG_COMPOSE16(iFGb16, iFGb16, iA16, iBGb16);
  432. /* and return the composed values */
  433. *pScanline = (mng_uint8)(iFGr16 >> 8);
  434. *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
  435. *(pScanline+2) = (mng_uint8)(iFGb16 >> 8);
  436. }
  437. }
  438. pScanline += (pData->iColinc * 3);
  439. pDataline += 8;
  440. }
  441. }
  442. else
  443. {
  444. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  445. iX += pData->iColinc)
  446. {
  447. iA8 = *(pDataline+3); /* get alpha value */
  448. if (iA8) /* any opacity at all ? */
  449. {
  450. if (iA8 == 0xFF) /* fully opaque ? */
  451. { /* then simply copy the values */
  452. *pScanline = *pDataline;
  453. *(pScanline+1) = *(pDataline+1);
  454. *(pScanline+2) = *(pDataline+2);
  455. }
  456. else
  457. { /* do alpha composing */
  458. MNG_COMPOSE8 (*pScanline, *pDataline, iA8, *pScanline );
  459. MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
  460. MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iA8, *(pScanline+2));
  461. }
  462. }
  463. pScanline += (pData->iColinc * 3);
  464. pDataline += 4;
  465. }
  466. }
  467. }
  468. }
  469. check_update_region (pData);
  470. #ifdef MNG_SUPPORT_TRACE
  471. MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_END);
  472. #endif
  473. return MNG_NOERROR;
  474. }
  475. #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
  476. mng_retcode mng_display_rgb8 (mng_datap pData)
  477. {
  478. mng_uint8p pScanline;
  479. mng_uint8p pDataline;
  480. mng_int32 iX;
  481. mng_uint16 iA16;
  482. mng_uint16 iFGg16;
  483. mng_uint16 iBGg16;
  484. mng_uint8 iA8;
  485. mng_uint8 iBps;
  486. #ifdef MNG_SUPPORT_TRACE
  487. MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_START);
  488. #endif
  489. iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
  490. /* viewable row ? */
  491. if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
  492. { /* address destination row */
  493. pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
  494. pData->iRow + pData->iDestt -
  495. pData->iSourcet);
  496. /* adjust destination row starting-point */
  497. pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
  498. pDataline = pData->pRGBArow; /* address source row */
  499. /* adjust source row starting-point */
  500. pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
  501. if (pData->bIsOpaque) /* forget about transparency ? */
  502. {
  503. {
  504. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  505. iX += pData->iColinc)
  506. { /* scale down by dropping the LSB */
  507. *pScanline = *pDataline;
  508. *(pScanline+1) = *(pDataline+iBps);
  509. *(pScanline+2) = *(pDataline+2*iBps);
  510. pScanline += (pData->iColinc * 3);
  511. pDataline += 4*iBps;
  512. }
  513. }
  514. }
  515. else
  516. {
  517. if (pData->bIsRGBA16) /* 16-bit input row ? */
  518. {
  519. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  520. iX += pData->iColinc)
  521. {
  522. iA16 = mng_get_uint16 (pDataline+6);
  523. if (iA16) /* any opacity at all ? */
  524. {
  525. if (iA16 == 0xFFFF) /* fully opaque ? */
  526. { /* scale down by dropping the LSB */
  527. *pScanline = *pDataline;
  528. *(pScanline+1) = *(pDataline+2);
  529. *(pScanline+2) = *(pDataline+4);
  530. }
  531. else
  532. { /* get the proper values */
  533. int i;
  534. for (i=2; i >= 0; i--)
  535. {
  536. iFGg16 = mng_get_uint16 (pDataline+i+i);
  537. /* scale background up */
  538. iBGg16 = (mng_uint16)(*(pScanline+i));
  539. iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
  540. /* now compose */
  541. MNG_COMPOSE16(iFGg16, iFGg16, iA16, iBGg16);
  542. /* and return the composed values */
  543. *(pScanline+i) = (mng_uint8)(iFGg16 >> 8);
  544. }
  545. }
  546. }
  547. pScanline += (pData->iColinc * 3);
  548. pDataline += 8;
  549. }
  550. }
  551. else
  552. {
  553. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  554. iX += pData->iColinc)
  555. {
  556. iA8 = *(pDataline+3); /* get alpha value */
  557. if (iA8) /* any opacity at all ? */
  558. {
  559. if (iA8 == 0xFF) /* fully opaque ? */
  560. { /* then simply copy the values */
  561. *pScanline = *pDataline;
  562. *(pScanline+1) = *(pDataline+1);
  563. *(pScanline+2) = *(pDataline+2);
  564. }
  565. else
  566. { /* do alpha composing */
  567. int i;
  568. for (i=2; i >= 0; i--)
  569. {
  570. MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iA8, *(pScanline+i));
  571. }
  572. }
  573. }
  574. pScanline += (pData->iColinc * 3);
  575. pDataline += 4;
  576. }
  577. }
  578. }
  579. }
  580. check_update_region (pData);
  581. #ifdef MNG_SUPPORT_TRACE
  582. MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_END);
  583. #endif
  584. return MNG_NOERROR;
  585. }
  586. #endif /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
  587. #else /* MNG_NO_16BIT_SUPPORT */
  588. mng_retcode mng_display_rgb8 (mng_datap pData)
  589. {
  590. mng_uint8p pScanline;
  591. mng_uint8p pDataline;
  592. mng_int32 iX;
  593. mng_uint8 iA8;
  594. #ifdef MNG_SUPPORT_TRACE
  595. MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_START);
  596. #endif
  597. /* viewable row ? */
  598. if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
  599. { /* address destination row */
  600. pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
  601. pData->iRow + pData->iDestt -
  602. pData->iSourcet);
  603. /* adjust destination row starting-point */
  604. pScanline = pScanline + (pData->iCol * 3) + (pData->iDestl * 3);
  605. pDataline = pData->pRGBArow; /* address source row */
  606. pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
  607. if (pData->bIsOpaque) /* forget about transparency ? */
  608. {
  609. {
  610. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  611. iX += pData->iColinc)
  612. { /* copy the values */
  613. *pScanline = *pDataline;
  614. *(pScanline+1) = *(pDataline+1);
  615. *(pScanline+2) = *(pDataline+2);
  616. pScanline += (pData->iColinc * 3);
  617. pDataline += 4;
  618. }
  619. }
  620. }
  621. else
  622. {
  623. {
  624. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  625. iX += pData->iColinc)
  626. {
  627. iA8 = *(pDataline+3); /* get alpha value */
  628. if (iA8) /* any opacity at all ? */
  629. {
  630. if (iA8 == 0xFF) /* fully opaque ? */
  631. { /* then simply copy the values */
  632. *pScanline = *pDataline;
  633. *(pScanline+1) = *(pDataline+1);
  634. *(pScanline+2) = *(pDataline+2);
  635. }
  636. else
  637. { /* do alpha composing */
  638. #ifdef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
  639. int i;
  640. for (i=2; i >= 0; i--)
  641. {
  642. MNG_COMPOSE8 (*(pScanline+i), *(pDataline+i), iA8, *(pScanline+i));
  643. }
  644. #else
  645. MNG_COMPOSE8 (*pScanline, *pDataline, iA8, *pScanline );
  646. MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iA8, *(pScanline+1));
  647. MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iA8, *(pScanline+2));
  648. #endif
  649. }
  650. }
  651. pScanline += (pData->iColinc * 3);
  652. pDataline += 4;
  653. }
  654. }
  655. }
  656. }
  657. check_update_region (pData);
  658. #ifdef MNG_SUPPORT_TRACE
  659. MNG_TRACE (pData, MNG_FN_DISPLAY_RGB8, MNG_LC_END);
  660. #endif
  661. return MNG_NOERROR;
  662. }
  663. #endif /* MNG_NO_16BIT_SUPPORT */
  664. #endif /* MNG_SKIPCANVAS_RGB8 */
  665. /* ************************************************************************** */
  666. #ifndef MNG_SKIPCANVAS_RGBA8
  667. #ifndef MNG_NO_16BIT_SUPPORT
  668. #ifndef MNG_OPTIMIZE_FOOTPRINT_COMPOSE
  669. mng_retcode mng_display_rgba8 (mng_datap pData)
  670. {
  671. mng_uint8p pScanline;
  672. mng_uint8p pDataline;
  673. mng_int32 iX;
  674. mng_uint8 iFGa8, iBGa8, iCa8;
  675. mng_uint16 iFGa16, iBGa16, iCa16;
  676. mng_uint16 iFGr16, iFGg16, iFGb16;
  677. mng_uint16 iBGr16, iBGg16, iBGb16;
  678. mng_uint16 iCr16, iCg16, iCb16;
  679. mng_uint8 iCr8, iCg8, iCb8;
  680. #ifdef MNG_SUPPORT_TRACE
  681. MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_START);
  682. #endif
  683. /* viewable row ? */
  684. if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
  685. { /* address destination row */
  686. pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
  687. pData->iRow + pData->iDestt -
  688. pData->iSourcet);
  689. /* adjust destination row starting-point */
  690. pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
  691. pDataline = pData->pRGBArow; /* address source row */
  692. if (pData->bIsRGBA16) /* adjust source row starting-point */
  693. pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 3);
  694. else
  695. pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << 2);
  696. if (pData->bIsOpaque) /* forget about transparency ? */
  697. {
  698. if (pData->bIsRGBA16) /* 16-bit input row ? */
  699. {
  700. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  701. iX += pData->iColinc)
  702. { /* scale down by dropping the LSB */
  703. *pScanline = *pDataline;
  704. *(pScanline+1) = *(pDataline+2);
  705. *(pScanline+2) = *(pDataline+4);
  706. *(pScanline+3) = *(pDataline+6);
  707. pScanline += (pData->iColinc << 2);
  708. pDataline += 8;
  709. }
  710. }
  711. else
  712. {
  713. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  714. iX += pData->iColinc)
  715. { /* copy the values */
  716. *pScanline = *pDataline;
  717. *(pScanline+1) = *(pDataline+1);
  718. *(pScanline+2) = *(pDataline+2);
  719. *(pScanline+3) = *(pDataline+3);
  720. pScanline += (pData->iColinc << 2);
  721. pDataline += 4;
  722. }
  723. }
  724. }
  725. else
  726. {
  727. if (pData->bIsRGBA16) /* 16-bit input row ? */
  728. {
  729. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  730. iX += pData->iColinc)
  731. { /* get alpha values */
  732. iFGa16 = mng_get_uint16 (pDataline+6);
  733. iBGa16 = (mng_uint16)(*(pScanline+3));
  734. iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
  735. if (iFGa16) /* any opacity at all ? */
  736. { /* fully opaque or background fully transparent ? */
  737. if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
  738. { /* plain copy it */
  739. *pScanline = *pDataline;
  740. *(pScanline+1) = *(pDataline+2);
  741. *(pScanline+2) = *(pDataline+4);
  742. *(pScanline+3) = *(pDataline+6);
  743. }
  744. else
  745. {
  746. if (iBGa16 == 0xFFFF) /* background fully opaque ? */
  747. { /* get the proper values */
  748. iFGr16 = mng_get_uint16 (pDataline );
  749. iFGg16 = mng_get_uint16 (pDataline+2);
  750. iFGb16 = mng_get_uint16 (pDataline+4);
  751. /* scale background up */
  752. iBGr16 = (mng_uint16)(*pScanline );
  753. iBGg16 = (mng_uint16)(*(pScanline+1));
  754. iBGb16 = (mng_uint16)(*(pScanline+2));
  755. iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
  756. iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
  757. iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
  758. /* now compose */
  759. MNG_COMPOSE16(iFGr16, iFGr16, iFGa16, iBGr16);
  760. MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
  761. MNG_COMPOSE16(iFGb16, iFGb16, iFGa16, iBGb16);
  762. /* and return the composed values */
  763. *pScanline = (mng_uint8)(iFGr16 >> 8);
  764. *(pScanline+1) = (mng_uint8)(iFGg16 >> 8);
  765. *(pScanline+2) = (mng_uint8)(iFGb16 >> 8);
  766. /* alpha remains fully opaque !!! */
  767. }
  768. else
  769. { /* scale background up */
  770. iBGr16 = (mng_uint16)(*pScanline );
  771. iBGg16 = (mng_uint16)(*(pScanline+1));
  772. iBGb16 = (mng_uint16)(*(pScanline+2));
  773. iBGr16 = (mng_uint16)((mng_uint32)iBGr16 << 8) | iBGr16;
  774. iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
  775. iBGb16 = (mng_uint16)((mng_uint32)iBGb16 << 8) | iBGb16;
  776. /* let's blend */
  777. MNG_BLEND16 (mng_get_uint16 (pDataline ),
  778. mng_get_uint16 (pDataline+2),
  779. mng_get_uint16 (pDataline+4), iFGa16,
  780. iBGr16, iBGg16, iBGb16, iBGa16,
  781. iCr16, iCg16, iCb16, iCa16);
  782. /* and return the composed values */
  783. *pScanline = (mng_uint8)(iCr16 >> 8);
  784. *(pScanline+1) = (mng_uint8)(iCg16 >> 8);
  785. *(pScanline+2) = (mng_uint8)(iCb16 >> 8);
  786. *(pScanline+3) = (mng_uint8)(iCa16 >> 8);
  787. }
  788. }
  789. }
  790. pScanline += (pData->iColinc << 2);
  791. pDataline += 8;
  792. }
  793. }
  794. else
  795. {
  796. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  797. iX += pData->iColinc)
  798. {
  799. iFGa8 = *(pDataline+3); /* get alpha values */
  800. iBGa8 = *(pScanline+3);
  801. if (iFGa8) /* any opacity at all ? */
  802. { /* fully opaque or background fully transparent ? */
  803. if ((iFGa8 == 0xFF) || (iBGa8 == 0))
  804. { /* then simply copy the values */
  805. *pScanline = *pDataline;
  806. *(pScanline+1) = *(pDataline+1);
  807. *(pScanline+2) = *(pDataline+2);
  808. *(pScanline+3) = *(pDataline+3);
  809. }
  810. else
  811. {
  812. if (iBGa8 == 0xFF) /* background fully opaque ? */
  813. { /* do alpha composing */
  814. MNG_COMPOSE8 (*pScanline, *pDataline, iFGa8, *pScanline );
  815. MNG_COMPOSE8 (*(pScanline+1), *(pDataline+1), iFGa8, *(pScanline+1));
  816. MNG_COMPOSE8 (*(pScanline+2), *(pDataline+2), iFGa8, *(pScanline+2));
  817. /* alpha remains fully opaque !!! */
  818. }
  819. else
  820. { /* now blend */
  821. MNG_BLEND8 (*pDataline, *(pDataline+1), *(pDataline+2), iFGa8,
  822. *pScanline, *(pScanline+1), *(pScanline+2), iBGa8,
  823. iCr8, iCg8, iCb8, iCa8);
  824. /* and return the composed values */
  825. *pScanline = iCr8;
  826. *(pScanline+1) = iCg8;
  827. *(pScanline+2) = iCb8;
  828. *(pScanline+3) = iCa8;
  829. }
  830. }
  831. }
  832. pScanline += (pData->iColinc << 2);
  833. pDataline += 4;
  834. }
  835. }
  836. }
  837. }
  838. check_update_region (pData);
  839. #ifdef MNG_SUPPORT_TRACE
  840. MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_END);
  841. #endif
  842. return MNG_NOERROR;
  843. }
  844. #else /* MNG_OPTIMIZE_FOOTPRINT_COMPOSE */
  845. mng_retcode mng_display_rgba8 (mng_datap pData)
  846. {
  847. mng_uint8p pScanline;
  848. mng_uint8p pDataline;
  849. mng_int32 iX;
  850. mng_uint8 iFGa8, iBGa8, iCa8;
  851. mng_uint16 iFGa16, iBGa16, iCa16;
  852. mng_uint16 iFGg16;
  853. mng_uint16 iBGr16, iBGg16, iBGb16;
  854. mng_uint16 iCr16, iCg16, iCb16;
  855. mng_uint8 iCr8, iCg8, iCb8;
  856. mng_uint8 iBps;
  857. #ifdef MNG_SUPPORT_TRACE
  858. MNG_TRACE (pData, MNG_FN_DISPLAY_RGBA8, MNG_LC_START);
  859. #endif
  860. iBps=(mng_uint8)(pData->bIsRGBA16 ? 2:1);
  861. /* viewable row ? */
  862. if ((pData->iRow >= pData->iSourcet) && (pData->iRow < pData->iSourceb))
  863. { /* address destination row */
  864. pScanline = (mng_uint8p)pData->fGetcanvasline (((mng_handle)pData),
  865. pData->iRow + pData->iDestt -
  866. pData->iSourcet);
  867. /* adjust destination row starting-point */
  868. pScanline = pScanline + (pData->iCol << 2) + (pData->iDestl << 2);
  869. pDataline = pData->pRGBArow; /* address source row */
  870. /* adjust source row starting-point */
  871. pDataline = pDataline + ((pData->iSourcel / pData->iColinc) << (iBps+1));
  872. if (pData->bIsOpaque) /* forget about transparency ? */
  873. {
  874. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  875. iX += pData->iColinc)
  876. { /* scale down by dropping the LSB */
  877. *pScanline = *pDataline;
  878. *(pScanline+1) = *(pDataline+iBps);
  879. *(pScanline+2) = *(pDataline+2*iBps);
  880. *(pScanline+3) = *(pDataline+3*iBps);
  881. pScanline += (pData->iColinc << 2);
  882. pDataline += 4*iBps;
  883. }
  884. }
  885. else
  886. {
  887. if (pData->bIsRGBA16) /* 16-bit input row ? */
  888. {
  889. for (iX = pData->iSourcel + pData->iCol; iX < pData->iSourcer;
  890. iX += pData->iColinc)
  891. { /* get alpha values */
  892. iFGa16 = mng_get_uint16 (pDataline+6);
  893. iBGa16 = (mng_uint16)(*(pScanline+3));
  894. iBGa16 = (mng_uint16)(iBGa16 << 8) | iBGa16;
  895. if (iFGa16) /* any opacity at all ? */
  896. { /* fully opaque or background fully transparent ? */
  897. if ((iFGa16 == 0xFFFF) || (iBGa16 == 0))
  898. { /* plain copy it */
  899. *pScanline = *pDataline;
  900. *(pScanline+1) = *(pDataline+2);
  901. *(pScanline+2) = *(pDataline+4);
  902. *(pScanline+3) = *(pDataline+6);
  903. }
  904. else
  905. {
  906. if (iBGa16 == 0xFFFF) /* background fully opaque ? */
  907. { /* get the proper values */
  908. int i;
  909. for (i=2; i >= 0; i--)
  910. {
  911. iFGg16 = mng_get_uint16 (pDataline+i+i);
  912. /* scale background up */
  913. iBGg16 = (mng_uint16)(*(pScanline+i));
  914. iBGg16 = (mng_uint16)((mng_uint32)iBGg16 << 8) | iBGg16;
  915. /* now compose */
  916. MNG_COMPOSE16(iFGg16, iFGg16, iFGa16, iBGg16);
  917. /* and return the composed values */
  918. *(pScanline+i) = (mng_uint8)(iFGg16 >> 8);
  919. /* alpha remains fully opaque !!! */
  920. }
  921. }
  922. else
  923. { /* scale background up */
  924. iBGr16 = (mng_uint16)(*pScanline );
  925. iBGg16 = (mng_uint16)(*(pScanline+1));

Large files files are truncated, but you can click here to view the full file