5165
5288
/* ************************************************************************** */
5290
#ifdef MNG_INCLUDE_MPNG_PROPOSAL
5291
MNG_C_SPECIALFUNC (mng_special_mpng)
5293
if ((pData->eImagetype != mng_it_png) && (pData->eImagetype != mng_it_jng))
5294
MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
5296
#ifdef MNG_SUPPORT_DISPLAY
5297
return mng_create_mpng_obj (pData, pChunk);
5304
/* ************************************************************************** */
5306
#ifdef MNG_INCLUDE_ANG_PROPOSAL
5307
MNG_C_SPECIALFUNC (mng_special_ahdr)
5309
#ifdef MNG_SUPPORT_DISPLAY
5310
return mng_create_ang_obj (pData, pChunk);
5317
/* ************************************************************************** */
5319
#ifdef MNG_INCLUDE_ANG_PROPOSAL
5320
MNG_F_SPECIALFUNC (mng_adat_tiles)
5322
if ((pData->eImagetype != mng_it_ang) || (!pData->pANG))
5323
MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
5326
mng_adatp pADAT = (mng_adatp)pChunk;
5327
mng_ang_objp pANG = (mng_ang_objp)pData->pANG;
5328
mng_uint32 iRawlen = *piRawlen;
5329
mng_uint8p pRawdata = *ppRawdata;
5330
mng_retcode iRetcode;
5332
mng_uint32 iBufsize;
5333
mng_uint32 iRealsize;
5339
#ifdef MNG_SUPPORT_DISPLAY
5344
mng_processobject pProcess;
5346
mng_uint32 iSavedatawidth;
5347
mng_uint32 iSavedataheight;
5349
mng_fptr fSaveinitrowproc;
5350
mng_fptr fSavestorerow;
5351
mng_fptr fSaveprocessrow;
5352
mng_fptr fSavedifferrow;
5353
mng_imagep fSavestoreobj;
5354
mng_imagedatap fSavestorebuf;
5356
#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
5357
png_imgtype eSavepngimgtype;
5360
mng_uint8 iSaveinterlace;
5363
mng_int32 iSaverowinc;
5365
mng_int32 iSavecolinc;
5366
mng_int32 iSaverowsamples;
5367
mng_int32 iSavesamplemul;
5368
mng_int32 iSavesampleofs;
5369
mng_int32 iSavesamplediv;
5370
mng_int32 iSaverowsize;
5371
mng_int32 iSaverowmax;
5372
mng_int32 iSavefilterofs;
5373
mng_int32 iSavepixelofs;
5374
mng_uint32 iSavelevel0;
5375
mng_uint32 iSavelevel1;
5376
mng_uint32 iSavelevel2;
5377
mng_uint32 iSavelevel3;
5378
mng_uint8p pSaveworkrow;
5379
mng_uint8p pSaveprevrow;
5380
mng_uint8p pSaverGBArow;
5381
mng_bool bSaveisRGBA16;
5382
mng_bool bSaveisOpaque;
5383
mng_int32 iSavefilterbpp;
5385
mng_int32 iSavedestl;
5386
mng_int32 iSavedestt;
5387
mng_int32 iSavedestr;
5388
mng_int32 iSavedestb;
5389
mng_int32 iSavesourcel;
5390
mng_int32 iSavesourcet;
5391
mng_int32 iSavesourcer;
5392
mng_int32 iSavesourceb;
5393
#endif /* MNG_SUPPORT_DISPLAY */
5395
iRetcode = mng_inflate_buffer (pData, pRawdata, iRawlen,
5396
&pBuf, &iBufsize, &iRealsize);
5397
if (iRetcode) /* on error bail out */
5398
{ /* don't forget to drop the temp buffer */
5399
MNG_FREEX (pData, pBuf, iBufsize);
5402
/* get buffer for tile info in ADAT chunk */
5403
pADAT->iTilessize = pANG->iNumframes * sizeof(mng_adat_tile);
5404
MNG_ALLOCX (pData, pADAT->pTiles, pADAT->iTilessize);
5407
pADAT->iTilessize = 0;
5408
MNG_FREEX (pData, pBuf, iBufsize);
5409
MNG_ERROR (pData, MNG_OUTOFMEMORY);
5413
pTemp2 = (mng_uint8p)pADAT->pTiles;
5415
if (!pANG->iStillused)
5420
for (iX = 0; iX < pANG->iNumframes; iX++)
5422
MNG_COPY (pTemp2, pTemp, iSize);
5424
pTemp2 += sizeof(mng_adat_tile);
5427
#ifdef MNG_SUPPORT_DISPLAY
5428
/* get buffer for tile info in ANG object */
5429
pANG->iTilessize = pADAT->iTilessize;
5430
MNG_ALLOCX (pData, pANG->pTiles, pANG->iTilessize);
5433
pANG->iTilessize = 0;
5434
MNG_FREEX (pData, pBuf, iBufsize);
5435
MNG_ERROR (pData, MNG_OUTOFMEMORY);
5437
/* copy it from the ADAT object */
5438
MNG_COPY (pANG->pTiles, pADAT->pTiles, pANG->iTilessize);
5440
/* save IDAT work-parms */
5441
fSaveinitrowproc = pData->fInitrowproc;
5442
fSavestorerow = pData->fDisplayrow;
5443
fSaveprocessrow = pData->fProcessrow;
5444
fSavedifferrow = pData->fDifferrow;
5445
fSavestoreobj = pData->pStoreobj;
5446
fSavestorebuf = pData->pStorebuf;
5448
#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
5449
eSavepngimgtype = pData->ePng_imgtype;
5452
iSavedatawidth = pData->iDatawidth;
5453
iSavedataheight = pData->iDataheight;
5454
iSaveinterlace = pData->iInterlace;
5455
iSavepass = pData->iPass;
5456
iSaverow = pData->iRow;
5457
iSaverowinc = pData->iRowinc;
5458
iSavecol = pData->iCol;
5459
iSavecolinc = pData->iColinc;
5460
iSaverowsamples = pData->iRowsamples;
5461
iSavesamplemul = pData->iSamplemul;
5462
iSavesampleofs = pData->iSampleofs;
5463
iSavesamplediv = pData->iSamplediv;
5464
iSaverowsize = pData->iRowsize;
5465
iSaverowmax = pData->iRowmax;
5466
iSavefilterofs = pData->iFilterofs;
5467
iSavepixelofs = pData->iPixelofs;
5468
iSavelevel0 = pData->iLevel0;
5469
iSavelevel1 = pData->iLevel1;
5470
iSavelevel2 = pData->iLevel2;
5471
iSavelevel3 = pData->iLevel3;
5472
pSaveworkrow = pData->pWorkrow;
5473
pSaveprevrow = pData->pPrevrow;
5474
pSaverGBArow = pData->pRGBArow;
5475
bSaveisRGBA16 = pData->bIsRGBA16;
5476
bSaveisOpaque = pData->bIsOpaque;
5477
iSavefilterbpp = pData->iFilterbpp;
5478
iSavedestl = pData->iDestl;
5479
iSavedestt = pData->iDestt;
5480
iSavedestr = pData->iDestr;
5481
iSavedestb = pData->iDestb;
5482
iSavesourcel = pData->iSourcel;
5483
iSavesourcet = pData->iSourcet;
5484
iSavesourcer = pData->iSourcer;
5485
iSavesourceb = pData->iSourceb;
5487
pData->iDatawidth = pANG->iTilewidth;
5488
pData->iDataheight = pANG->iTileheight;
5492
pData->iDestr = pANG->iTilewidth;
5493
pData->iDestb = pANG->iTileheight;
5494
pData->iSourcel = 0;
5495
pData->iSourcet = 0;
5496
pData->iSourcer = pANG->iTilewidth;
5497
pData->iSourceb = pANG->iTileheight;
5499
pData->fInitrowproc = MNG_NULL;
5500
pData->fStorerow = MNG_NULL;
5501
pData->fProcessrow = MNG_NULL;
5502
pData->fDifferrow = MNG_NULL;
5504
/* clone image object to store the pixel-data from object 0 */
5505
iRetcode = mng_clone_imageobject (pData, 1, MNG_FALSE, MNG_FALSE, MNG_FALSE,
5506
MNG_FALSE, 0, 0, 0, pData->pObjzero, &pImage);
5507
if (iRetcode) /* on error, drop temp buffer and bail */
5509
MNG_FREEX (pData, pBuf, iBufsize);
5513
/* make sure we got the right dimensions and interlacing */
5514
iRetcode = mng_reset_object_details (pData, pImage, pANG->iTilewidth, pANG->iTileheight,
5515
pImage->pImgbuf->iBitdepth, pImage->pImgbuf->iColortype,
5516
pImage->pImgbuf->iCompression, pImage->pImgbuf->iFilter,
5517
pANG->iInterlace, MNG_FALSE);
5518
if (iRetcode) /* on error, drop temp buffer and bail */
5520
MNG_FREEX (pData, pBuf, iBufsize);
5524
pData->pStoreobj = pImage;
5526
#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
5527
pData->fInitrowproc = (mng_fptr)mng_init_rowproc;
5528
pData->ePng_imgtype = mng_png_imgtype(pData->iColortype,pData->iBitdepth);
5530
switch (pData->iColortype) /* determine row initialization routine */
5532
case 0 : { /* gray */
5533
switch (pData->iBitdepth)
5535
#ifndef MNG_NO_1_2_4BIT_SUPPORT
5537
if (!pData->iInterlace)
5538
pData->fInitrowproc = (mng_fptr)mng_init_g1_ni;
5540
pData->fInitrowproc = (mng_fptr)mng_init_g1_i;
5545
if (!pData->iInterlace)
5546
pData->fInitrowproc = (mng_fptr)mng_init_g2_ni;
5548
pData->fInitrowproc = (mng_fptr)mng_init_g2_i;
5553
if (!pData->iInterlace)
5554
pData->fInitrowproc = (mng_fptr)mng_init_g4_ni;
5556
pData->fInitrowproc = (mng_fptr)mng_init_g4_i;
5559
#endif /* MNG_NO_1_2_4BIT_SUPPORT */
5561
if (!pData->iInterlace)
5562
pData->fInitrowproc = (mng_fptr)mng_init_g8_ni;
5564
pData->fInitrowproc = (mng_fptr)mng_init_g8_i;
5568
#ifndef MNG_NO_16BIT_SUPPORT
5570
if (!pData->iInterlace)
5571
pData->fInitrowproc = (mng_fptr)mng_init_g16_ni;
5573
pData->fInitrowproc = (mng_fptr)mng_init_g16_i;
5582
case 2 : { /* rgb */
5583
switch (pData->iBitdepth)
5586
if (!pData->iInterlace)
5587
pData->fInitrowproc = (mng_fptr)mng_init_rgb8_ni;
5589
pData->fInitrowproc = (mng_fptr)mng_init_rgb8_i;
5592
#ifndef MNG_NO_16BIT_SUPPORT
5594
if (!pData->iInterlace)
5595
pData->fInitrowproc = (mng_fptr)mng_init_rgb16_ni;
5597
pData->fInitrowproc = (mng_fptr)mng_init_rgb16_i;
5606
case 3 : { /* indexed */
5607
switch (pData->iBitdepth)
5609
#ifndef MNG_NO_1_2_4BIT_SUPPORT
5611
if (!pData->iInterlace)
5612
pData->fInitrowproc = (mng_fptr)mng_init_idx1_ni;
5614
pData->fInitrowproc = (mng_fptr)mng_init_idx1_i;
5619
if (!pData->iInterlace)
5620
pData->fInitrowproc = (mng_fptr)mng_init_idx2_ni;
5622
pData->fInitrowproc = (mng_fptr)mng_init_idx2_i;
5627
if (!pData->iInterlace)
5628
pData->fInitrowproc = (mng_fptr)mng_init_idx4_ni;
5630
pData->fInitrowproc = (mng_fptr)mng_init_idx4_i;
5634
#endif /* MNG_NO_1_2_4BIT_SUPPORT */
5636
if (!pData->iInterlace)
5637
pData->fInitrowproc = (mng_fptr)mng_init_idx8_ni;
5639
pData->fInitrowproc = (mng_fptr)mng_init_idx8_i;
5647
case 4 : { /* gray+alpha */
5648
switch (pData->iBitdepth)
5651
if (!pData->iInterlace)
5652
pData->fInitrowproc = (mng_fptr)mng_init_ga8_ni;
5654
pData->fInitrowproc = (mng_fptr)mng_init_ga8_i;
5658
#ifndef MNG_NO_16BIT_SUPPORT
5660
if (!pData->iInterlace)
5661
pData->fInitrowproc = (mng_fptr)mng_init_ga16_ni;
5663
pData->fInitrowproc = (mng_fptr)mng_init_ga16_i;
5671
case 6 : { /* rgb+alpha */
5672
switch (pData->iBitdepth)
5675
if (!pData->iInterlace)
5676
pData->fInitrowproc = (mng_fptr)mng_init_rgba8_ni;
5678
pData->fInitrowproc = (mng_fptr)mng_init_rgba8_i;
5682
#ifndef MNG_NO_16BIT_SUPPORT
5684
if (!pData->iInterlace)
5685
pData->fInitrowproc = (mng_fptr)mng_init_rgba16_ni;
5687
pData->fInitrowproc = (mng_fptr)mng_init_rgba16_i;
5697
#endif /* MNG_OPTIMIZE_FOOTPRINT_INIT */
5699
pData->iFilterofs = 0; /* determine filter characteristics */
5700
pData->iLevel0 = 0; /* default levels */
5705
#ifdef FILTER192 /* leveling & differing ? */
5706
if (pData->iFilter == MNG_FILTER_DIFFERING)
5708
switch (pData->iColortype)
5711
if (pData->iBitdepth <= 8)
5712
pData->iFilterofs = 1;
5714
pData->iFilterofs = 2;
5719
if (pData->iBitdepth <= 8)
5720
pData->iFilterofs = 3;
5722
pData->iFilterofs = 6;
5727
pData->iFilterofs = 1;
5731
if (pData->iBitdepth <= 8)
5732
pData->iFilterofs = 2;
5734
pData->iFilterofs = 4;
5739
if (pData->iBitdepth <= 8)
5740
pData->iFilterofs = 4;
5742
pData->iFilterofs = 8;
5750
#ifdef FILTER193 /* no adaptive filtering ? */
5751
if (pData->iFilter == MNG_FILTER_NOFILTER)
5752
pData->iPixelofs = pData->iFilterofs;
5755
pData->iPixelofs = pData->iFilterofs + 1;
5757
if (pData->fInitrowproc) /* need to initialize row processing? */
5759
iRetcode = ((mng_initrowproc)pData->fInitrowproc) (pData);
5762
MNG_FREEX (pData, pBuf, iBufsize);
5766
/* calculate remainder of buffer */
5767
pTemp = pBuf + (mng_int32)(pANG->iNumframes * iSize);
5768
iTemplen = iRealsize - (mng_int32)(pANG->iNumframes * iSize);
5772
if (iTemplen > pData->iRowmax) /* get a pixel-row from the temp buffer */
5774
MNG_COPY (pData->pWorkrow, pTemp, pData->iRowmax);
5778
MNG_COPY (pData->pWorkrow, pTemp, iTemplen);
5781
{ /* image not completed yet ? */
5782
if (pData->iRow < (mng_int32)pData->iDataheight)
5784
#ifdef MNG_NO_1_2_4BIT_SUPPORT
5785
if (pData->iPNGdepth == 1)
5787
/* Inflate Workrow to 8-bit */
5789
mng_uint8p pSrc = pData->pWorkrow+1;
5790
mng_uint8p pDest = pSrc + pData->iRowsize - (pData->iRowsize+7)/8;
5792
for (iX = ((pData->iRowsize+7)/8) ; iX > 0 ; iX--)
5795
pDest = pData->pWorkrow+1;
5796
pSrc = pDest + pData->iRowsize - (pData->iRowsize+7)/8;
5797
for (iX = pData->iRowsize; ;)
5799
*pDest++ = (((*pSrc)>>7)&1);
5802
*pDest++ = (((*pSrc)>>6)&1);
5805
*pDest++ = (((*pSrc)>>5)&1);
5808
*pDest++ = (((*pSrc)>>4)&1);
5811
*pDest++ = (((*pSrc)>>3)&1);
5814
*pDest++ = (((*pSrc)>>2)&1);
5817
*pDest++ = (((*pSrc)>>1)&1);
5820
*pDest++ = (((*pSrc) )&1);
5826
else if (pData->iPNGdepth == 2)
5828
/* Inflate Workrow to 8-bit */
5830
mng_uint8p pSrc = pData->pWorkrow+1;
5831
mng_uint8p pDest = pSrc + pData->iRowsize - (2*pData->iRowsize+7)/8;
5833
for (iX = ((2*pData->iRowsize+7)/8) ; iX > 0 ; iX--)
5836
pDest = pData->pWorkrow+1;
5837
pSrc = pDest + pData->iRowsize - (2*pData->iRowsize+7)/8;
5838
for (iX = pData->iRowsize; ;)
5840
*pDest++ = (((*pSrc)>>6)&3);
5843
*pDest++ = (((*pSrc)>>4)&3);
5846
*pDest++ = (((*pSrc)>>2)&3);
5849
*pDest++ = (((*pSrc) )&3);
5855
else if (pData->iPNGdepth == 4)
5857
/* Inflate Workrow to 8-bit */
5859
mng_uint8p pSrc = pData->pWorkrow+1;
5860
mng_uint8p pDest = pSrc + pData->iRowsize - (4*pData->iRowsize+7)/8;
5862
for (iX = ((4*pData->iRowsize+7)/8) ; iX > 0 ; iX--)
5865
pDest = pData->pWorkrow+1;
5866
pSrc = pDest + pData->iRowsize - (4*pData->iRowsize+7)/8;
5867
for (iX = pData->iRowsize; ;)
5869
*pDest++ = (((*pSrc)>>4)&0x0f);
5872
*pDest++ = (((*pSrc) )&0x0f);
5878
if (pData->iPNGdepth < 8 && pData->iColortype == 0)
5880
/* Expand samples to 8-bit by LBR */
5882
mng_uint8p pSrc = pData->pWorkrow+1;
5883
mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1};
5885
for (iX = pData->iRowsize; iX > 0; iX--)
5886
*pSrc++ *= multiplier[pData->iPNGdepth];
5889
#ifdef MNG_NO_16BIT_SUPPORT
5890
if (pData->iPNGdepth > 8)
5892
/* Reduce Workrow to 8-bit */
5894
mng_uint8p pSrc = pData->pWorkrow+1;
5895
mng_uint8p pDest = pSrc;
5897
for (iX = pData->iRowsize; iX > 0; iX--)
5906
#ifdef FILTER192 /* has leveling info ? */
5907
if (pData->iFilterofs == MNG_FILTER_DIFFERING)
5908
iRetcode = init_rowdiffering (pData);
5911
iRetcode = MNG_NOERROR;
5912
/* filter the row if necessary */
5913
if ((!iRetcode) && (pData->iFilterofs < pData->iPixelofs ) &&
5914
(*(pData->pWorkrow + pData->iFilterofs)) )
5915
iRetcode = mng_filter_a_row (pData);
5917
/* additional leveling/differing ? */
5918
if ((!iRetcode) && (pData->fDifferrow))
5920
iRetcode = ((mng_differrow)pData->fDifferrow) (pData);
5922
pSwap = pData->pWorkrow;
5923
pData->pWorkrow = pData->pPrevrow;
5924
pData->pPrevrow = pSwap; /* make sure we're processing the right data */
5929
{ /* process this row */
5930
if ((!iRetcode) && (pData->fProcessrow))
5931
iRetcode = ((mng_processrow)pData->fProcessrow) (pData);
5932
/* store in object ? */
5933
if ((!iRetcode) && (pData->fStorerow))
5934
iRetcode = ((mng_storerow)pData->fStorerow) (pData);
5938
if (iRetcode) /* on error bail out */
5940
MNG_FREEX (pData, pBuf, iBufsize);
5941
MNG_ERROR (pData, iRetcode);
5944
if (!pData->fDifferrow) /* swap row-pointers */
5946
pSwap = pData->pWorkrow;
5947
pData->pWorkrow = pData->pPrevrow;
5948
pData->pPrevrow = pSwap; /* so prev points to the processed row! */
5950
/* adjust variables for next row */
5951
iRetcode = mng_next_row (pData);
5953
if (iRetcode) /* on error bail out */
5955
MNG_FREEX (pData, pBuf, iBufsize);
5956
MNG_ERROR (pData, iRetcode);
5961
pTemp += pData->iRowmax;
5962
iTemplen -= pData->iRowmax;
5963
} /* until some error or EOI
5964
or all pixels received */
5965
while ( (iTemplen > 0) &&
5966
( (pData->iRow < (mng_int32)pData->iDataheight) ||
5967
( (pData->iPass >= 0) && (pData->iPass < 7) ) ) );
5969
mng_cleanup_rowproc (pData); /* cleanup row processing buffers !! */
5971
/* restore saved work-parms */
5972
pData->iDatawidth = iSavedatawidth;
5973
pData->iDataheight = iSavedataheight;
5975
pData->fInitrowproc = fSaveinitrowproc;
5976
pData->fDisplayrow = fSavestorerow;
5977
pData->fProcessrow = fSaveprocessrow;
5978
pData->fDifferrow = fSavedifferrow;
5979
pData->pStoreobj = fSavestoreobj;
5980
pData->pStorebuf = fSavestorebuf;
5982
#ifdef MNG_OPTIMIZE_FOOTPRINT_INIT
5983
pData->ePng_imgtype = eSavepngimgtype;
5986
pData->iInterlace = iSaveinterlace;
5987
pData->iPass = iSavepass;
5988
pData->iRow = iSaverow;
5989
pData->iRowinc = iSaverowinc;
5990
pData->iCol = iSavecol;
5991
pData->iColinc = iSavecolinc;
5992
pData->iRowsamples = iSaverowsamples;
5993
pData->iSamplemul = iSavesamplemul;
5994
pData->iSampleofs = iSavesampleofs;
5995
pData->iSamplediv = iSavesamplediv;
5996
pData->iRowsize = iSaverowsize;
5997
pData->iRowmax = iSaverowmax;
5998
pData->iFilterofs = iSavefilterofs;
5999
pData->iPixelofs = iSavepixelofs;
6000
pData->iLevel0 = iSavelevel0;
6001
pData->iLevel1 = iSavelevel1;
6002
pData->iLevel2 = iSavelevel2;
6003
pData->iLevel3 = iSavelevel3;
6004
pData->pWorkrow = pSaveworkrow;
6005
pData->pPrevrow = pSaveprevrow;
6006
pData->pRGBArow = pSaverGBArow;
6007
pData->bIsRGBA16 = bSaveisRGBA16;
6008
pData->bIsOpaque = bSaveisOpaque;
6009
pData->iFilterbpp = iSavefilterbpp;
6010
pData->iDestl = iSavedestl;
6011
pData->iDestt = iSavedestt;
6012
pData->iDestr = iSavedestr;
6013
pData->iDestb = iSavedestb;
6014
pData->iSourcel = iSavesourcel;
6015
pData->iSourcet = iSavesourcet;
6016
pData->iSourcer = iSavesourcer;
6017
pData->iSourceb = iSavesourceb;
6019
/* create the animation directives ! */
6020
pProcess = (mng_processobject)pANG->sHeader.fProcess;
6021
iRetcode = pProcess (pData, (mng_objectp)pData->pANG);
6025
#endif /* MNG_SUPPORT_DISPLAY */
6027
MNG_FREE (pData, pBuf, iBufsize); /* always free the temp buffer ! */
6036
/* ************************************************************************** */
6038
#ifdef MNG_INCLUDE_ANG_PROPOSAL
6039
MNG_C_SPECIALFUNC (mng_special_adat)
6045
/* ************************************************************************** */
5167
6047
MNG_C_SPECIALFUNC (mng_special_unknown)
5169
6049
/* critical chunk ? */