PageRenderTime 48ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 1ms

/src/FreeImage/Source/LibMNG/libmng_object_prc.c

https://bitbucket.org/cabalistic/ogredeps/
C | 1749 lines | 1353 code | 180 blank | 216 comment | 315 complexity | d56ffb7f9062f3e156cdb829c2ad50c8 MD5 | raw file
Possible License(s): LGPL-3.0, BSD-3-Clause, CPL-1.0, Unlicense, GPL-2.0, GPL-3.0, LGPL-2.0, MPL-2.0-no-copyleft-exception, BSD-2-Clause, LGPL-2.1
  1. /* ************************************************************************** */
  2. /* * For conditions of distribution and use, * */
  3. /* * see copyright notice in libmng.h * */
  4. /* ************************************************************************** */
  5. /* * * */
  6. /* * project : libmng * */
  7. /* * file : libmng_object_prc.c copyright (c) 2000-2007 G.Juyn * */
  8. /* * version : 1.0.10 * */
  9. /* * * */
  10. /* * purpose : Object processing routines (implementation) * */
  11. /* * * */
  12. /* * author : G.Juyn * */
  13. /* * * */
  14. /* * comment : implementation of the internal object processing routines * */
  15. /* * * */
  16. /* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
  17. /* * - changed strict-ANSI stuff * */
  18. /* * 0.5.1 - 05/12/2000 - G.Juyn * */
  19. /* * - changed trace to macro for callback error-reporting * */
  20. /* * * */
  21. /* * 0.5.2 - 05/20/2000 - G.Juyn * */
  22. /* * - fixed to support JNG objects * */
  23. /* * 0.5.2 - 05/24/2000 - G.Juyn * */
  24. /* * - added support for global color-chunks in animation * */
  25. /* * - added support for global PLTE,tRNS,bKGD in animation * */
  26. /* * - added SAVE & SEEK animation objects * */
  27. /* * 0.5.2 - 05/29/2000 - G.Juyn * */
  28. /* * - added initialization of framenr/layernr/playtime * */
  29. /* * - changed ani_object create routines not to return the * */
  30. /* * created object (wasn't necessary) * */
  31. /* * 0.5.2 - 05/30/2000 - G.Juyn * */
  32. /* * - added object promotion routine (PROM handling) * */
  33. /* * - added ani-object routines for delta-image processing * */
  34. /* * - added compression/filter/interlace fields to * */
  35. /* * object-buffer for delta-image processing * */
  36. /* * * */
  37. /* * 0.5.3 - 06/17/2000 - G.Juyn * */
  38. /* * - changed support for delta-image processing * */
  39. /* * 0.5.3 - 06/20/2000 - G.Juyn * */
  40. /* * - fixed some small things (as precaution) * */
  41. /* * 0.5.3 - 06/21/2000 - G.Juyn * */
  42. /* * - added processing of PLTE/tRNS & color-info for * */
  43. /* * delta-images in the ani_objects chain * */
  44. /* * 0.5.3 - 06/22/2000 - G.Juyn * */
  45. /* * - added support for PPLT chunk * */
  46. /* * * */
  47. /* * 0.9.1 - 07/07/2000 - G.Juyn * */
  48. /* * - added support for freeze/restart/resume & go_xxxx * */
  49. /* * 0.9.1 - 07/16/2000 - G.Juyn * */
  50. /* * - fixed support for mng_display() after mng_read() * */
  51. /* * * */
  52. /* * 0.9.2 - 07/29/2000 - G.Juyn * */
  53. /* * - fixed small bugs in display processing * */
  54. /* * 0.9.2 - 08/05/2000 - G.Juyn * */
  55. /* * - changed file-prefixes * */
  56. /* * * */
  57. /* * 0.9.3 - 08/07/2000 - G.Juyn * */
  58. /* * - B111300 - fixup for improved portability * */
  59. /* * 0.9.3 - 08/26/2000 - G.Juyn * */
  60. /* * - added MAGN chunk * */
  61. /* * 0.9.3 - 09/10/2000 - G.Juyn * */
  62. /* * - fixed DEFI behavior * */
  63. /* * 0.9.3 - 10/17/2000 - G.Juyn * */
  64. /* * - added valid-flag to stored objects for read() / display()* */
  65. /* * - added routine to discard "invalid" objects * */
  66. /* * 0.9.3 - 10/18/2000 - G.Juyn * */
  67. /* * - fixed delta-processing behavior * */
  68. /* * 0.9.3 - 10/19/2000 - G.Juyn * */
  69. /* * - added storage for pixel-/alpha-sampledepth for delta's * */
  70. /* * * */
  71. /* * 0.9.4 - 1/18/2001 - G.Juyn * */
  72. /* * - removed "old" MAGN methods 3 & 4 * */
  73. /* * - added "new" MAGN methods 3, 4 & 5 * */
  74. /* * * */
  75. /* * 0.9.5 - 1/22/2001 - G.Juyn * */
  76. /* * - B129681 - fixed compiler warnings SGI/Irix * */
  77. /* * * */
  78. /* * 1.0.2 - 06/23/2001 - G.Juyn * */
  79. /* * - added optimization option for MNG-video playback * */
  80. /* * * */
  81. /* * 1.0.5 - 08/15/2002 - G.Juyn * */
  82. /* * - completed PROM support * */
  83. /* * 1.0.5 - 08/16/2002 - G.Juyn * */
  84. /* * - completed MAGN support (16-bit functions) * */
  85. /* * 1.0.5 - 08/19/2002 - G.Juyn * */
  86. /* * - B597134 - libmng pollutes the linker namespace * */
  87. /* * 1.0.5 - 09/13/2002 - G.Juyn * */
  88. /* * - fixed read/write of MAGN chunk * */
  89. /* * 1.0.5 - 09/15/2002 - G.Juyn * */
  90. /* * - added event handling for dynamic MNG * */
  91. /* * 1.0.5 - 09/20/2002 - G.Juyn * */
  92. /* * - added support for PAST * */
  93. /* * 1.0.5 - 09/23/2002 - G.Juyn * */
  94. /* * - fixed reset_object_detail to clear old buffer * */
  95. /* * - added in-memory color-correction of abstract images * */
  96. /* * 1.0.5 - 10/05/2002 - G.Juyn * */
  97. /* * - fixed problem with cloned objects marked as invalid * */
  98. /* * - fixed problem cloning frozen object_buffers * */
  99. /* * 1.0.5 - 10/07/2002 - G.Juyn * */
  100. /* * - fixed DISC support * */
  101. /* * 1.0.5 - 11/04/2002 - G.Juyn * */
  102. /* * - fixed goframe/golayer/gotime processing * */
  103. /* * 1.0.5 - 11/07/2002 - G.Juyn * */
  104. /* * - fixed magnification bug with object 0 * */
  105. /* * 1.0.5 - 01/19/2003 - G.Juyn * */
  106. /* * - B664911 - fixed buffer overflow during init * */
  107. /* * * */
  108. /* * 1.0.6 - 04/19/2003 - G.Juyn * */
  109. /* * - fixed problem with infinite loops during readdisplay() * */
  110. /* * 1.0.6 - 05/25/2003 - G.R-P * */
  111. /* * - added MNG_SKIPCHUNK_cHNK footprint optimizations * */
  112. /* * 1.0.6 - 06/09/2003 - G. R-P * */
  113. /* * - added conditionals around 8-bit magn routines * */
  114. /* * 1.0.6 - 07/07/2003 - G.R-P * */
  115. /* * - added conditionals around some JNG-supporting code * */
  116. /* * - removed conditionals around 8-bit magn routines * */
  117. /* * - added conditionals around delta-png and 16-bit code * */
  118. /* * 1.0.6 - 07/14/2003 - G.R-P * */
  119. /* * - added MNG_NO_LOOP_SIGNALS_SUPPORTED conditional * */
  120. /* * 1.0.6 - 07/29/2003 - G.Juyn * */
  121. /* * - fixed invalid test in promote_imageobject * */
  122. /* * 1.0.6 - 07/29/2003 - G.R-P. * */
  123. /* * - added conditionals around PAST chunk support * */
  124. /* * 1.0.6 - 08/17/2003 - G.R-P. * */
  125. /* * - added conditionals around MAGN chunk support * */
  126. /* * * */
  127. /* * 1.0.7 - 03/21/2004 - G.Juyn * */
  128. /* * - fixed some 64-bit platform compiler warnings * */
  129. /* * * */
  130. /* * 1.0.9 - 10/10/2004 - G.R-P. * */
  131. /* * - added MNG_NO_1_2_4BIT_SUPPORT support * */
  132. /* * 1.0.9 - 12/05/2004 - G.Juyn * */
  133. /* * - added conditional MNG_OPTIMIZE_OBJCLEANUP * */
  134. /* * 1.0.9 - 12/11/2004 - G.Juyn * */
  135. /* * - added conditional MNG_OPTIMIZE_DISPLAYCALLS * */
  136. /* * 1.0.9 - 12/31/2004 - G.R-P. * */
  137. /* * - fixed warnings about possible uninitialized pointers * */
  138. /* * 1.0.9 - 01/02/2005 - G.Juyn * */
  139. /* * - fixing some compiler-warnings * */
  140. /* * * */
  141. /* * 1.0.10 - 02/07/2005 - G.Juyn * */
  142. /* * - fixed some compiler-warnings * */
  143. /* * 1.0.10 - 07/30/2005 - G.Juyn * */
  144. /* * - fixed problem with CLON object during readdisplay() * */
  145. /* * 1.0.10 - 04/08/2007 - G.Juyn * */
  146. /* * - added support for mPNG proposal * */
  147. /* * 1.0.10 - 04/12/2007 - G.Juyn * */
  148. /* * - added support for ANG proposal * */
  149. /* * * */
  150. /* ************************************************************************** */
  151. #include "libmng.h"
  152. #include "libmng_data.h"
  153. #include "libmng_error.h"
  154. #include "libmng_trace.h"
  155. #ifdef __BORLANDC__
  156. #pragma hdrstop
  157. #endif
  158. #include "libmng_memory.h"
  159. #include "libmng_chunks.h"
  160. #include "libmng_objects.h"
  161. #include "libmng_display.h"
  162. #include "libmng_pixels.h"
  163. #include "libmng_object_prc.h"
  164. #include "libmng_cms.h"
  165. #if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
  166. #pragma option -A /* force ANSI-C */
  167. #endif
  168. /* ************************************************************************** */
  169. #ifdef MNG_INCLUDE_DISPLAY_PROCS
  170. /* ************************************************************************** */
  171. /* * * */
  172. /* * Generic object routines * */
  173. /* * * */
  174. /* ************************************************************************** */
  175. mng_retcode mng_drop_invalid_objects (mng_datap pData)
  176. {
  177. mng_objectp pObject;
  178. mng_objectp pNext;
  179. mng_cleanupobject fCleanup;
  180. #ifdef MNG_SUPPORT_TRACE
  181. MNG_TRACE (pData, MNG_FN_DROP_INVALID_OBJECTS, MNG_LC_START);
  182. #endif
  183. pObject = pData->pFirstimgobj; /* get first stored image-object (if any) */
  184. while (pObject) /* more objects to check ? */
  185. {
  186. pNext = ((mng_object_headerp)pObject)->pNext;
  187. /* invalid ? */
  188. if (!((mng_imagep)pObject)->bValid)
  189. { /* call appropriate cleanup */
  190. fCleanup = ((mng_object_headerp)pObject)->fCleanup;
  191. fCleanup (pData, pObject);
  192. }
  193. pObject = pNext; /* neeeext */
  194. }
  195. #ifdef MNG_SUPPORT_TRACE
  196. MNG_TRACE (pData, MNG_FN_DROP_INVALID_OBJECTS, MNG_LC_END);
  197. #endif
  198. return MNG_NOERROR;
  199. }
  200. /* ************************************************************************** */
  201. #ifdef MNG_OPTIMIZE_OBJCLEANUP
  202. MNG_LOCAL mng_retcode create_obj_general (mng_datap pData,
  203. mng_size_t iObjsize,
  204. mng_cleanupobject fCleanup,
  205. mng_processobject fProcess,
  206. mng_ptr *ppObject)
  207. {
  208. mng_object_headerp pWork;
  209. MNG_ALLOC (pData, pWork, iObjsize);
  210. pWork->fCleanup = fCleanup;
  211. pWork->fProcess = fProcess;
  212. pWork->iObjsize = iObjsize;
  213. *ppObject = (mng_ptr)pWork;
  214. return MNG_NOERROR;
  215. }
  216. /* ************************************************************************** */
  217. MNG_LOCAL mng_retcode mng_free_obj_general (mng_datap pData,
  218. mng_objectp pObject)
  219. {
  220. MNG_FREEX (pData, pObject, ((mng_object_headerp)pObject)->iObjsize);
  221. return MNG_NOERROR;
  222. }
  223. #endif
  224. /* ************************************************************************** */
  225. /* * * */
  226. /* * Image-data-object routines * */
  227. /* * * */
  228. /* * these handle the "object buffer" as defined by the MNG specification * */
  229. /* * * */
  230. /* ************************************************************************** */
  231. mng_retcode mng_create_imagedataobject (mng_datap pData,
  232. mng_bool bConcrete,
  233. mng_bool bViewable,
  234. mng_uint32 iWidth,
  235. mng_uint32 iHeight,
  236. mng_uint8 iBitdepth,
  237. mng_uint8 iColortype,
  238. mng_uint8 iCompression,
  239. mng_uint8 iFilter,
  240. mng_uint8 iInterlace,
  241. mng_imagedatap *ppObject)
  242. {
  243. mng_imagedatap pImagedata;
  244. mng_uint32 iSamplesize = 0;
  245. #ifdef MNG_SUPPORT_TRACE
  246. MNG_TRACE (pData, MNG_FN_CREATE_IMGDATAOBJECT, MNG_LC_START);
  247. #endif
  248. /* get a buffer */
  249. #ifdef MNG_OPTIMIZE_OBJCLEANUP
  250. {
  251. mng_ptr pTemp;
  252. mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_imagedata),
  253. (mng_cleanupobject)mng_free_imagedataobject,
  254. MNG_NULL, &pTemp);
  255. if (iRetcode)
  256. return iRetcode;
  257. pImagedata = (mng_imagedatap)pTemp;
  258. }
  259. #else
  260. MNG_ALLOC (pData, pImagedata, sizeof (mng_imagedata));
  261. /* fill the appropriate fields */
  262. pImagedata->sHeader.fCleanup = (mng_cleanupobject)mng_free_imagedataobject;
  263. pImagedata->sHeader.fProcess = MNG_NULL;
  264. #endif
  265. pImagedata->iRefcount = 1;
  266. pImagedata->bFrozen = MNG_FALSE;
  267. pImagedata->bConcrete = bConcrete;
  268. pImagedata->bViewable = bViewable;
  269. pImagedata->iWidth = iWidth;
  270. pImagedata->iHeight = iHeight;
  271. pImagedata->iBitdepth = iBitdepth;
  272. pImagedata->iColortype = iColortype;
  273. pImagedata->iCompression = iCompression;
  274. pImagedata->iFilter = iFilter;
  275. pImagedata->iInterlace = iInterlace;
  276. pImagedata->bCorrected = MNG_FALSE;
  277. pImagedata->iAlphabitdepth = 0;
  278. pImagedata->iJHDRcompression = 0;
  279. pImagedata->iJHDRinterlace = 0;
  280. pImagedata->iPixelsampledepth = iBitdepth;
  281. pImagedata->iAlphasampledepth = iBitdepth;
  282. /* determine samplesize from color_type/bit_depth */
  283. switch (iColortype) /* for < 8-bit samples we just reserve 8 bits */
  284. {
  285. case 0 : ; /* gray */
  286. case 8 : { /* JPEG gray */
  287. #ifndef MNG_NO_16BIT_SUPPORT
  288. if (iBitdepth > 8)
  289. iSamplesize = 2;
  290. else
  291. #endif
  292. iSamplesize = 1;
  293. break;
  294. }
  295. case 2 : ; /* rgb */
  296. case 10 : { /* JPEG rgb */
  297. #ifndef MNG_NO_16BIT_SUPPORT
  298. if (iBitdepth > 8)
  299. iSamplesize = 6;
  300. else
  301. #endif
  302. iSamplesize = 3;
  303. break;
  304. }
  305. case 3 : { /* indexed */
  306. iSamplesize = 1;
  307. break;
  308. }
  309. case 4 : ; /* gray+alpha */
  310. case 12 : { /* JPEG gray+alpha */
  311. #ifndef MNG_NO_16BIT_SUPPORT
  312. if (iBitdepth > 8)
  313. iSamplesize = 4;
  314. else
  315. #endif
  316. iSamplesize = 2;
  317. break;
  318. }
  319. case 6 : ; /* rgb+alpha */
  320. case 14 : { /* JPEG rgb+alpha */
  321. #ifndef MNG_NO_16BIT_SUPPORT
  322. if (iBitdepth > 8)
  323. iSamplesize = 8;
  324. else
  325. #endif
  326. iSamplesize = 4;
  327. break;
  328. }
  329. }
  330. /* make sure we remember all this */
  331. pImagedata->iSamplesize = iSamplesize;
  332. pImagedata->iRowsize = iSamplesize * iWidth;
  333. pImagedata->iImgdatasize = pImagedata->iRowsize * iHeight;
  334. if (pImagedata->iImgdatasize) /* need a buffer ? */
  335. { /* so allocate it */
  336. MNG_ALLOCX (pData, pImagedata->pImgdata, pImagedata->iImgdatasize);
  337. if (!pImagedata->pImgdata) /* enough memory ? */
  338. {
  339. MNG_FREEX (pData, pImagedata, sizeof (mng_imagedata));
  340. MNG_ERROR (pData, MNG_OUTOFMEMORY);
  341. }
  342. }
  343. /* check global stuff */
  344. pImagedata->bHasGAMA = pData->bHasglobalGAMA;
  345. #ifndef MNG_SKIPCHUNK_cHRM
  346. pImagedata->bHasCHRM = pData->bHasglobalCHRM;
  347. #endif
  348. pImagedata->bHasSRGB = pData->bHasglobalSRGB;
  349. #ifndef MNG_SKIPCHUNK_iCCP
  350. pImagedata->bHasICCP = pData->bHasglobalICCP;
  351. #endif
  352. #ifndef MNG_SKIPCHUNK_bKGD
  353. pImagedata->bHasBKGD = pData->bHasglobalBKGD;
  354. #endif
  355. if (pData->bHasglobalGAMA) /* global gAMA present ? */
  356. pImagedata->iGamma = pData->iGlobalGamma;
  357. #ifndef MNG_SKIPCHUNK_cHRM
  358. if (pData->bHasglobalCHRM) /* global cHRM present ? */
  359. {
  360. pImagedata->iWhitepointx = pData->iGlobalWhitepointx;
  361. pImagedata->iWhitepointy = pData->iGlobalWhitepointy;
  362. pImagedata->iPrimaryredx = pData->iGlobalPrimaryredx;
  363. pImagedata->iPrimaryredy = pData->iGlobalPrimaryredy;
  364. pImagedata->iPrimarygreenx = pData->iGlobalPrimarygreenx;
  365. pImagedata->iPrimarygreeny = pData->iGlobalPrimarygreeny;
  366. pImagedata->iPrimarybluex = pData->iGlobalPrimarybluex;
  367. pImagedata->iPrimarybluey = pData->iGlobalPrimarybluey;
  368. }
  369. #endif
  370. if (pData->bHasglobalSRGB) /* glbal sRGB present ? */
  371. pImagedata->iRenderingintent = pData->iGlobalRendintent;
  372. #ifndef MNG_SKIPCHUNK_iCCP
  373. if (pData->bHasglobalICCP) /* glbal iCCP present ? */
  374. {
  375. pImagedata->iProfilesize = pData->iGlobalProfilesize;
  376. if (pImagedata->iProfilesize)
  377. {
  378. MNG_ALLOCX (pData, pImagedata->pProfile, pImagedata->iProfilesize);
  379. if (!pImagedata->pProfile) /* enough memory ? */
  380. {
  381. MNG_FREEX (pData, pImagedata->pImgdata, pImagedata->iImgdatasize);
  382. MNG_FREEX (pData, pImagedata, sizeof (mng_imagedata));
  383. MNG_ERROR (pData, MNG_OUTOFMEMORY);
  384. }
  385. MNG_COPY (pImagedata->pProfile, pData->pGlobalProfile, pImagedata->iProfilesize);
  386. }
  387. }
  388. #endif
  389. #ifndef MNG_SKIPCHUNK_bKGD
  390. if (pData->bHasglobalBKGD) /* global bKGD present ? */
  391. {
  392. pImagedata->iBKGDred = pData->iGlobalBKGDred;
  393. pImagedata->iBKGDgreen = pData->iGlobalBKGDgreen;
  394. pImagedata->iBKGDblue = pData->iGlobalBKGDblue;
  395. }
  396. #endif
  397. *ppObject = pImagedata; /* return it */
  398. #ifdef MNG_SUPPORT_TRACE
  399. MNG_TRACE (pData, MNG_FN_CREATE_IMGDATAOBJECT, MNG_LC_END);
  400. #endif
  401. return MNG_NOERROR;
  402. }
  403. /* ************************************************************************** */
  404. mng_retcode mng_free_imagedataobject (mng_datap pData,
  405. mng_imagedatap pImagedata)
  406. {
  407. #ifdef MNG_SUPPORT_TRACE
  408. MNG_TRACE (pData, MNG_FN_FREE_IMGDATAOBJECT, MNG_LC_START);
  409. #endif
  410. if (pImagedata->iRefcount) /* decrease reference count */
  411. pImagedata->iRefcount--;
  412. if (!pImagedata->iRefcount) /* reached zero ? */
  413. {
  414. #ifndef MNG_SKIPCHUNK_iCCP
  415. if (pImagedata->iProfilesize) /* stored an iCCP profile ? */
  416. MNG_FREEX (pData, pImagedata->pProfile, pImagedata->iProfilesize);
  417. #endif
  418. if (pImagedata->iImgdatasize) /* sample-buffer present ? */
  419. MNG_FREEX (pData, pImagedata->pImgdata, pImagedata->iImgdatasize);
  420. /* drop the buffer */
  421. MNG_FREEX (pData, pImagedata, sizeof (mng_imagedata));
  422. }
  423. #ifdef MNG_SUPPORT_TRACE
  424. MNG_TRACE (pData, MNG_FN_FREE_IMGDATAOBJECT, MNG_LC_END);
  425. #endif
  426. return MNG_NOERROR;
  427. }
  428. /* ************************************************************************** */
  429. mng_retcode mng_clone_imagedataobject (mng_datap pData,
  430. mng_bool bConcrete,
  431. mng_imagedatap pSource,
  432. mng_imagedatap *ppClone)
  433. {
  434. mng_imagedatap pNewdata;
  435. #ifdef MNG_SUPPORT_TRACE
  436. MNG_TRACE (pData, MNG_FN_CLONE_IMGDATAOBJECT, MNG_LC_START);
  437. #endif
  438. /* get a buffer */
  439. MNG_ALLOC (pData, pNewdata, sizeof (mng_imagedata));
  440. /* blatently copy the original buffer */
  441. MNG_COPY (pNewdata, pSource, sizeof (mng_imagedata));
  442. pNewdata->iRefcount = 1; /* only the reference count */
  443. pNewdata->bConcrete = bConcrete; /* and concrete-flag are different */
  444. pNewdata->bFrozen = MNG_FALSE;
  445. if (pNewdata->iImgdatasize) /* sample buffer present ? */
  446. {
  447. MNG_ALLOCX (pData, pNewdata->pImgdata, pNewdata->iImgdatasize);
  448. if (!pNewdata->pImgdata) /* not enough memory ? */
  449. {
  450. MNG_FREEX (pData, pNewdata, sizeof (mng_imagedata));
  451. MNG_ERROR (pData, MNG_OUTOFMEMORY);
  452. }
  453. /* make a copy */
  454. MNG_COPY (pNewdata->pImgdata, pSource->pImgdata, pNewdata->iImgdatasize);
  455. }
  456. #ifndef MNG_SKIPCHUNK_iCCP
  457. if (pNewdata->iProfilesize) /* iCCP profile present ? */
  458. {
  459. MNG_ALLOCX (pData, pNewdata->pProfile, pNewdata->iProfilesize);
  460. if (!pNewdata->pProfile) /* enough memory ? */
  461. {
  462. MNG_FREEX (pData, pNewdata, sizeof (mng_imagedata));
  463. MNG_ERROR (pData, MNG_OUTOFMEMORY);
  464. }
  465. /* make a copy */
  466. MNG_COPY (pNewdata->pProfile, pSource->pProfile, pNewdata->iProfilesize);
  467. }
  468. #endif
  469. *ppClone = pNewdata; /* return the clone */
  470. #ifdef MNG_SUPPORT_TRACE
  471. MNG_TRACE (pData, MNG_FN_CLONE_IMGDATAOBJECT, MNG_LC_END);
  472. #endif
  473. return MNG_NOERROR;
  474. }
  475. /* ************************************************************************** */
  476. /* * * */
  477. /* * Image-object routines * */
  478. /* * * */
  479. /* * these handle the "object" as defined by the MNG specification * */
  480. /* * * */
  481. /* ************************************************************************** */
  482. mng_retcode mng_create_imageobject (mng_datap pData,
  483. mng_uint16 iId,
  484. mng_bool bConcrete,
  485. mng_bool bVisible,
  486. mng_bool bViewable,
  487. mng_uint32 iWidth,
  488. mng_uint32 iHeight,
  489. mng_uint8 iBitdepth,
  490. mng_uint8 iColortype,
  491. mng_uint8 iCompression,
  492. mng_uint8 iFilter,
  493. mng_uint8 iInterlace,
  494. mng_int32 iPosx,
  495. mng_int32 iPosy,
  496. mng_bool bClipped,
  497. mng_int32 iClipl,
  498. mng_int32 iClipr,
  499. mng_int32 iClipt,
  500. mng_int32 iClipb,
  501. mng_imagep *ppObject)
  502. {
  503. mng_imagep pImage;
  504. mng_imagep pPrev, pNext;
  505. mng_retcode iRetcode;
  506. mng_imagedatap pImgbuf;
  507. #ifdef MNG_SUPPORT_TRACE
  508. MNG_TRACE (pData, MNG_FN_CREATE_IMGOBJECT, MNG_LC_START);
  509. #endif
  510. /* get a buffer */
  511. MNG_ALLOC (pData, pImage, sizeof (mng_image));
  512. /* now get a new "object buffer" */
  513. iRetcode = mng_create_imagedataobject (pData, bConcrete, bViewable,
  514. iWidth, iHeight, iBitdepth, iColortype,
  515. iCompression, iFilter, iInterlace,
  516. &pImgbuf);
  517. if (iRetcode) /* on error bail out */
  518. {
  519. MNG_FREEX (pData, pImage, sizeof (mng_image));
  520. return iRetcode;
  521. }
  522. /* fill the appropriate fields */
  523. pImage->sHeader.fCleanup = (mng_cleanupobject)mng_free_imageobject;
  524. pImage->sHeader.fProcess = MNG_NULL;
  525. #ifdef MNG_OPTIMIZE_OBJCLEANUP
  526. pImage->sHeader.iObjsize = sizeof (mng_image);
  527. #endif
  528. pImage->iId = iId;
  529. pImage->bFrozen = MNG_FALSE;
  530. pImage->bVisible = bVisible;
  531. pImage->bViewable = bViewable;
  532. pImage->bValid = (mng_bool)((pData->bDisplaying) &&
  533. ((pData->bRunning) || (pData->bSearching)) &&
  534. (!pData->bFreezing));
  535. pImage->iPosx = iPosx;
  536. pImage->iPosy = iPosy;
  537. pImage->bClipped = bClipped;
  538. pImage->iClipl = iClipl;
  539. pImage->iClipr = iClipr;
  540. pImage->iClipt = iClipt;
  541. pImage->iClipb = iClipb;
  542. #ifndef MNG_SKIPCHUNK_MAGN
  543. pImage->iMAGN_MethodX = 0;
  544. pImage->iMAGN_MethodY = 0;
  545. pImage->iMAGN_MX = 0;
  546. pImage->iMAGN_MY = 0;
  547. pImage->iMAGN_ML = 0;
  548. pImage->iMAGN_MR = 0;
  549. pImage->iMAGN_MT = 0;
  550. pImage->iMAGN_MB = 0;
  551. #endif
  552. #ifndef MNG_SKIPCHUNK_PAST
  553. pImage->iPastx = 0;
  554. pImage->iPasty = 0;
  555. #endif
  556. pImage->pImgbuf = pImgbuf;
  557. if (iId) /* only if not object 0 ! */
  558. { /* find previous lower object-id */
  559. pPrev = (mng_imagep)pData->pLastimgobj;
  560. while ((pPrev) && (pPrev->iId > iId))
  561. pPrev = (mng_imagep)pPrev->sHeader.pPrev;
  562. if (pPrev) /* found it ? */
  563. {
  564. pImage->sHeader.pPrev = pPrev; /* than link it in place */
  565. pImage->sHeader.pNext = pPrev->sHeader.pNext;
  566. pPrev->sHeader.pNext = pImage;
  567. }
  568. else /* if not found, it becomes the first ! */
  569. {
  570. pImage->sHeader.pNext = pData->pFirstimgobj;
  571. pData->pFirstimgobj = pImage;
  572. }
  573. pNext = (mng_imagep)pImage->sHeader.pNext;
  574. if (pNext)
  575. pNext->sHeader.pPrev = pImage;
  576. else
  577. pData->pLastimgobj = pImage;
  578. }
  579. *ppObject = pImage; /* and return the new buffer */
  580. #ifdef MNG_SUPPORT_TRACE
  581. MNG_TRACE (pData, MNG_FN_CREATE_IMGOBJECT, MNG_LC_END);
  582. #endif
  583. return MNG_NOERROR; /* okido */
  584. }
  585. /* ************************************************************************** */
  586. mng_retcode mng_free_imageobject (mng_datap pData,
  587. mng_imagep pImage)
  588. {
  589. mng_retcode iRetcode;
  590. mng_imagep pPrev = pImage->sHeader.pPrev;
  591. mng_imagep pNext = pImage->sHeader.pNext;
  592. mng_imagedatap pImgbuf = pImage->pImgbuf;
  593. #ifdef MNG_SUPPORT_TRACE
  594. MNG_TRACE (pData, MNG_FN_FREE_IMGOBJECT, MNG_LC_START);
  595. #endif
  596. if (pImage->iId) /* not for object 0 */
  597. {
  598. if (pPrev) /* unlink from the list first ! */
  599. pPrev->sHeader.pNext = pImage->sHeader.pNext;
  600. else
  601. pData->pFirstimgobj = pImage->sHeader.pNext;
  602. if (pNext)
  603. pNext->sHeader.pPrev = pImage->sHeader.pPrev;
  604. else
  605. pData->pLastimgobj = pImage->sHeader.pPrev;
  606. }
  607. /* unlink the image-data buffer */
  608. iRetcode = mng_free_imagedataobject (pData, pImgbuf);
  609. /* drop its own buffer */
  610. MNG_FREEX (pData, pImage, sizeof (mng_image));
  611. #ifdef MNG_SUPPORT_TRACE
  612. MNG_TRACE (pData, MNG_FN_FREE_IMGOBJECT, MNG_LC_END);
  613. #endif
  614. return iRetcode;
  615. }
  616. /* ************************************************************************** */
  617. mng_imagep mng_find_imageobject (mng_datap pData,
  618. mng_uint16 iId)
  619. {
  620. mng_imagep pImage = (mng_imagep)pData->pFirstimgobj;
  621. #ifdef MNG_SUPPORT_TRACE
  622. MNG_TRACEX (pData, MNG_FN_FIND_IMGOBJECT, MNG_LC_START);
  623. #endif
  624. /* look up the right id */
  625. while ((pImage) && (pImage->iId != iId))
  626. pImage = (mng_imagep)pImage->sHeader.pNext;
  627. #ifdef MNG_INCLUDE_MPNG_PROPOSAL
  628. if ((!pImage) && (pData->eImagetype == mng_it_mpng))
  629. pImage = pData->pObjzero;
  630. #endif
  631. #ifdef MNG_SUPPORT_TRACE
  632. MNG_TRACEX (pData, MNG_FN_FIND_IMGOBJECT, MNG_LC_END);
  633. #endif
  634. return pImage;
  635. }
  636. /* ************************************************************************** */
  637. mng_retcode mng_clone_imageobject (mng_datap pData,
  638. mng_uint16 iId,
  639. mng_bool bPartial,
  640. mng_bool bVisible,
  641. mng_bool bAbstract,
  642. mng_bool bHasloca,
  643. mng_uint8 iLocationtype,
  644. mng_int32 iLocationx,
  645. mng_int32 iLocationy,
  646. mng_imagep pSource,
  647. mng_imagep *ppClone)
  648. {
  649. mng_imagep pNew;
  650. mng_imagep pPrev, pNext;
  651. mng_retcode iRetcode;
  652. mng_imagedatap pImgbuf;
  653. #ifdef MNG_SUPPORT_TRACE
  654. MNG_TRACE (pData, MNG_FN_CLONE_IMGOBJECT, MNG_LC_START);
  655. #endif
  656. #ifndef MNG_SKIPCHUNK_MAGN
  657. if ((pSource->iId) && /* needs magnification ? */
  658. ((pSource->iMAGN_MethodX) || (pSource->iMAGN_MethodY)))
  659. {
  660. iRetcode = mng_magnify_imageobject (pData, pSource);
  661. if (iRetcode) /* on error bail out */
  662. return iRetcode;
  663. }
  664. #endif
  665. /* get a buffer */
  666. #ifdef MNG_OPTIMIZE_OBJCLEANUP
  667. {
  668. mng_ptr pTemp;
  669. mng_retcode iRetcode = create_obj_general (pData, sizeof (mng_image),
  670. (mng_cleanupobject)mng_free_imageobject,
  671. MNG_NULL, &pTemp);
  672. if (iRetcode)
  673. return iRetcode;
  674. pNew = (mng_imagep)pTemp;
  675. }
  676. #else
  677. MNG_ALLOC (pData, pNew, sizeof (mng_image));
  678. /* fill or copy the appropriate fields */
  679. pNew->sHeader.fCleanup = (mng_cleanupobject)mng_free_imageobject;
  680. pNew->sHeader.fProcess = MNG_NULL;
  681. #endif
  682. pNew->iId = iId;
  683. pNew->bFrozen = MNG_FALSE;
  684. pNew->bVisible = bVisible;
  685. pNew->bViewable = pSource->bViewable;
  686. pNew->bValid = MNG_TRUE;
  687. if (bHasloca) /* location info available ? */
  688. {
  689. if (iLocationtype == 0) /* absolute position ? */
  690. {
  691. pNew->iPosx = iLocationx;
  692. pNew->iPosy = iLocationy;
  693. }
  694. else /* relative */
  695. {
  696. pNew->iPosx = pSource->iPosx + iLocationx;
  697. pNew->iPosy = pSource->iPosy + iLocationy;
  698. }
  699. }
  700. else /* copy from source */
  701. {
  702. pNew->iPosx = pSource->iPosx;
  703. pNew->iPosy = pSource->iPosy;
  704. }
  705. /* copy clipping info */
  706. pNew->bClipped = pSource->bClipped;
  707. pNew->iClipl = pSource->iClipl;
  708. pNew->iClipr = pSource->iClipr;
  709. pNew->iClipt = pSource->iClipt;
  710. pNew->iClipb = pSource->iClipb;
  711. #ifndef MNG_SKIPCHUNK_MAGN
  712. /* copy magnification info */
  713. /* pNew->iMAGN_MethodX = pSource->iMAGN_MethodX; LET'S NOT !!!!!!
  714. pNew->iMAGN_MethodY = pSource->iMAGN_MethodY;
  715. pNew->iMAGN_MX = pSource->iMAGN_MX;
  716. pNew->iMAGN_MY = pSource->iMAGN_MY;
  717. pNew->iMAGN_ML = pSource->iMAGN_ML;
  718. pNew->iMAGN_MR = pSource->iMAGN_MR;
  719. pNew->iMAGN_MT = pSource->iMAGN_MT;
  720. pNew->iMAGN_MB = pSource->iMAGN_MB; */
  721. #endif
  722. #ifndef MNG_SKIPCHUNK_PAST
  723. pNew->iPastx = 0; /* initialize PAST info */
  724. pNew->iPasty = 0;
  725. #endif
  726. if (iId) /* not for object 0 */
  727. { /* find previous lower object-id */
  728. pPrev = (mng_imagep)pData->pLastimgobj;
  729. while ((pPrev) && (pPrev->iId > iId))
  730. pPrev = (mng_imagep)pPrev->sHeader.pPrev;
  731. if (pPrev) /* found it ? */
  732. {
  733. pNew->sHeader.pPrev = pPrev; /* than link it in place */
  734. pNew->sHeader.pNext = pPrev->sHeader.pNext;
  735. pPrev->sHeader.pNext = pNew;
  736. }
  737. else /* if not found, it becomes the first ! */
  738. {
  739. pNew->sHeader.pNext = pData->pFirstimgobj;
  740. pData->pFirstimgobj = pNew;
  741. }
  742. pNext = (mng_imagep)pNew->sHeader.pNext;
  743. if (pNext)
  744. pNext->sHeader.pPrev = pNew;
  745. else
  746. pData->pLastimgobj = pNew;
  747. }
  748. if (bPartial) /* partial clone ? */
  749. {
  750. pNew->pImgbuf = pSource->pImgbuf; /* use the same object buffer */
  751. pNew->pImgbuf->iRefcount++; /* and increase the reference count */
  752. }
  753. else /* create a full clone ! */
  754. {
  755. mng_bool bConcrete = MNG_FALSE; /* it's abstract by default (?) */
  756. if (!bAbstract) /* determine concreteness from source ? */
  757. bConcrete = pSource->pImgbuf->bConcrete;
  758. /* create a full clone ! */
  759. iRetcode = mng_clone_imagedataobject (pData, bConcrete, pSource->pImgbuf, &pImgbuf);
  760. if (iRetcode) /* on error bail out */
  761. {
  762. MNG_FREEX (pData, pNew, sizeof (mng_image));
  763. return iRetcode;
  764. }
  765. pNew->pImgbuf = pImgbuf; /* and remember it */
  766. }
  767. *ppClone = pNew; /* return it */
  768. #ifdef MNG_SUPPORT_TRACE
  769. MNG_TRACE (pData, MNG_FN_CLONE_IMGOBJECT, MNG_LC_END);
  770. #endif
  771. return MNG_NOERROR;
  772. }
  773. /* ************************************************************************** */
  774. mng_retcode mng_renum_imageobject (mng_datap pData,
  775. mng_imagep pSource,
  776. mng_uint16 iId,
  777. mng_bool bVisible,
  778. mng_bool bAbstract,
  779. mng_bool bHasloca,
  780. mng_uint8 iLocationtype,
  781. mng_int32 iLocationx,
  782. mng_int32 iLocationy)
  783. {
  784. mng_imagep pPrev, pNext;
  785. #ifdef MNG_SUPPORT_TRACE
  786. MNG_TRACE (pData, MNG_FN_RENUM_IMGOBJECT, MNG_LC_START);
  787. #endif
  788. pSource->bVisible = bVisible; /* store the new visibility */
  789. if (bHasloca) /* location info available ? */
  790. {
  791. if (iLocationtype == 0) /* absolute position ? */
  792. {
  793. pSource->iPosx = iLocationx;
  794. pSource->iPosy = iLocationy;
  795. }
  796. else /* relative */
  797. {
  798. pSource->iPosx = pSource->iPosx + iLocationx;
  799. pSource->iPosy = pSource->iPosy + iLocationy;
  800. }
  801. }
  802. if (iId) /* not for object 0 */
  803. { /* find previous lower object-id */
  804. pPrev = (mng_imagep)pData->pLastimgobj;
  805. while ((pPrev) && (pPrev->iId > iId))
  806. pPrev = (mng_imagep)pPrev->sHeader.pPrev;
  807. /* different from current ? */
  808. if (pPrev != (mng_imagep)pSource->sHeader.pPrev)
  809. {
  810. if (pSource->sHeader.pPrev) /* unlink from current position !! */
  811. ((mng_imagep)pSource->sHeader.pPrev)->sHeader.pNext = pSource->sHeader.pNext;
  812. else
  813. pData->pFirstimgobj = pSource->sHeader.pNext;
  814. if (pSource->sHeader.pNext)
  815. ((mng_imagep)pSource->sHeader.pNext)->sHeader.pPrev = pSource->sHeader.pPrev;
  816. else
  817. pData->pLastimgobj = pSource->sHeader.pPrev;
  818. if (pPrev) /* found the previous ? */
  819. { /* than link it in place */
  820. pSource->sHeader.pPrev = pPrev;
  821. pSource->sHeader.pNext = pPrev->sHeader.pNext;
  822. pPrev->sHeader.pNext = pSource;
  823. }
  824. else /* if not found, it becomes the first ! */
  825. {
  826. pSource->sHeader.pNext = pData->pFirstimgobj;
  827. pData->pFirstimgobj = pSource;
  828. }
  829. pNext = (mng_imagep)pSource->sHeader.pNext;
  830. if (pNext)
  831. pNext->sHeader.pPrev = pSource;
  832. else
  833. pData->pLastimgobj = pSource;
  834. }
  835. }
  836. pSource->iId = iId; /* now set the new id! */
  837. if (bAbstract) /* force it to abstract ? */
  838. pSource->pImgbuf->bConcrete = MNG_FALSE;
  839. #ifdef MNG_SUPPORT_TRACE
  840. MNG_TRACE (pData, MNG_FN_RENUM_IMGOBJECT, MNG_LC_END);
  841. #endif
  842. return MNG_NOERROR;
  843. }
  844. /* ************************************************************************** */
  845. mng_retcode mng_reset_object_details (mng_datap pData,
  846. mng_imagep pImage,
  847. mng_uint32 iWidth,
  848. mng_uint32 iHeight,
  849. mng_uint8 iBitdepth,
  850. mng_uint8 iColortype,
  851. mng_uint8 iCompression,
  852. mng_uint8 iFilter,
  853. mng_uint8 iInterlace,
  854. mng_bool bResetall)
  855. {
  856. mng_imagedatap pBuf = pImage->pImgbuf;
  857. mng_uint32 iSamplesize = 0;
  858. mng_uint32 iRowsize;
  859. mng_uint32 iImgdatasize;
  860. #ifdef MNG_SUPPORT_TRACE
  861. MNG_TRACE (pData, MNG_FN_RESET_OBJECTDETAILS, MNG_LC_START);
  862. #endif
  863. pBuf->iWidth = iWidth; /* set buffer characteristics */
  864. pBuf->iHeight = iHeight;
  865. pBuf->iBitdepth = iBitdepth;
  866. pBuf->iColortype = iColortype;
  867. pBuf->iCompression = iCompression;
  868. pBuf->iFilter = iFilter;
  869. pBuf->iInterlace = iInterlace;
  870. pBuf->bCorrected = MNG_FALSE;
  871. pBuf->iAlphabitdepth = 0;
  872. /* determine samplesize from color_type/bit_depth */
  873. switch (iColortype) /* for < 8-bit samples we just reserve 8 bits */
  874. {
  875. case 0 : ; /* gray */
  876. case 8 : { /* JPEG gray */
  877. #ifndef MNG_NO_16BIT_SUPPORT
  878. if (iBitdepth > 8)
  879. iSamplesize = 2;
  880. else
  881. #endif
  882. iSamplesize = 1;
  883. break;
  884. }
  885. case 2 : ; /* rgb */
  886. case 10 : { /* JPEG rgb */
  887. #ifndef MNG_NO_16BIT_SUPPORT
  888. if (iBitdepth > 8)
  889. iSamplesize = 6;
  890. else
  891. #endif
  892. iSamplesize = 3;
  893. break;
  894. }
  895. case 3 : { /* indexed */
  896. iSamplesize = 1;
  897. break;
  898. }
  899. case 4 : ; /* gray+alpha */
  900. case 12 : { /* JPEG gray+alpha */
  901. #ifndef MNG_NO_16BIT_SUPPORT
  902. if (iBitdepth > 8)
  903. iSamplesize = 4;
  904. else
  905. #endif
  906. iSamplesize = 2;
  907. break;
  908. }
  909. case 6 : ; /* rgb+alpha */
  910. case 14 : { /* JPEG rgb+alpha */
  911. #ifndef MNG_NO_16BIT_SUPPORT
  912. if (iBitdepth > 8)
  913. iSamplesize = 8;
  914. else
  915. #endif
  916. iSamplesize = 4;
  917. break;
  918. }
  919. }
  920. iRowsize = iSamplesize * iWidth;
  921. iImgdatasize = iRowsize * iHeight;
  922. /* buffer size changed ? */
  923. if (iImgdatasize != pBuf->iImgdatasize)
  924. { /* drop the old one */
  925. MNG_FREE (pData, pBuf->pImgdata, pBuf->iImgdatasize);
  926. if (iImgdatasize) /* allocate new sample-buffer ? */
  927. MNG_ALLOC (pData, pBuf->pImgdata, iImgdatasize);
  928. }
  929. else
  930. {
  931. if (iImgdatasize) /* clear old buffer */
  932. {
  933. mng_uint8p pTemp = pBuf->pImgdata;
  934. mng_uint32 iX;
  935. for (iX = 0; iX < (iImgdatasize & (mng_uint32)(~3L)); iX += 4)
  936. {
  937. *((mng_uint32p)pTemp) = 0x00000000l;
  938. pTemp += 4;
  939. }
  940. while (pTemp < (pBuf->pImgdata + iImgdatasize))
  941. {
  942. *pTemp = 0;
  943. pTemp++;
  944. }
  945. }
  946. }
  947. pBuf->iSamplesize = iSamplesize; /* remember new sizes */
  948. pBuf->iRowsize = iRowsize;
  949. pBuf->iImgdatasize = iImgdatasize;
  950. if (!pBuf->iPixelsampledepth) /* set delta sampledepths if empty */
  951. pBuf->iPixelsampledepth = iBitdepth;
  952. if (!pBuf->iAlphasampledepth)
  953. pBuf->iAlphasampledepth = iBitdepth;
  954. /* dimension set and clipping not ? */
  955. if ((iWidth) && (iHeight) && (!pImage->bClipped))
  956. {
  957. pImage->iClipl = 0; /* set clipping to dimension by default */
  958. pImage->iClipr = iWidth;
  959. pImage->iClipt = 0;
  960. pImage->iClipb = iHeight;
  961. }
  962. #ifndef MNG_SKIPCHUNK_MAGN
  963. if (pImage->iId) /* reset magnification info ? */
  964. {
  965. pImage->iMAGN_MethodX = 0;
  966. pImage->iMAGN_MethodY = 0;
  967. pImage->iMAGN_MX = 0;
  968. pImage->iMAGN_MY = 0;
  969. pImage->iMAGN_ML = 0;
  970. pImage->iMAGN_MR = 0;
  971. pImage->iMAGN_MT = 0;
  972. pImage->iMAGN_MB = 0;
  973. }
  974. #endif
  975. if (bResetall) /* reset the other characteristics ? */
  976. {
  977. #ifndef MNG_SKIPCHUNK_PAST
  978. pImage->iPastx = 0;
  979. pImage->iPasty = 0;
  980. #endif
  981. pBuf->bHasPLTE = MNG_FALSE;
  982. pBuf->bHasTRNS = MNG_FALSE;
  983. pBuf->bHasGAMA = pData->bHasglobalGAMA;
  984. #ifndef MNG_SKIPCHUNK_cHRM
  985. pBuf->bHasCHRM = pData->bHasglobalCHRM;
  986. #endif
  987. pBuf->bHasSRGB = pData->bHasglobalSRGB;
  988. #ifndef MNG_SKIPCHUNK_iCCP
  989. pBuf->bHasICCP = pData->bHasglobalICCP;
  990. #endif
  991. #ifndef MNG_SKIPCHUNK_bKGD
  992. pBuf->bHasBKGD = pData->bHasglobalBKGD;
  993. #endif
  994. #ifndef MNG_SKIPCHUNK_iCCP
  995. if (pBuf->iProfilesize) /* drop possibly old ICC profile */
  996. {
  997. MNG_FREE (pData, pBuf->pProfile, pBuf->iProfilesize);
  998. pBuf->iProfilesize = 0;
  999. }
  1000. #endif
  1001. if (pData->bHasglobalGAMA) /* global gAMA present ? */
  1002. pBuf->iGamma = pData->iGlobalGamma;
  1003. #ifndef MNG_SKIPCHUNK_cHRM
  1004. if (pData->bHasglobalCHRM) /* global cHRM present ? */
  1005. {
  1006. pBuf->iWhitepointx = pData->iGlobalWhitepointx;
  1007. pBuf->iWhitepointy = pData->iGlobalWhitepointy;
  1008. pBuf->iPrimaryredx = pData->iGlobalPrimaryredx;
  1009. pBuf->iPrimaryredy = pData->iGlobalPrimaryredy;
  1010. pBuf->iPrimarygreenx = pData->iGlobalPrimarygreenx;
  1011. pBuf->iPrimarygreeny = pData->iGlobalPrimarygreeny;
  1012. pBuf->iPrimarybluex = pData->iGlobalPrimarybluex;
  1013. pBuf->iPrimarybluey = pData->iGlobalPrimarybluey;
  1014. }
  1015. #endif
  1016. if (pData->bHasglobalSRGB) /* global sRGB present ? */
  1017. pBuf->iRenderingintent = pData->iGlobalRendintent;
  1018. #ifndef MNG_SKIPCHUNK_iCCP
  1019. if (pData->bHasglobalICCP) /* global iCCP present ? */
  1020. {
  1021. if (pData->iGlobalProfilesize)
  1022. {
  1023. MNG_ALLOC (pData, pBuf->pProfile, pData->iGlobalProfilesize);
  1024. MNG_COPY (pBuf->pProfile, pData->pGlobalProfile, pData->iGlobalProfilesize);
  1025. }
  1026. pBuf->iProfilesize = pData->iGlobalProfilesize;
  1027. }
  1028. #endif
  1029. #ifndef MNG_SKIPCHUNK_bKGD
  1030. if (pData->bHasglobalBKGD) /* global bKGD present ? */
  1031. {
  1032. pBuf->iBKGDred = pData->iGlobalBKGDred;
  1033. pBuf->iBKGDgreen = pData->iGlobalBKGDgreen;
  1034. pBuf->iBKGDblue = pData->iGlobalBKGDblue;
  1035. }
  1036. #endif
  1037. }
  1038. #ifdef MNG_SUPPORT_TRACE
  1039. MNG_TRACE (pData, MNG_FN_RESET_OBJECTDETAILS, MNG_LC_END);
  1040. #endif
  1041. return MNG_NOERROR;
  1042. }
  1043. /* ************************************************************************** */
  1044. #if !defined(MNG_NO_DELTA_PNG) || !defined(MNG_SKIPCHUNK_PAST) || !defined(MNG_SKIPCHUNK_MAGN)
  1045. mng_retcode mng_promote_imageobject (mng_datap pData,
  1046. mng_imagep pImage,
  1047. mng_uint8 iBitdepth,
  1048. mng_uint8 iColortype,
  1049. mng_uint8 iFilltype)
  1050. {
  1051. mng_retcode iRetcode = MNG_NOERROR;
  1052. mng_imagedatap pBuf = pImage->pImgbuf;
  1053. mng_uint32 iW = pBuf->iWidth;
  1054. mng_uint32 iH = pBuf->iHeight;
  1055. mng_uint8p pNewbuf;
  1056. mng_uint32 iNewbufsize;
  1057. mng_uint32 iNewrowsize;
  1058. mng_uint32 iNewsamplesize = pBuf->iSamplesize;
  1059. mng_uint32 iY;
  1060. mng_uint8 iTempdepth;
  1061. #ifdef MNG_SUPPORT_TRACE
  1062. MNG_TRACE (pData, MNG_FN_PROMOTE_IMGOBJECT, MNG_LC_START);
  1063. #endif
  1064. #ifdef MNG_NO_1_2_4BIT_SUPPORT
  1065. if (iBitdepth < 8)
  1066. iBitdepth=8;
  1067. if (pBuf->iBitdepth < 8)
  1068. pBuf->iBitdepth=8;
  1069. #endif
  1070. #ifdef MNG_NO_16BIT_SUPPORT
  1071. if (iBitdepth > 8)
  1072. iBitdepth=8;
  1073. if (pBuf->iBitdepth > 8)
  1074. pBuf->iBitdepth=8;
  1075. #endif
  1076. pData->fPromoterow = MNG_NULL; /* init promotion fields */
  1077. pData->fPromBitdepth = MNG_NULL;
  1078. pData->iPromColortype = iColortype;
  1079. pData->iPromBitdepth = iBitdepth;
  1080. pData->iPromFilltype = iFilltype;
  1081. if (iBitdepth != pBuf->iBitdepth) /* determine bitdepth promotion */
  1082. {
  1083. if (pBuf->iColortype == MNG_COLORTYPE_INDEXED)
  1084. iTempdepth = 8;
  1085. else
  1086. iTempdepth = pBuf->iBitdepth;
  1087. #ifndef MNG_NO_DELTA_PNG
  1088. if (iFilltype == MNG_FILLMETHOD_ZEROFILL)
  1089. {
  1090. switch (iTempdepth)
  1091. {
  1092. #ifndef MNG_NO_1_2_4BIT_SUPPORT
  1093. case 1 : {
  1094. switch (iBitdepth)
  1095. {
  1096. case 2 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_1_2; break; }
  1097. case 4 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_1_4; break; }
  1098. case 8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_1_8; break; }
  1099. #ifndef MNG_NO_16BIT_SUPPORT
  1100. case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_1_16; break; }
  1101. #endif
  1102. }
  1103. break;
  1104. }
  1105. case 2 : {
  1106. switch (iBitdepth)
  1107. {
  1108. case 4 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_2_4; break; }
  1109. case 8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_2_8; break; }
  1110. #ifndef MNG_NO_16BIT_SUPPORT
  1111. case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_2_16; break; }
  1112. #endif
  1113. }
  1114. break;
  1115. }
  1116. case 4 : {
  1117. switch (iBitdepth)
  1118. {
  1119. case 8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_4_8; break; }
  1120. #ifndef MNG_NO_16BIT_SUPPORT
  1121. case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_4_16; break; }
  1122. #endif
  1123. }
  1124. break;
  1125. }
  1126. #endif /* MNG_NO_1_2_4BIT_SUPPORT */
  1127. case 8 : {
  1128. #ifndef MNG_NO_16BIT_SUPPORT
  1129. if (iBitdepth == 16)
  1130. pData->fPromBitdepth = (mng_fptr)mng_promote_zerofill_8_16;
  1131. #endif
  1132. break;
  1133. }
  1134. }
  1135. }
  1136. else
  1137. #endif
  1138. {
  1139. switch (iTempdepth)
  1140. {
  1141. #ifndef MNG_NO_1_2_4BIT_SUPPORT
  1142. case 1 : {
  1143. switch (iBitdepth)
  1144. {
  1145. case 2 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_1_2; break; }
  1146. case 4 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_1_4; break; }
  1147. case 8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_1_8; break; }
  1148. #ifndef MNG_NO_16BIT_SUPPORT
  1149. case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_1_16; break; }
  1150. #endif
  1151. }
  1152. break;
  1153. }
  1154. case 2 : {
  1155. switch (iBitdepth)
  1156. {
  1157. case 4 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_2_4; break; }
  1158. case 8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_2_8; break; }
  1159. #ifndef MNG_NO_16BIT_SUPPORT
  1160. case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_2_16; break; }
  1161. #endif
  1162. }
  1163. break;
  1164. }
  1165. case 4 : {
  1166. switch (iBitdepth)
  1167. {
  1168. case 8 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_4_8; break; }
  1169. #ifndef MNG_NO_16BIT_SUPPORT
  1170. case 16 : { pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_4_16; break; }
  1171. #endif
  1172. }
  1173. break;
  1174. }
  1175. #endif /* MNG_NO_1_2_4BIT_SUPPORT */
  1176. case 8 : {
  1177. #ifndef MNG_NO_16BIT_SUPPORT
  1178. if (iBitdepth == 16)
  1179. pData->fPromBitdepth = (mng_fptr)mng_promote_replicate_8_16;
  1180. #endif
  1181. break;
  1182. }
  1183. }
  1184. }
  1185. }
  1186. /* g -> g */
  1187. if ((pBuf->iColortype == MNG_COLORTYPE_GRAY) &&
  1188. (iColortype == MNG_COLORTYPE_GRAY))
  1189. {
  1190. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1191. {
  1192. #ifndef MNG_NO_16BIT_SUPPORT
  1193. if (iBitdepth == 16)
  1194. pData->fPromoterow = (mng_fptr)mng_promote_g8_g16;
  1195. else
  1196. #endif
  1197. pData->fPromoterow = (mng_fptr)mng_promote_g8_g8;
  1198. }
  1199. iNewsamplesize = 1;
  1200. #ifndef MNG_NO_16BIT_SUPPORT
  1201. if (iBitdepth == 16) /* 16-bit wide ? */
  1202. iNewsamplesize = 2;
  1203. #endif
  1204. }
  1205. else /* g -> ga */
  1206. if ((pBuf->iColortype == MNG_COLORTYPE_GRAY) &&
  1207. (iColortype == MNG_COLORTYPE_GRAYA))
  1208. {
  1209. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1210. {
  1211. #ifndef MNG_NO_16BIT_SUPPORT
  1212. if (iBitdepth == 16)
  1213. pData->fPromoterow = (mng_fptr)mng_promote_g8_ga16;
  1214. else
  1215. #endif
  1216. pData->fPromoterow = (mng_fptr)mng_promote_g8_ga8;
  1217. }
  1218. #ifndef MNG_NO_16BIT_SUPPORT
  1219. else /* source = 16 bits */
  1220. pData->fPromoterow = (mng_fptr)mng_promote_g16_ga16;
  1221. #endif
  1222. iNewsamplesize = 2;
  1223. #ifndef MNG_NO_16BIT_SUPPORT
  1224. if (iBitdepth == 16) /* 16-bit wide ? */
  1225. iNewsamplesize = 4;
  1226. #endif
  1227. }
  1228. else /* g -> rgb */
  1229. if ((pBuf->iColortype == MNG_COLORTYPE_GRAY) &&
  1230. (iColortype == MNG_COLORTYPE_RGB))
  1231. {
  1232. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1233. {
  1234. #ifndef MNG_NO_16BIT_SUPPORT
  1235. if (iBitdepth == 16)
  1236. pData->fPromoterow = (mng_fptr)mng_promote_g8_rgb16;
  1237. else
  1238. #endif
  1239. pData->fPromoterow = (mng_fptr)mng_promote_g8_rgb8;
  1240. }
  1241. #ifndef MNG_NO_16BIT_SUPPORT
  1242. else /* source = 16 bits */
  1243. pData->fPromoterow = (mng_fptr)mng_promote_g16_rgb16;
  1244. #endif
  1245. iNewsamplesize = 3;
  1246. #ifndef MNG_NO_16BIT_SUPPORT
  1247. if (iBitdepth == 16) /* 16-bit wide ? */
  1248. iNewsamplesize = 6;
  1249. #endif
  1250. }
  1251. else /* g -> rgba */
  1252. if ((pBuf->iColortype == MNG_COLORTYPE_GRAY) &&
  1253. (iColortype == MNG_COLORTYPE_RGBA))
  1254. {
  1255. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1256. {
  1257. #ifndef MNG_NO_16BIT_SUPPORT
  1258. if (iBitdepth == 16)
  1259. pData->fPromoterow = (mng_fptr)mng_promote_g8_rgba16;
  1260. else
  1261. #endif
  1262. pData->fPromoterow = (mng_fptr)mng_promote_g8_rgba8;
  1263. }
  1264. #ifndef MNG_NO_16BIT_SUPPORT
  1265. else /* source = 16 bits */
  1266. pData->fPromoterow = (mng_fptr)mng_promote_g16_rgba16;
  1267. #endif
  1268. iNewsamplesize = 4;
  1269. #ifndef MNG_NO_16BIT_SUPPORT
  1270. if (iBitdepth == 16) /* 16-bit wide ? */
  1271. iNewsamplesize = 8;
  1272. #endif
  1273. }
  1274. else /* ga -> ga */
  1275. if ((pBuf->iColortype == MNG_COLORTYPE_GRAYA) &&
  1276. (iColortype == MNG_COLORTYPE_GRAYA))
  1277. {
  1278. iNewsamplesize = 2;
  1279. #ifndef MNG_NO_16BIT_SUPPORT
  1280. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1281. if (iBitdepth == 16)
  1282. pData->fPromoterow = (mng_fptr)mng_promote_ga8_ga16;
  1283. if (iBitdepth == 16)
  1284. iNewsamplesize = 4;
  1285. #endif
  1286. }
  1287. else /* ga -> rgba */
  1288. if ((pBuf->iColortype == MNG_COLORTYPE_GRAYA) &&
  1289. (iColortype == MNG_COLORTYPE_RGBA))
  1290. {
  1291. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1292. {
  1293. #ifndef MNG_NO_16BIT_SUPPORT
  1294. if (iBitdepth == 16)
  1295. pData->fPromoterow = (mng_fptr)mng_promote_ga8_rgba16;
  1296. else
  1297. #endif
  1298. pData->fPromoterow = (mng_fptr)mng_promote_ga8_rgba8;
  1299. }
  1300. #ifndef MNG_NO_16BIT_SUPPORT
  1301. else /* source = 16 bits */
  1302. pData->fPromoterow = (mng_fptr)mng_promote_ga16_rgba16;
  1303. #endif
  1304. iNewsamplesize = 4;
  1305. #ifndef MNG_NO_16BIT_SUPPORT
  1306. if (iBitdepth == 16) /* 16-bit wide ? */
  1307. iNewsamplesize = 8;
  1308. #endif
  1309. }
  1310. else /* rgb -> rgb */
  1311. if ((pBuf->iColortype == MNG_COLORTYPE_RGB) &&
  1312. (iColortype == MNG_COLORTYPE_RGB))
  1313. {
  1314. iNewsamplesize = 3;
  1315. #ifndef MNG_NO_16BIT_SUPPORT
  1316. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1317. if (iBitdepth == 16)
  1318. pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgb16;
  1319. if (iBitdepth == 16)
  1320. iNewsamplesize = 6;
  1321. #endif
  1322. }
  1323. else /* rgb -> rgba */
  1324. if ((pBuf->iColortype == MNG_COLORTYPE_RGB) &&
  1325. (iColortype == MNG_COLORTYPE_RGBA))
  1326. {
  1327. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1328. {
  1329. #ifndef MNG_NO_16BIT_SUPPORT
  1330. if (iBitdepth == 16)
  1331. pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgba16;
  1332. else
  1333. #endif
  1334. pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgba8;
  1335. }
  1336. #ifndef MNG_NO_16BIT_SUPPORT
  1337. else /* source = 16 bits */
  1338. pData->fPromoterow = (mng_fptr)mng_promote_rgb16_rgba16;
  1339. #endif
  1340. iNewsamplesize = 4;
  1341. #ifndef MNG_NO_16BIT_SUPPORT
  1342. if (iBitdepth == 16) /* 16-bit wide ? */
  1343. iNewsamplesize = 8;
  1344. #endif
  1345. }
  1346. else /* indexed -> rgb */
  1347. if ((pBuf->iColortype == MNG_COLORTYPE_INDEXED) &&
  1348. (iColortype == MNG_COLORTYPE_RGB))
  1349. {
  1350. #ifndef MNG_NO_16BIT_SUPPORT
  1351. if (iBitdepth == 16)
  1352. pData->fPromoterow = (mng_fptr)mng_promote_idx8_rgb16;
  1353. else
  1354. #endif
  1355. pData->fPromoterow = (mng_fptr)mng_promote_idx8_rgb8;
  1356. iNewsamplesize = 3;
  1357. #ifndef MNG_NO_16BIT_SUPPORT
  1358. if (iBitdepth == 16) /* 16-bit wide ? */
  1359. iNewsamplesize = 6;
  1360. #endif
  1361. }
  1362. else /* indexed -> rgba */
  1363. if ((pBuf->iColortype == MNG_COLORTYPE_INDEXED) &&
  1364. (iColortype == MNG_COLORTYPE_RGBA))
  1365. {
  1366. #ifndef MNG_NO_16BIT_SUPPORT
  1367. if (iBitdepth == 16)
  1368. pData->fPromoterow = (mng_fptr)mng_promote_idx8_rgba16;
  1369. else
  1370. #endif
  1371. pData->fPromoterow = (mng_fptr)mng_promote_idx8_rgba8;
  1372. iNewsamplesize = 4;
  1373. #ifndef MNG_NO_16BIT_SUPPORT
  1374. if (iBitdepth == 16) /* 16-bit wide ? */
  1375. iNewsamplesize = 8;
  1376. #endif
  1377. }
  1378. else /* rgba -> rgba */
  1379. if ((pBuf->iColortype == MNG_COLORTYPE_RGBA) &&
  1380. (iColortype == MNG_COLORTYPE_RGBA))
  1381. {
  1382. iNewsamplesize = 4;
  1383. #ifndef MNG_NO_16BIT_SUPPORT
  1384. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1385. {
  1386. if (iBitdepth == 16)
  1387. pData->fPromoterow = (mng_fptr)mng_promote_rgba8_rgba16;
  1388. }
  1389. if (iBitdepth == 16) /* 16-bit wide ? */
  1390. iNewsamplesize = 8;
  1391. #endif
  1392. }
  1393. #ifdef MNG_INCLUDE_JNG
  1394. else /* JPEG g -> g */
  1395. if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY) &&
  1396. (iColortype == MNG_COLORTYPE_JPEGGRAY))
  1397. {
  1398. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1399. {
  1400. #ifndef MNG_NO_16BIT_SUPPORT
  1401. if (iBitdepth == 16)
  1402. pData->fPromoterow = (mng_fptr)mng_promote_g8_g16;
  1403. else
  1404. #endif
  1405. pData->fPromoterow = (mng_fptr)mng_promote_g8_g8;
  1406. }
  1407. iNewsamplesize = 1;
  1408. #ifndef MNG_NO_16BIT_SUPPORT
  1409. if (iBitdepth == 16) /* 16-bit wide ? */
  1410. iNewsamplesize = 2;
  1411. #endif
  1412. }
  1413. else /* JPEG g -> ga */
  1414. if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY) &&
  1415. (iColortype == MNG_COLORTYPE_JPEGGRAYA))
  1416. {
  1417. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1418. {
  1419. #ifndef MNG_NO_16BIT_SUPPORT
  1420. if (iBitdepth == 16)
  1421. pData->fPromoterow = (mng_fptr)mng_promote_g8_ga16;
  1422. else
  1423. #endif
  1424. pData->fPromoterow = (mng_fptr)mng_promote_g8_ga8;
  1425. }
  1426. #ifndef MNG_NO_16BIT_SUPPORT
  1427. else /* source = 16 bits */
  1428. pData->fPromoterow = (mng_fptr)mng_promote_g16_ga16;
  1429. #endif
  1430. iNewsamplesize = 2;
  1431. #ifndef MNG_NO_16BIT_SUPPORT
  1432. if (iBitdepth == 16) /* 16-bit wide ? */
  1433. iNewsamplesize = 4;
  1434. #endif
  1435. }
  1436. else /* JPEG g -> rgb */
  1437. if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY) &&
  1438. (iColortype == MNG_COLORTYPE_JPEGCOLOR))
  1439. {
  1440. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1441. {
  1442. #ifndef MNG_NO_16BIT_SUPPORT
  1443. if (iBitdepth == 16)
  1444. pData->fPromoterow = (mng_fptr)mng_promote_g8_rgb16;
  1445. else
  1446. #endif
  1447. pData->fPromoterow = (mng_fptr)mng_promote_g8_rgb8;
  1448. }
  1449. #ifndef MNG_NO_16BIT_SUPPORT
  1450. else /* source = 16 bits */
  1451. pData->fPromoterow = (mng_fptr)mng_promote_g16_rgb16;
  1452. #endif
  1453. iNewsamplesize = 3;
  1454. #ifndef MNG_NO_16BIT_SUPPORT
  1455. if (iBitdepth == 16) /* 16-bit wide ? */
  1456. iNewsamplesize = 6;
  1457. #endif
  1458. }
  1459. else /* JPEG g -> rgba */
  1460. if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAY) &&
  1461. (iColortype == MNG_COLORTYPE_JPEGCOLORA))
  1462. {
  1463. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1464. {
  1465. #ifndef MNG_NO_16BIT_SUPPORT
  1466. if (iBitdepth == 16)
  1467. pData->fPromoterow = (mng_fptr)mng_promote_g8_rgba16;
  1468. else
  1469. #endif
  1470. pData->fPromoterow = (mng_fptr)mng_promote_g8_rgba8;
  1471. }
  1472. #ifndef MNG_NO_16BIT_SUPPORT
  1473. else /* source = 16 bits */
  1474. pData->fPromoterow = (mng_fptr)mng_promote_g16_rgba16;
  1475. #endif
  1476. iNewsamplesize = 4;
  1477. #ifndef MNG_NO_16BIT_SUPPORT
  1478. if (iBitdepth == 16) /* 16-bit wide ? */
  1479. iNewsamplesize = 8;
  1480. #endif
  1481. }
  1482. else /* JPEG ga -> ga */
  1483. if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAYA) &&
  1484. (iColortype == MNG_COLORTYPE_JPEGGRAYA))
  1485. {
  1486. iNewsamplesize = 2;
  1487. #ifndef MNG_NO_16BIT_SUPPORT
  1488. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1489. if (iBitdepth == 16)
  1490. pData->fPromoterow = (mng_fptr)mng_promote_ga8_ga16;
  1491. if (iBitdepth == 16)
  1492. iNewsamplesize = 4;
  1493. #endif
  1494. }
  1495. else /* JPEG ga -> rgba */
  1496. if ((pBuf->iColortype == MNG_COLORTYPE_JPEGGRAYA) &&
  1497. (iColortype == MNG_COLORTYPE_JPEGCOLORA))
  1498. {
  1499. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1500. {
  1501. #ifndef MNG_NO_16BIT_SUPPORT
  1502. if (iBitdepth == 16)
  1503. pData->fPromoterow = (mng_fptr)mng_promote_ga8_rgba16;
  1504. else
  1505. #endif
  1506. pData->fPromoterow = (mng_fptr)mng_promote_ga8_rgba8;
  1507. }
  1508. #ifndef MNG_NO_16BIT_SUPPORT
  1509. else /* source = 16 bits */
  1510. pData->fPromoterow = (mng_fptr)mng_promote_ga16_rgba16;
  1511. #endif
  1512. iNewsamplesize = 4;
  1513. #ifndef MNG_NO_16BIT_SUPPORT
  1514. if (iBitdepth == 16) /* 16-bit wide ? */
  1515. iNewsamplesize = 8;
  1516. #endif
  1517. }
  1518. else /* JPEG rgb -> rgb */
  1519. if ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLOR) &&
  1520. (iColortype == MNG_COLORTYPE_JPEGCOLOR))
  1521. {
  1522. iNewsamplesize = 3;
  1523. #ifndef MNG_NO_16BIT_SUPPORT
  1524. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1525. if (iBitdepth == 16)
  1526. pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgb16;
  1527. if (iBitdepth == 16)
  1528. iNewsamplesize = 6;
  1529. #endif
  1530. }
  1531. else /* JPEG rgb -> rgba */
  1532. if ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLOR) &&
  1533. (iColortype == MNG_COLORTYPE_JPEGCOLORA))
  1534. {
  1535. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1536. {
  1537. #ifndef MNG_NO_16BIT_SUPPORT
  1538. if (iBitdepth == 16)
  1539. pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgba16;
  1540. else
  1541. #endif
  1542. pData->fPromoterow = (mng_fptr)mng_promote_rgb8_rgba8;
  1543. }
  1544. #ifndef MNG_NO_16BIT_SUPPORT
  1545. else /* source = 16 bits */
  1546. pData->fPromoterow = (mng_fptr)mng_promote_rgb16_rgba16;
  1547. #endif
  1548. iNewsamplesize = 4;
  1549. #ifndef MNG_NO_16BIT_SUPPORT
  1550. if (iBitdepth == 16) /* 16-bit wide ? */
  1551. iNewsamplesize = 8;
  1552. #endif
  1553. }
  1554. else /* JPEG rgba -> rgba */
  1555. if ((pBuf->iColortype == MNG_COLORTYPE_JPEGCOLORA) &&
  1556. (iColortype == MNG_COLORTYPE_JPEGCOLORA))
  1557. {
  1558. iNewsamplesize = 4;
  1559. #ifndef MNG_NO_16BIT_SUPPORT
  1560. if (pBuf->iBitdepth <= 8) /* source <= 8 bits */
  1561. if (iBitdepth == 16)
  1562. pData->fPromoterow = (mng_fptr)mng_promote_rgba8_rgba16;
  1563. if (iBitdepth == 16)
  1564. iNewsamplesize = 8;
  1565. #endif
  1566. }
  1567. #endif /* JNG */
  1568. /* found a proper promotion ? */
  1569. if (pData->fPromote