libmng_chunk_io.c 340 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740
  1. /** ************************************************************************* */
  2. /* * For conditions of distribution and use, * */
  3. /* * see copyright notice in libmng.h * */
  4. /* ************************************************************************** */
  5. /* * * */
  6. /* * project : libmng * */
  7. /* * file : libmng_chunk_io.c copyright (c) 2000-2007 G.Juyn * */
  8. /* * version : 1.0.10 * */
  9. /* * * */
  10. /* * purpose : Chunk I/O routines (implementation) * */
  11. /* * * */
  12. /* * author : G.Juyn * */
  13. /* * * */
  14. /* * comment : implementation of chunk input/output routines * */
  15. /* * * */
  16. /* * changes : 0.5.1 - 05/01/2000 - G.Juyn * */
  17. /* * - cleaned up left-over teststuff in the BACK chunk routine * */
  18. /* * 0.5.1 - 05/04/2000 - G.Juyn * */
  19. /* * - changed CRC initialization to use dynamic structure * */
  20. /* * (wasn't thread-safe the old way !) * */
  21. /* * 0.5.1 - 05/06/2000 - G.Juyn * */
  22. /* * - filled in many missing sequence&length checks * */
  23. /* * - filled in many missing chunk-store snippets * */
  24. /* * 0.5.1 - 05/08/2000 - G.Juyn * */
  25. /* * - added checks for running animations * */
  26. /* * - filled some write routines * */
  27. /* * - changed strict-ANSI stuff * */
  28. /* * 0.5.1 - 05/10/2000 - G.Juyn * */
  29. /* * - filled some more write routines * */
  30. /* * 0.5.1 - 05/11/2000 - G.Juyn * */
  31. /* * - filled remaining write routines * */
  32. /* * - fixed read_pplt with regard to deltatype * */
  33. /* * - added callback error-reporting support * */
  34. /* * - added pre-draft48 support (short MHDR, frame_mode, LOOP) * */
  35. /* * 0.5.1 - 05/12/2000 - G.Juyn * */
  36. /* * - changed trace to macro for callback error-reporting * */
  37. /* * - fixed chunk-storage bit in several routines * */
  38. /* * 0.5.1 - 05/13/2000 - G.Juyn * */
  39. /* * - added eMNGma hack (will be removed in 1.0.0 !!!) * */
  40. /* * - added TERM animation object pointer (easier reference) * */
  41. /* * - supplemented the SAVE & SEEK display processing * */
  42. /* * * */
  43. /* * 0.5.2 - 05/18/2000 - G.Juyn * */
  44. /* * - B004 - fixed problem with MNG_SUPPORT_WRITE not defined * */
  45. /* * also for MNG_SUPPORT_WRITE without MNG_INCLUDE_JNG * */
  46. /* * 0.5.2 - 05/19/2000 - G.Juyn * */
  47. /* * - cleaned up some code regarding mixed support * */
  48. /* * 0.5.2 - 05/20/2000 - G.Juyn * */
  49. /* * - implemented JNG support * */
  50. /* * 0.5.2 - 05/24/2000 - G.Juyn * */
  51. /* * - added support for global color-chunks in animation * */
  52. /* * - added support for global PLTE,tRNS,bKGD in animation * */
  53. /* * - added support for SAVE & SEEK in animation * */
  54. /* * 0.5.2 - 05/29/2000 - G.Juyn * */
  55. /* * - changed ani_create calls not returning object pointer * */
  56. /* * - create ani objects always (not just inside TERM/LOOP) * */
  57. /* * 0.5.2 - 05/30/2000 - G.Juyn * */
  58. /* * - added support for delta-image processing * */
  59. /* * 0.5.2 - 05/31/2000 - G.Juyn * */
  60. /* * - fixed up punctuation (contributed by Tim Rowley) * */
  61. /* * 0.5.2 - 06/02/2000 - G.Juyn * */
  62. /* * - changed SWAP_ENDIAN to BIGENDIAN_SUPPORTED * */
  63. /* * 0.5.2 - 06/03/2000 - G.Juyn * */
  64. /* * - fixed makeup for Linux gcc compile * */
  65. /* * * */
  66. /* * 0.5.3 - 06/12/2000 - G.Juyn * */
  67. /* * - added processing of color-info on delta-image * */
  68. /* * 0.5.3 - 06/13/2000 - G.Juyn * */
  69. /* * - fixed handling of empty SAVE chunk * */
  70. /* * 0.5.3 - 06/17/2000 - G.Juyn * */
  71. /* * - changed to support delta-images * */
  72. /* * - added extra checks for delta-images * */
  73. /* * 0.5.3 - 06/20/2000 - G.Juyn * */
  74. /* * - fixed possible trouble if IEND display-process got * */
  75. /* * broken up * */
  76. /* * 0.5.3 - 06/21/2000 - G.Juyn * */
  77. /* * - added processing of PLTE & tRNS for delta-images * */
  78. /* * - added administration of imagelevel parameter * */
  79. /* * 0.5.3 - 06/22/2000 - G.Juyn * */
  80. /* * - implemented support for PPLT chunk * */
  81. /* * 0.5.3 - 06/26/2000 - G.Juyn * */
  82. /* * - added precaution against faulty iCCP chunks from PS * */
  83. /* * 0.5.3 - 06/29/2000 - G.Juyn * */
  84. /* * - fixed some 64-bit warnings * */
  85. /* * * */
  86. /* * 0.9.1 - 07/14/2000 - G.Juyn * */
  87. /* * - changed pre-draft48 frame_mode=3 to frame_mode=1 * */
  88. /* * 0.9.1 - 07/16/2000 - G.Juyn * */
  89. /* * - fixed storage of images during mng_read() * */
  90. /* * - fixed support for mng_display() after mng_read() * */
  91. /* * 0.9.1 - 07/19/2000 - G.Juyn * */
  92. /* * - fixed several chunk-writing routines * */
  93. /* * 0.9.1 - 07/24/2000 - G.Juyn * */
  94. /* * - fixed reading of still-images * */
  95. /* * * */
  96. /* * 0.9.2 - 08/05/2000 - G.Juyn * */
  97. /* * - changed file-prefixes * */
  98. /* * * */
  99. /* * 0.9.3 - 08/07/2000 - G.Juyn * */
  100. /* * - B111300 - fixup for improved portability * */
  101. /* * 0.9.3 - 08/08/2000 - G.Juyn * */
  102. /* * - fixed compiler-warnings from Mozilla * */
  103. /* * 0.9.3 - 08/09/2000 - G.Juyn * */
  104. /* * - added check for simplicity-bits in MHDR * */
  105. /* * 0.9.3 - 08/12/2000 - G.Juyn * */
  106. /* * - fixed check for simplicity-bits in MHDR (JNG) * */
  107. /* * 0.9.3 - 08/12/2000 - G.Juyn * */
  108. /* * - added workaround for faulty PhotoShop iCCP chunk * */
  109. /* * 0.9.3 - 08/22/2000 - G.Juyn * */
  110. /* * - fixed write-code for zTXt & iTXt * */
  111. /* * - fixed read-code for iTXt * */
  112. /* * 0.9.3 - 08/26/2000 - G.Juyn * */
  113. /* * - added MAGN chunk * */
  114. /* * 0.9.3 - 09/07/2000 - G.Juyn * */
  115. /* * - added support for new filter_types * */
  116. /* * 0.9.3 - 09/10/2000 - G.Juyn * */
  117. /* * - fixed DEFI behavior * */
  118. /* * 0.9.3 - 10/02/2000 - G.Juyn * */
  119. /* * - fixed simplicity-check in compliance with draft 81/0.98a * */
  120. /* * 0.9.3 - 10/10/2000 - G.Juyn * */
  121. /* * - added support for alpha-depth prediction * */
  122. /* * 0.9.3 - 10/11/2000 - G.Juyn * */
  123. /* * - added support for nEED * */
  124. /* * 0.9.3 - 10/16/2000 - G.Juyn * */
  125. /* * - added support for JDAA * */
  126. /* * 0.9.3 - 10/17/2000 - G.Juyn * */
  127. /* * - fixed support for MAGN * */
  128. /* * - implemented nEED "xxxx" (where "xxxx" is a chunkid) * */
  129. /* * - added callback to process non-critical unknown chunks * */
  130. /* * - fixed support for bKGD * */
  131. /* * 0.9.3 - 10/23/2000 - G.Juyn * */
  132. /* * - fixed bug in empty PLTE handling * */
  133. /* * * */
  134. /* * 0.9.4 - 11/20/2000 - G.Juyn * */
  135. /* * - changed IHDR filter_method check for PNGs * */
  136. /* * 0.9.4 - 1/18/2001 - G.Juyn * */
  137. /* * - added errorchecking for MAGN methods * */
  138. /* * - removed test filter-methods 1 & 65 * */
  139. /* * * */
  140. /* * 0.9.5 - 1/25/2001 - G.Juyn * */
  141. /* * - fixed some small compiler warnings (thanks Nikki) * */
  142. /* * * */
  143. /* * 1.0.2 - 05/05/2000 - G.Juyn * */
  144. /* * - B421427 - writes wrong format in bKGD and tRNS * */
  145. /* * 1.0.2 - 06/20/2000 - G.Juyn * */
  146. /* * - B434583 - compiler-warning if MNG_STORE_CHUNKS undefined * */
  147. /* * * */
  148. /* * 1.0.5 - 07/08/2002 - G.Juyn * */
  149. /* * - B578572 - removed eMNGma hack (thanks Dimitri!) * */
  150. /* * 1.0.5 - 08/07/2002 - G.Juyn * */
  151. /* * - added test-option for PNG filter method 193 (=no filter) * */
  152. /* * 1.0.5 - 08/15/2002 - G.Juyn * */
  153. /* * - completed PROM support * */
  154. /* * 1.0.5 - 08/19/2002 - G.Juyn * */
  155. /* * - B597134 - libmng pollutes the linker namespace * */
  156. /* * 1.0.5 - 09/07/2002 - G.Juyn * */
  157. /* * - fixed reading of FRAM with just frame_mode and name * */
  158. /* * 1.0.5 - 09/13/2002 - G.Juyn * */
  159. /* * - fixed read/write of MAGN chunk * */
  160. /* * 1.0.5 - 09/14/2002 - G.Juyn * */
  161. /* * - added event handling for dynamic MNG * */
  162. /* * 1.0.5 - 09/15/2002 - G.Juyn * */
  163. /* * - fixed LOOP iteration=0 special case * */
  164. /* * 1.0.5 - 09/19/2002 - G.Juyn * */
  165. /* * - misplaced TERM is now treated as warning * */
  166. /* * 1.0.5 - 09/20/2002 - G.Juyn * */
  167. /* * - added support for PAST * */
  168. /* * 1.0.5 - 10/03/2002 - G.Juyn * */
  169. /* * - fixed chunk-storage for evNT chunk * */
  170. /* * 1.0.5 - 10/07/2002 - G.Juyn * */
  171. /* * - fixed DISC support * */
  172. /* * - added another fix for misplaced TERM chunk * */
  173. /* * 1.0.5 - 10/17/2002 - G.Juyn * */
  174. /* * - fixed initializtion of pIds in dISC read routine * */
  175. /* * 1.0.5 - 11/06/2002 - G.Juyn * */
  176. /* * - added support for nEED "MNG 1.1" * */
  177. /* * - added support for nEED "CACHEOFF" * */
  178. /* * * */
  179. /* * 1.0.6 - 05/25/2003 - G.R-P * */
  180. /* * - added MNG_SKIPCHUNK_cHNK footprint optimizations * */
  181. /* * 1.0.6 - 06/02/2003 - G.R-P * */
  182. /* * - removed some redundant checks for iRawlen==0 * */
  183. /* * 1.0.6 - 06/22/2003 - G.R-P * */
  184. /* * - added MNG_NO_16BIT_SUPPORT, MNG_NO_DELTA_PNG reductions * */
  185. /* * - optionally use zlib's crc32 function instead of * */
  186. /* * local mng_update_crc * */
  187. /* * 1.0.6 - 07/14/2003 - G.R-P * */
  188. /* * - added MNG_NO_LOOP_SIGNALS_SUPPORTED conditional * */
  189. /* * 1.0.6 - 07/29/2003 - G.R-P * */
  190. /* * - added conditionals around PAST chunk support * */
  191. /* * 1.0.6 - 08/17/2003 - G.R-P * */
  192. /* * - added conditionals around non-VLC chunk support * */
  193. /* * * */
  194. /* * 1.0.7 - 10/29/2003 - G.R-P * */
  195. /* * - revised JDAA and JDAT readers to avoid compiler bug * */
  196. /* * 1.0.7 - 01/25/2004 - J.S * */
  197. /* * - added premultiplied alpha canvas' for RGBA, ARGB, ABGR * */
  198. /* * 1.0.7 - 01/27/2004 - J.S * */
  199. /* * - fixed inclusion of IJNG chunk for non-JNG use * */
  200. /* * 1.0.7 - 02/26/2004 - G.Juyn * */
  201. /* * - fixed bug in chunk-storage of SHOW chunk (from == to) * */
  202. /* * * */
  203. /* * 1.0.8 - 04/02/2004 - G.Juyn * */
  204. /* * - added CRC existence & checking flags * */
  205. /* * 1.0.8 - 07/07/2004 - G.R-P * */
  206. /* * - change worst-case iAlphadepth to 1 for standalone PNGs * */
  207. /* * * */
  208. /* * 1.0.9 - 09/28/2004 - G.R-P * */
  209. /* * - improved handling of cheap transparency when 16-bit * */
  210. /* * support is disabled * */
  211. /* * 1.0.9 - 10/04/2004 - G.Juyn * */
  212. /* * - fixed bug in writing sBIT for indexed color * */
  213. /* * 1.0.9 - 10/10/2004 - G.R-P. * */
  214. /* * - added MNG_NO_1_2_4BIT_SUPPORT * */
  215. /* * 1.0.9 - 12/05/2004 - G.Juyn * */
  216. /* * - added conditional MNG_OPTIMIZE_CHUNKINITFREE * */
  217. /* * 1.0.9 - 12/06/2004 - G.Juyn * */
  218. /* * - added conditional MNG_OPTIMIZE_CHUNKASSIGN * */
  219. /* * 1.0.9 - 12/07/2004 - G.Juyn * */
  220. /* * - added conditional MNG_OPTIMIZE_CHUNKREADER * */
  221. /* * 1.0.9 - 12/11/2004 - G.Juyn * */
  222. /* * - added conditional MNG_OPTIMIZE_DISPLAYCALLS * */
  223. /* * 1.0.9 - 12/20/2004 - G.Juyn * */
  224. /* * - cleaned up macro-invocations (thanks to D. Airlie) * */
  225. /* * 1.0.9 - 01/17/2005 - G.Juyn * */
  226. /* * - fixed problem with global PLTE/tRNS * */
  227. /* * * */
  228. /* * 1.0.10 - 02/07/2005 - G.Juyn * */
  229. /* * - fixed display routines called twice for FULL_MNG * */
  230. /* * support in mozlibmngconf.h * */
  231. /* * 1.0.10 - 12/04/2005 - G.R-P. * */
  232. /* * - #ifdef out use of mng_inflate_buffer when it is not * */
  233. /* * available. * */
  234. /* * 1.0.10 - 04/08/2007 - G.Juyn * */
  235. /* * - added support for mPNG proposal * */
  236. /* * 1.0.10 - 04/12/2007 - G.Juyn * */
  237. /* * - added support for ANG proposal * */
  238. /* * 1.0.10 - 05/02/2007 - G.Juyn * */
  239. /* * - fixed inflate_buffer for extreme compression ratios * */
  240. /* * * */
  241. /* ************************************************************************** */
  242. #include "libmng.h"
  243. #include "libmng_data.h"
  244. #include "libmng_error.h"
  245. #include "libmng_trace.h"
  246. #ifdef __BORLANDC__
  247. #pragma hdrstop
  248. #endif
  249. #include "libmng_objects.h"
  250. #include "libmng_object_prc.h"
  251. #include "libmng_chunks.h"
  252. #ifdef MNG_CHECK_BAD_ICCP
  253. #include "libmng_chunk_prc.h"
  254. #endif
  255. #include "libmng_memory.h"
  256. #include "libmng_display.h"
  257. #include "libmng_zlib.h"
  258. #include "libmng_pixels.h"
  259. #include "libmng_chunk_io.h"
  260. #if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
  261. #pragma option -A /* force ANSI-C */
  262. #endif
  263. /* ************************************************************************** */
  264. /* * * */
  265. /* * CRC - Cyclic Redundancy Check * */
  266. /* * * */
  267. /* * The code below is taken directly from the sample provided with the * */
  268. /* * PNG specification. * */
  269. /* * (it is only adapted to the library's internal data-definitions) * */
  270. /* * * */
  271. /* ************************************************************************** */
  272. /* Make the table for a fast CRC. */
  273. #ifndef MNG_USE_ZLIB_CRC
  274. MNG_LOCAL void make_crc_table (mng_datap pData)
  275. {
  276. mng_uint32 iC;
  277. mng_int32 iN, iK;
  278. for (iN = 0; iN < 256; iN++)
  279. {
  280. iC = (mng_uint32) iN;
  281. for (iK = 0; iK < 8; iK++)
  282. {
  283. if (iC & 1)
  284. iC = 0xedb88320U ^ (iC >> 1);
  285. else
  286. iC = iC >> 1;
  287. }
  288. pData->aCRCtable [iN] = iC;
  289. }
  290. pData->bCRCcomputed = MNG_TRUE;
  291. }
  292. #endif
  293. /* Update a running CRC with the bytes buf[0..len-1]--the CRC
  294. should be initialized to all 1's, and the transmitted value
  295. is the 1's complement of the final running CRC (see the
  296. crc() routine below). */
  297. MNG_LOCAL mng_uint32 update_crc (mng_datap pData,
  298. mng_uint32 iCrc,
  299. mng_uint8p pBuf,
  300. mng_int32 iLen)
  301. {
  302. #ifdef MNG_USE_ZLIB_CRC
  303. return crc32 (iCrc, pBuf, iLen);
  304. #else
  305. mng_uint32 iC = iCrc;
  306. mng_int32 iN;
  307. if (!pData->bCRCcomputed)
  308. make_crc_table (pData);
  309. for (iN = 0; iN < iLen; iN++)
  310. iC = pData->aCRCtable [(iC ^ pBuf [iN]) & 0xff] ^ (iC >> 8);
  311. return iC;
  312. #endif
  313. }
  314. /* Return the CRC of the bytes buf[0..len-1]. */
  315. mng_uint32 mng_crc (mng_datap pData,
  316. mng_uint8p pBuf,
  317. mng_int32 iLen)
  318. {
  319. #ifdef MNG_USE_ZLIB_CRC
  320. return update_crc (pData, 0, pBuf, iLen);
  321. #else
  322. return update_crc (pData, 0xffffffffU, pBuf, iLen) ^ 0xffffffffU;
  323. #endif
  324. }
  325. /* ************************************************************************** */
  326. /* * * */
  327. /* * Routines for swapping byte-order from and to graphic files * */
  328. /* * (This code is adapted from the libpng package) * */
  329. /* * * */
  330. /* ************************************************************************** */
  331. #ifndef MNG_BIGENDIAN_SUPPORTED
  332. /* ************************************************************************** */
  333. mng_uint32 mng_get_uint32 (mng_uint8p pBuf)
  334. {
  335. mng_uint32 i = ((mng_uint32)(*pBuf) << 24) +
  336. ((mng_uint32)(*(pBuf + 1)) << 16) +
  337. ((mng_uint32)(*(pBuf + 2)) << 8) +
  338. (mng_uint32)(*(pBuf + 3));
  339. return (i);
  340. }
  341. /* ************************************************************************** */
  342. mng_int32 mng_get_int32 (mng_uint8p pBuf)
  343. {
  344. mng_int32 i = ((mng_int32)(*pBuf) << 24) +
  345. ((mng_int32)(*(pBuf + 1)) << 16) +
  346. ((mng_int32)(*(pBuf + 2)) << 8) +
  347. (mng_int32)(*(pBuf + 3));
  348. return (i);
  349. }
  350. /* ************************************************************************** */
  351. mng_uint16 mng_get_uint16 (mng_uint8p pBuf)
  352. {
  353. mng_uint16 i = (mng_uint16)(((mng_uint16)(*pBuf) << 8) +
  354. (mng_uint16)(*(pBuf + 1)));
  355. return (i);
  356. }
  357. /* ************************************************************************** */
  358. void mng_put_uint32 (mng_uint8p pBuf,
  359. mng_uint32 i)
  360. {
  361. *pBuf = (mng_uint8)((i >> 24) & 0xff);
  362. *(pBuf+1) = (mng_uint8)((i >> 16) & 0xff);
  363. *(pBuf+2) = (mng_uint8)((i >> 8) & 0xff);
  364. *(pBuf+3) = (mng_uint8)(i & 0xff);
  365. }
  366. /* ************************************************************************** */
  367. void mng_put_int32 (mng_uint8p pBuf,
  368. mng_int32 i)
  369. {
  370. *pBuf = (mng_uint8)((i >> 24) & 0xff);
  371. *(pBuf+1) = (mng_uint8)((i >> 16) & 0xff);
  372. *(pBuf+2) = (mng_uint8)((i >> 8) & 0xff);
  373. *(pBuf+3) = (mng_uint8)(i & 0xff);
  374. }
  375. /* ************************************************************************** */
  376. void mng_put_uint16 (mng_uint8p pBuf,
  377. mng_uint16 i)
  378. {
  379. *pBuf = (mng_uint8)((i >> 8) & 0xff);
  380. *(pBuf+1) = (mng_uint8)(i & 0xff);
  381. }
  382. /* ************************************************************************** */
  383. #endif /* !MNG_BIGENDIAN_SUPPORTED */
  384. /* ************************************************************************** */
  385. /* * * */
  386. /* * Helper routines to simplify chunk-data extraction * */
  387. /* * * */
  388. /* ************************************************************************** */
  389. #ifdef MNG_INCLUDE_READ_PROCS
  390. /* ************************************************************************** */
  391. #ifndef MNG_OPTIMIZE_CHUNKREADER
  392. MNG_LOCAL mng_uint8p find_null (mng_uint8p pIn)
  393. {
  394. mng_uint8p pOut = pIn;
  395. while (*pOut) /* the read_graphic routine has made sure there's */
  396. pOut++; /* always at least 1 zero-byte in the buffer */
  397. return pOut;
  398. }
  399. #endif
  400. /* ************************************************************************** */
  401. #if !defined(MNG_SKIPCHUNK_iCCP) || !defined(MNG_SKIPCHUNK_zTXt) || \
  402. !defined(MNG_SKIPCHUNK_iTXt) || defined(MNG_INCLUDE_MPNG_PROPOSAL) || \
  403. defined(MNG_INCLUDE_ANG_PROPOSAL)
  404. mng_retcode mng_inflate_buffer (mng_datap pData,
  405. mng_uint8p pInbuf,
  406. mng_uint32 iInsize,
  407. mng_uint8p *pOutbuf,
  408. mng_uint32 *iOutsize,
  409. mng_uint32 *iRealsize)
  410. {
  411. mng_retcode iRetcode = MNG_NOERROR;
  412. #ifdef MNG_SUPPORT_TRACE
  413. MNG_TRACE (pData, MNG_FN_INFLATE_BUFFER, MNG_LC_START);
  414. #endif
  415. if (iInsize) /* anything to do ? */
  416. {
  417. *iOutsize = iInsize * 3; /* estimate uncompressed size */
  418. /* and allocate a temporary buffer */
  419. MNG_ALLOC (pData, *pOutbuf, *iOutsize);
  420. do
  421. {
  422. mngzlib_inflateinit (pData); /* initialize zlib */
  423. /* let zlib know where to store the output */
  424. pData->sZlib.next_out = *pOutbuf;
  425. /* "size - 1" so we've got space for the
  426. zero-termination of a possible string */
  427. pData->sZlib.avail_out = *iOutsize - 1;
  428. /* ok; let's inflate... */
  429. iRetcode = mngzlib_inflatedata (pData, iInsize, pInbuf);
  430. /* determine actual output size */
  431. *iRealsize = (mng_uint32)pData->sZlib.total_out;
  432. mngzlib_inflatefree (pData); /* zlib's done */
  433. if (iRetcode == MNG_BUFOVERFLOW) /* not enough space ? */
  434. { /* then get some more */
  435. MNG_FREEX (pData, *pOutbuf, *iOutsize);
  436. *iOutsize = *iOutsize + *iOutsize;
  437. MNG_ALLOC (pData, *pOutbuf, *iOutsize);
  438. }
  439. } /* repeat if we didn't have enough space */
  440. while ((iRetcode == MNG_BUFOVERFLOW) &&
  441. (*iOutsize < 200 * iInsize));
  442. if (!iRetcode) /* if oke ? */
  443. *((*pOutbuf) + *iRealsize) = 0; /* then put terminator zero */
  444. }
  445. else
  446. {
  447. *pOutbuf = 0; /* nothing to do; then there's no output */
  448. *iOutsize = 0;
  449. *iRealsize = 0;
  450. }
  451. #ifdef MNG_SUPPORT_TRACE
  452. MNG_TRACE (pData, MNG_FN_INFLATE_BUFFER, MNG_LC_END);
  453. #endif
  454. return iRetcode;
  455. }
  456. #endif
  457. /* ************************************************************************** */
  458. #endif /* MNG_INCLUDE_READ_PROCS */
  459. /* ************************************************************************** */
  460. /* * * */
  461. /* * Helper routines to simplify chunk writing * */
  462. /* * * */
  463. /* ************************************************************************** */
  464. #ifdef MNG_INCLUDE_WRITE_PROCS
  465. /* ************************************************************************** */
  466. #if !defined(MNG_SKIPCHUNK_iCCP) || !defined(MNG_SKIPCHUNK_zTXt) || !defined(MNG_SKIPCHUNK_iTXt)
  467. MNG_LOCAL mng_retcode deflate_buffer (mng_datap pData,
  468. mng_uint8p pInbuf,
  469. mng_uint32 iInsize,
  470. mng_uint8p *pOutbuf,
  471. mng_uint32 *iOutsize,
  472. mng_uint32 *iRealsize)
  473. {
  474. mng_retcode iRetcode = MNG_NOERROR;
  475. #ifdef MNG_SUPPORT_TRACE
  476. MNG_TRACE (pData, MNG_FN_DEFLATE_BUFFER, MNG_LC_START);
  477. #endif
  478. if (iInsize) /* anything to do ? */
  479. {
  480. *iOutsize = (iInsize * 5) >> 2; /* estimate compressed size */
  481. /* and allocate a temporary buffer */
  482. MNG_ALLOC (pData, *pOutbuf, *iOutsize);
  483. do
  484. {
  485. mngzlib_deflateinit (pData); /* initialize zlib */
  486. /* let zlib know where to store the output */
  487. pData->sZlib.next_out = *pOutbuf;
  488. pData->sZlib.avail_out = *iOutsize;
  489. /* ok; let's deflate... */
  490. iRetcode = mngzlib_deflatedata (pData, iInsize, pInbuf);
  491. /* determine actual output size */
  492. *iRealsize = pData->sZlib.total_out;
  493. mngzlib_deflatefree (pData); /* zlib's done */
  494. if (iRetcode == MNG_BUFOVERFLOW) /* not enough space ? */
  495. { /* then get some more */
  496. MNG_FREEX (pData, *pOutbuf, *iOutsize);
  497. *iOutsize = *iOutsize + (iInsize >> 1);
  498. MNG_ALLOC (pData, *pOutbuf, *iOutsize);
  499. }
  500. } /* repeat if we didn't have enough space */
  501. while (iRetcode == MNG_BUFOVERFLOW);
  502. }
  503. else
  504. {
  505. *pOutbuf = 0; /* nothing to do; then there's no output */
  506. *iOutsize = 0;
  507. *iRealsize = 0;
  508. }
  509. #ifdef MNG_SUPPORT_TRACE
  510. MNG_TRACE (pData, MNG_FN_DEFLATE_BUFFER, MNG_LC_END);
  511. #endif
  512. return iRetcode;
  513. }
  514. #endif
  515. /* ************************************************************************** */
  516. MNG_LOCAL mng_retcode write_raw_chunk (mng_datap pData,
  517. mng_chunkid iChunkname,
  518. mng_uint32 iRawlen,
  519. mng_uint8p pRawdata)
  520. {
  521. mng_uint32 iCrc;
  522. mng_uint32 iWritten;
  523. #ifdef MNG_SUPPORT_TRACE
  524. MNG_TRACE (pData, MNG_FN_WRITE_RAW_CHUNK, MNG_LC_START);
  525. #endif
  526. /* temporary buffer ? */
  527. if ((pRawdata != 0) && (pRawdata != pData->pWritebuf+8))
  528. { /* store length & chunktype in default buffer */
  529. mng_put_uint32 (pData->pWritebuf, iRawlen);
  530. mng_put_uint32 (pData->pWritebuf+4, (mng_uint32)iChunkname);
  531. if (pData->iCrcmode & MNG_CRC_OUTPUT)
  532. {
  533. if ((pData->iCrcmode & MNG_CRC_OUTPUT) == MNG_CRC_OUTPUT_GENERATE)
  534. { /* calculate the crc */
  535. iCrc = update_crc (pData, 0xffffffffL, pData->pWritebuf+4, 4);
  536. iCrc = update_crc (pData, iCrc, pRawdata, iRawlen) ^ 0xffffffffL;
  537. } else {
  538. iCrc = 0; /* dummy crc */
  539. } /* store in default buffer */
  540. mng_put_uint32 (pData->pWritebuf+8, iCrc);
  541. }
  542. /* write the length & chunktype */
  543. if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, 8, &iWritten))
  544. MNG_ERROR (pData, MNG_APPIOERROR);
  545. if (iWritten != 8) /* disk full ? */
  546. MNG_ERROR (pData, MNG_OUTPUTERROR);
  547. /* write the temporary buffer */
  548. if (!pData->fWritedata ((mng_handle)pData, pRawdata, iRawlen, &iWritten))
  549. MNG_ERROR (pData, MNG_APPIOERROR);
  550. if (iWritten != iRawlen) /* disk full ? */
  551. MNG_ERROR (pData, MNG_OUTPUTERROR);
  552. if (pData->iCrcmode & MNG_CRC_OUTPUT)
  553. { /* write the crc */
  554. if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf+8, 4, &iWritten))
  555. MNG_ERROR (pData, MNG_APPIOERROR);
  556. if (iWritten != 4) /* disk full ? */
  557. MNG_ERROR (pData, MNG_OUTPUTERROR);
  558. }
  559. }
  560. else
  561. { /* prefix with length & chunktype */
  562. mng_put_uint32 (pData->pWritebuf, iRawlen);
  563. mng_put_uint32 (pData->pWritebuf+4, (mng_uint32)iChunkname);
  564. if (pData->iCrcmode & MNG_CRC_OUTPUT)
  565. {
  566. if ((pData->iCrcmode & MNG_CRC_OUTPUT) == MNG_CRC_OUTPUT_GENERATE)
  567. /* calculate the crc */
  568. iCrc = mng_crc (pData, pData->pWritebuf+4, iRawlen + 4);
  569. else
  570. iCrc = 0; /* dummy crc */
  571. /* add it to the buffer */
  572. mng_put_uint32 (pData->pWritebuf + iRawlen + 8, iCrc);
  573. /* write it in a single pass */
  574. if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, iRawlen + 12, &iWritten))
  575. MNG_ERROR (pData, MNG_APPIOERROR);
  576. if (iWritten != iRawlen + 12) /* disk full ? */
  577. MNG_ERROR (pData, MNG_OUTPUTERROR);
  578. } else {
  579. if (!pData->fWritedata ((mng_handle)pData, pData->pWritebuf, iRawlen + 8, &iWritten))
  580. MNG_ERROR (pData, MNG_APPIOERROR);
  581. if (iWritten != iRawlen + 8) /* disk full ? */
  582. MNG_ERROR (pData, MNG_OUTPUTERROR);
  583. }
  584. }
  585. #ifdef MNG_SUPPORT_TRACE
  586. MNG_TRACE (pData, MNG_FN_WRITE_RAW_CHUNK, MNG_LC_END);
  587. #endif
  588. return MNG_NOERROR;
  589. }
  590. /* ************************************************************************** */
  591. /* B004 */
  592. #endif /* MNG_INCLUDE_WRITE_PROCS */
  593. /* B004 */
  594. /* ************************************************************************** */
  595. /* * * */
  596. /* * chunk read functions * */
  597. /* * * */
  598. /* ************************************************************************** */
  599. #ifdef MNG_INCLUDE_READ_PROCS
  600. /* ************************************************************************** */
  601. #ifdef MNG_OPTIMIZE_CHUNKREADER
  602. /* ************************************************************************** */
  603. MNG_LOCAL mng_retcode create_chunk_storage (mng_datap pData,
  604. mng_chunkp pHeader,
  605. mng_uint32 iRawlen,
  606. mng_uint8p pRawdata,
  607. mng_field_descp pField,
  608. mng_uint16 iFields,
  609. mng_chunkp* ppChunk,
  610. mng_bool bWorkcopy)
  611. {
  612. mng_field_descp pTempfield = pField;
  613. mng_uint16 iFieldcount = iFields;
  614. mng_uint8p pTempdata = pRawdata;
  615. mng_uint32 iTemplen = iRawlen;
  616. mng_uint16 iLastgroup = 0;
  617. mng_uint8p pChunkdata;
  618. mng_uint32 iDatalen;
  619. mng_uint8 iColortype;
  620. mng_bool bProcess;
  621. /* initialize storage */
  622. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  623. if (iRetcode) /* on error bail out */
  624. return iRetcode;
  625. if (((mng_chunk_headerp)(*ppChunk))->iChunkname == MNG_UINT_HUH)
  626. ((mng_chunk_headerp)(*ppChunk))->iChunkname = pData->iChunkname;
  627. if ((!bWorkcopy) ||
  628. ((((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_IDAT) &&
  629. (((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_JDAT) &&
  630. (((mng_chunk_headerp)pHeader)->iChunkname != MNG_UINT_JDAA) ))
  631. {
  632. pChunkdata = (mng_uint8p)(*ppChunk);
  633. #ifdef MNG_INCLUDE_JNG /* determine current colortype */
  634. if (pData->bHasJHDR)
  635. iColortype = (mng_uint8)(pData->iJHDRcolortype - 8);
  636. else
  637. #endif /* MNG_INCLUDE_JNG */
  638. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  639. iColortype = pData->iColortype;
  640. else
  641. iColortype = 6;
  642. if (iTemplen) /* not empty ? */
  643. { /* then go fill the fields */
  644. while ((iFieldcount) && (iTemplen))
  645. {
  646. if (pTempfield->iOffsetchunk)
  647. {
  648. if (pTempfield->iFlags & MNG_FIELD_PUTIMGTYPE)
  649. {
  650. *(pChunkdata+pTempfield->iOffsetchunk) = iColortype;
  651. bProcess = MNG_FALSE;
  652. }
  653. else
  654. if (pTempfield->iFlags & MNG_FIELD_IFIMGTYPES)
  655. bProcess = (mng_bool)(((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE0) && (iColortype == 0)) ||
  656. ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE2) && (iColortype == 2)) ||
  657. ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE3) && (iColortype == 3)) ||
  658. ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE4) && (iColortype == 4)) ||
  659. ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE6) && (iColortype == 6)) );
  660. else
  661. bProcess = MNG_TRUE;
  662. if (bProcess)
  663. {
  664. iLastgroup = (mng_uint16)(pTempfield->iFlags & MNG_FIELD_GROUPMASK);
  665. /* numeric field ? */
  666. if (pTempfield->iFlags & MNG_FIELD_INT)
  667. {
  668. if (iTemplen < pTempfield->iLengthmax)
  669. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  670. switch (pTempfield->iLengthmax)
  671. {
  672. case 1 : { mng_uint8 iNum = *pTempdata;
  673. if (((mng_uint16)iNum < pTempfield->iMinvalue) ||
  674. ((mng_uint16)iNum > pTempfield->iMaxvalue) )
  675. MNG_ERROR (pData, MNG_INVALIDFIELDVAL);
  676. *(pChunkdata+pTempfield->iOffsetchunk) = iNum;
  677. break; }
  678. case 2 : { mng_uint16 iNum = mng_get_uint16 (pTempdata);
  679. if ((iNum < pTempfield->iMinvalue) || (iNum > pTempfield->iMaxvalue))
  680. MNG_ERROR (pData, MNG_INVALIDFIELDVAL);
  681. *((mng_uint16p)(pChunkdata+pTempfield->iOffsetchunk)) = iNum;
  682. break; }
  683. case 4 : { mng_uint32 iNum = mng_get_uint32 (pTempdata);
  684. if ((iNum < pTempfield->iMinvalue) ||
  685. ((pTempfield->iFlags & MNG_FIELD_NOHIGHBIT) && (iNum & 0x80000000)) )
  686. MNG_ERROR (pData, MNG_INVALIDFIELDVAL);
  687. *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunk)) = iNum;
  688. break; }
  689. }
  690. pTempdata += pTempfield->iLengthmax;
  691. iTemplen -= pTempfield->iLengthmax;
  692. } else { /* not numeric so it's a bunch of bytes */
  693. if (!pTempfield->iOffsetchunklen) /* big fat NONO */
  694. MNG_ERROR (pData, MNG_INTERNALERROR);
  695. /* with terminating 0 ? */
  696. if (pTempfield->iFlags & MNG_FIELD_TERMINATOR)
  697. {
  698. mng_uint8p pWork = pTempdata;
  699. while (*pWork) /* find the zero */
  700. pWork++;
  701. iDatalen = (mng_uint32)(pWork - pTempdata);
  702. } else { /* no terminator, so everything that's left ! */
  703. iDatalen = iTemplen;
  704. }
  705. if ((pTempfield->iLengthmax) && (iDatalen > pTempfield->iLengthmax))
  706. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  707. #if !defined(MNG_SKIPCHUNK_iCCP) || !defined(MNG_SKIPCHUNK_zTXt) || \
  708. !defined(MNG_SKIPCHUNK_iTXt) || defined(MNG_INCLUDE_MPNG_PROPOSAL) || \
  709. defined(MNG_INCLUDE_ANG_PROPOSAL)
  710. /* needs decompression ? */
  711. if (pTempfield->iFlags & MNG_FIELD_DEFLATED)
  712. {
  713. mng_uint8p pBuf = 0;
  714. mng_uint32 iBufsize = 0;
  715. mng_uint32 iRealsize;
  716. mng_ptr pWork;
  717. iRetcode = mng_inflate_buffer (pData, pTempdata, iDatalen,
  718. &pBuf, &iBufsize, &iRealsize);
  719. #ifdef MNG_CHECK_BAD_ICCP /* Check for bad iCCP chunk */
  720. if ((iRetcode) && (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_iCCP))
  721. {
  722. *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk)) = MNG_NULL;
  723. *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iDatalen;
  724. }
  725. else
  726. #endif
  727. {
  728. if (iRetcode)
  729. return iRetcode;
  730. #if defined(MNG_INCLUDE_MPNG_PROPOSAL) || defined(MNG_INCLUDE_ANG_PROPOSAL)
  731. if ( (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_mpNG) ||
  732. (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_adAT) )
  733. {
  734. MNG_ALLOC (pData, pWork, iRealsize);
  735. }
  736. else
  737. {
  738. #endif
  739. /* don't forget to generate null terminator */
  740. MNG_ALLOC (pData, pWork, iRealsize+1);
  741. #if defined(MNG_INCLUDE_MPNG_PROPOSAL) || defined(MNG_INCLUDE_ANG_PROPOSAL)
  742. }
  743. #endif
  744. MNG_COPY (pWork, pBuf, iRealsize);
  745. *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk)) = pWork;
  746. *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iRealsize;
  747. }
  748. if (pBuf) /* free the temporary buffer */
  749. MNG_FREEX (pData, pBuf, iBufsize);
  750. } else
  751. #endif
  752. { /* no decompression, so just copy */
  753. mng_ptr pWork;
  754. /* don't forget to generate null terminator */
  755. MNG_ALLOC (pData, pWork, iDatalen+1);
  756. MNG_COPY (pWork, pTempdata, iDatalen);
  757. *((mng_ptr *)(pChunkdata+pTempfield->iOffsetchunk)) = pWork;
  758. *((mng_uint32p)(pChunkdata+pTempfield->iOffsetchunklen)) = iDatalen;
  759. }
  760. if (pTempfield->iFlags & MNG_FIELD_TERMINATOR)
  761. iDatalen++; /* skip the terminating zero as well !!! */
  762. iTemplen -= iDatalen;
  763. pTempdata += iDatalen;
  764. }
  765. /* need to set an indicator ? */
  766. if (pTempfield->iOffsetchunkind)
  767. *((mng_uint8p)(pChunkdata+pTempfield->iOffsetchunkind)) = MNG_TRUE;
  768. }
  769. }
  770. if (pTempfield->pSpecialfunc) /* special function required ? */
  771. {
  772. iRetcode = pTempfield->pSpecialfunc(pData, *ppChunk, &iTemplen, &pTempdata);
  773. if (iRetcode) /* on error bail out */
  774. return iRetcode;
  775. }
  776. pTempfield++; /* Neeeeeeexxxtt */
  777. iFieldcount--;
  778. }
  779. if (iTemplen) /* extra data ??? */
  780. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  781. while (iFieldcount) /* not enough data ??? */
  782. {
  783. if (pTempfield->iFlags & MNG_FIELD_IFIMGTYPES)
  784. bProcess = (mng_bool)(((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE0) && (iColortype == 0)) ||
  785. ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE2) && (iColortype == 2)) ||
  786. ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE3) && (iColortype == 3)) ||
  787. ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE4) && (iColortype == 4)) ||
  788. ((pTempfield->iFlags & MNG_FIELD_IFIMGTYPE6) && (iColortype == 6)) );
  789. else
  790. bProcess = MNG_TRUE;
  791. if (bProcess)
  792. {
  793. if (!(pTempfield->iFlags & MNG_FIELD_OPTIONAL))
  794. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  795. if ((pTempfield->iFlags & MNG_FIELD_GROUPMASK) &&
  796. ((mng_uint16)(pTempfield->iFlags & MNG_FIELD_GROUPMASK) == iLastgroup))
  797. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  798. }
  799. pTempfield++;
  800. iFieldcount--;
  801. }
  802. }
  803. }
  804. return MNG_NOERROR;
  805. }
  806. /* ************************************************************************** */
  807. READ_CHUNK (mng_read_general)
  808. {
  809. mng_retcode iRetcode = MNG_NOERROR;
  810. mng_chunk_descp pDescr = ((mng_chunk_headerp)pHeader)->pChunkdescr;
  811. mng_field_descp pField;
  812. mng_uint16 iFields;
  813. if (!pDescr) /* this is a bad booboo !!! */
  814. MNG_ERROR (pData, MNG_INTERNALERROR);
  815. pField = pDescr->pFielddesc;
  816. iFields = pDescr->iFielddesc;
  817. /* check chunk against signature */
  818. if ((pDescr->eImgtype == mng_it_mng) && (pData->eSigtype != mng_it_mng))
  819. MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
  820. if ((pDescr->eImgtype == mng_it_jng) && (pData->eSigtype == mng_it_png))
  821. MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
  822. /* empties allowed ? */
  823. if ((iRawlen == 0) && (!(pDescr->iAllowed & MNG_DESCR_EMPTY)))
  824. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  825. if ((pData->eImagetype != mng_it_mng) || (!(pDescr->iAllowed & MNG_DESCR_GLOBAL)))
  826. { /* *a* header required ? */
  827. if ((pDescr->iMusthaves & MNG_DESCR_GenHDR) &&
  828. #ifdef MNG_INCLUDE_JNG
  829. (!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  830. #else
  831. (!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR))
  832. #endif
  833. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  834. #ifdef MNG_INCLUDE_JNG
  835. if ((pDescr->iMusthaves & MNG_DESCR_JngHDR) &&
  836. (!pData->bHasDHDR) && (!pData->bHasJHDR))
  837. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  838. #endif
  839. }
  840. /* specific chunk pre-requisite ? */
  841. if (((pDescr->iMusthaves & MNG_DESCR_IHDR) && (!pData->bHasIHDR)) ||
  842. #ifdef MNG_INCLUDE_JNG
  843. ((pDescr->iMusthaves & MNG_DESCR_JHDR) && (!pData->bHasJHDR)) ||
  844. #endif
  845. ((pDescr->iMusthaves & MNG_DESCR_DHDR) && (!pData->bHasDHDR)) ||
  846. ((pDescr->iMusthaves & MNG_DESCR_LOOP) && (!pData->bHasLOOP)) ||
  847. ((pDescr->iMusthaves & MNG_DESCR_PLTE) && (!pData->bHasPLTE)) ||
  848. ((pDescr->iMusthaves & MNG_DESCR_MHDR) && (!pData->bHasMHDR)) ||
  849. ((pDescr->iMusthaves & MNG_DESCR_SAVE) && (!pData->bHasSAVE)) )
  850. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  851. /* specific chunk undesired ? */
  852. if (((pDescr->iMustNOThaves & MNG_DESCR_NOIHDR) && (pData->bHasIHDR)) ||
  853. ((pDescr->iMustNOThaves & MNG_DESCR_NOBASI) && (pData->bHasBASI)) ||
  854. ((pDescr->iMustNOThaves & MNG_DESCR_NODHDR) && (pData->bHasDHDR)) ||
  855. ((pDescr->iMustNOThaves & MNG_DESCR_NOIDAT) && (pData->bHasIDAT)) ||
  856. ((pDescr->iMustNOThaves & MNG_DESCR_NOPLTE) && (pData->bHasPLTE)) ||
  857. #ifdef MNG_INCLUDE_JNG
  858. ((pDescr->iMustNOThaves & MNG_DESCR_NOJHDR) && (pData->bHasJHDR)) ||
  859. ((pDescr->iMustNOThaves & MNG_DESCR_NOJDAT) && (pData->bHasJDAT)) ||
  860. ((pDescr->iMustNOThaves & MNG_DESCR_NOJDAA) && (pData->bHasJDAA)) ||
  861. ((pDescr->iMustNOThaves & MNG_DESCR_NOJSEP) && (pData->bHasJSEP)) ||
  862. #endif
  863. ((pDescr->iMustNOThaves & MNG_DESCR_NOMHDR) && (pData->bHasMHDR)) ||
  864. ((pDescr->iMustNOThaves & MNG_DESCR_NOLOOP) && (pData->bHasLOOP)) ||
  865. ((pDescr->iMustNOThaves & MNG_DESCR_NOTERM) && (pData->bHasTERM)) ||
  866. ((pDescr->iMustNOThaves & MNG_DESCR_NOSAVE) && (pData->bHasSAVE)) )
  867. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  868. if (pData->eSigtype == mng_it_mng) /* check global and embedded empty chunks */
  869. {
  870. #ifdef MNG_INCLUDE_JNG
  871. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  872. #else
  873. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  874. #endif
  875. {
  876. if ((iRawlen == 0) && (!(pDescr->iAllowed & MNG_DESCR_EMPTYEMBED)))
  877. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  878. } else {
  879. if ((iRawlen == 0) && (!(pDescr->iAllowed & MNG_DESCR_EMPTYGLOBAL)))
  880. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  881. }
  882. }
  883. if (pDescr->pSpecialfunc) /* need special processing ? */
  884. {
  885. iRetcode = create_chunk_storage (pData, pHeader, iRawlen, pRawdata,
  886. pField, iFields, ppChunk, MNG_TRUE);
  887. if (iRetcode) /* on error bail out */
  888. return iRetcode;
  889. /* empty indicator ? */
  890. if ((!iRawlen) && (pDescr->iOffsetempty))
  891. *(((mng_uint8p)*ppChunk)+pDescr->iOffsetempty) = MNG_TRUE;
  892. iRetcode = pDescr->pSpecialfunc(pData, *ppChunk);
  893. if (iRetcode) /* on error bail out */
  894. return iRetcode;
  895. if ((((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_IDAT) ||
  896. (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAT) ||
  897. (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAA) )
  898. {
  899. iRetcode = ((mng_chunk_headerp)*ppChunk)->fCleanup (pData, *ppChunk);
  900. if (iRetcode) /* on error bail out */
  901. return iRetcode;
  902. *ppChunk = MNG_NULL;
  903. } else {
  904. #ifdef MNG_STORE_CHUNKS
  905. if (!pData->bStorechunks)
  906. #endif
  907. {
  908. iRetcode = ((mng_chunk_headerp)*ppChunk)->fCleanup (pData, *ppChunk);
  909. if (iRetcode) /* on error bail out */
  910. return iRetcode;
  911. *ppChunk = MNG_NULL;
  912. }
  913. }
  914. }
  915. #ifdef MNG_SUPPORT_DISPLAY
  916. if (iRawlen)
  917. {
  918. #ifdef MNG_OPTIMIZE_DISPLAYCALLS
  919. pData->iRawlen = iRawlen;
  920. pData->pRawdata = pRawdata;
  921. #endif
  922. /* display processing */
  923. #ifndef MNG_OPTIMIZE_DISPLAYCALLS
  924. if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_IDAT)
  925. iRetcode = mng_process_display_idat (pData, iRawlen, pRawdata);
  926. #ifdef MNG_INCLUDE_JNG
  927. else
  928. if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAT)
  929. iRetcode = mng_process_display_jdat (pData, iRawlen, pRawdata);
  930. else
  931. if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAA)
  932. iRetcode = mng_process_display_jdaa (pData, iRawlen, pRawdata);
  933. #endif
  934. #else
  935. if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_IDAT)
  936. iRetcode = mng_process_display_idat (pData);
  937. #ifdef MNG_INCLUDE_JNG
  938. else
  939. if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAT)
  940. iRetcode = mng_process_display_jdat (pData);
  941. else
  942. if (((mng_chunk_headerp)pHeader)->iChunkname == MNG_UINT_JDAA)
  943. iRetcode = mng_process_display_jdaa (pData);
  944. #endif
  945. #endif
  946. if (iRetcode)
  947. return iRetcode;
  948. }
  949. #endif /* MNG_SUPPORT_DISPLAY */
  950. #ifdef MNG_STORE_CHUNKS
  951. if ((pData->bStorechunks) && (!(*ppChunk)))
  952. {
  953. iRetcode = create_chunk_storage (pData, pHeader, iRawlen, pRawdata,
  954. pField, iFields, ppChunk, MNG_FALSE);
  955. if (iRetcode) /* on error bail out */
  956. return iRetcode;
  957. /* empty indicator ? */
  958. if ((!iRawlen) && (pDescr->iOffsetempty))
  959. *(((mng_uint8p)*ppChunk)+pDescr->iOffsetempty) = MNG_TRUE;
  960. }
  961. #endif /* MNG_STORE_CHUNKS */
  962. return MNG_NOERROR;
  963. }
  964. /* ************************************************************************** */
  965. #endif /* MNG_OPTIMIZE_CHUNKREADER */
  966. /* ************************************************************************** */
  967. #ifndef MNG_OPTIMIZE_CHUNKREADER
  968. READ_CHUNK (mng_read_ihdr)
  969. {
  970. #ifdef MNG_SUPPORT_TRACE
  971. MNG_TRACE (pData, MNG_FN_READ_IHDR, MNG_LC_START);
  972. #endif
  973. if (iRawlen != 13) /* length oke ? */
  974. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  975. /* only allowed inside PNG or MNG */
  976. if ((pData->eSigtype != mng_it_png) && (pData->eSigtype != mng_it_mng))
  977. MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
  978. /* sequence checks */
  979. if ((pData->eSigtype == mng_it_png) && (pData->iChunkseq > 1))
  980. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  981. #ifdef MNG_INCLUDE_JNG
  982. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasIDAT) || (pData->bHasJHDR))
  983. #else
  984. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasIDAT))
  985. #endif
  986. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  987. pData->bHasIHDR = MNG_TRUE; /* indicate IHDR is present */
  988. /* and store interesting fields */
  989. if ((!pData->bHasDHDR) || (pData->iDeltatype == MNG_DELTATYPE_NOCHANGE))
  990. {
  991. pData->iDatawidth = mng_get_uint32 (pRawdata);
  992. pData->iDataheight = mng_get_uint32 (pRawdata+4);
  993. }
  994. pData->iBitdepth = *(pRawdata+8);
  995. pData->iColortype = *(pRawdata+9);
  996. pData->iCompression = *(pRawdata+10);
  997. pData->iFilter = *(pRawdata+11);
  998. pData->iInterlace = *(pRawdata+12);
  999. #if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT)
  1000. pData->iPNGmult = 1;
  1001. pData->iPNGdepth = pData->iBitdepth;
  1002. #endif
  1003. #ifdef MNG_NO_1_2_4BIT_SUPPORT
  1004. if (pData->iBitdepth < 8)
  1005. pData->iBitdepth = 8;
  1006. #endif
  1007. #ifdef MNG_NO_16BIT_SUPPORT
  1008. if (pData->iBitdepth > 8)
  1009. {
  1010. pData->iBitdepth = 8;
  1011. pData->iPNGmult = 2;
  1012. }
  1013. #endif
  1014. if ((pData->iBitdepth != 8) /* parameter validity checks */
  1015. #ifndef MNG_NO_1_2_4BIT_SUPPORT
  1016. && (pData->iBitdepth != 1) &&
  1017. (pData->iBitdepth != 2) &&
  1018. (pData->iBitdepth != 4)
  1019. #endif
  1020. #ifndef MNG_NO_16BIT_SUPPORT
  1021. && (pData->iBitdepth != 16)
  1022. #endif
  1023. )
  1024. MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
  1025. if ((pData->iColortype != MNG_COLORTYPE_GRAY ) &&
  1026. (pData->iColortype != MNG_COLORTYPE_RGB ) &&
  1027. (pData->iColortype != MNG_COLORTYPE_INDEXED) &&
  1028. (pData->iColortype != MNG_COLORTYPE_GRAYA ) &&
  1029. (pData->iColortype != MNG_COLORTYPE_RGBA ) )
  1030. MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
  1031. if ((pData->iColortype == MNG_COLORTYPE_INDEXED) && (pData->iBitdepth > 8))
  1032. MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
  1033. if (((pData->iColortype == MNG_COLORTYPE_RGB ) ||
  1034. (pData->iColortype == MNG_COLORTYPE_GRAYA ) ||
  1035. (pData->iColortype == MNG_COLORTYPE_RGBA ) ) &&
  1036. (pData->iBitdepth < 8 ) )
  1037. MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
  1038. if (pData->iCompression != MNG_COMPRESSION_DEFLATE)
  1039. MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
  1040. #if defined(FILTER192) || defined(FILTER193)
  1041. if ((pData->iFilter != MNG_FILTER_ADAPTIVE ) &&
  1042. #if defined(FILTER192) && defined(FILTER193)
  1043. (pData->iFilter != MNG_FILTER_DIFFERING) &&
  1044. (pData->iFilter != MNG_FILTER_NOFILTER ) )
  1045. #else
  1046. #ifdef FILTER192
  1047. (pData->iFilter != MNG_FILTER_DIFFERING) )
  1048. #else
  1049. (pData->iFilter != MNG_FILTER_NOFILTER ) )
  1050. #endif
  1051. #endif
  1052. MNG_ERROR (pData, MNG_INVALIDFILTER);
  1053. #else
  1054. if (pData->iFilter)
  1055. MNG_ERROR (pData, MNG_INVALIDFILTER);
  1056. #endif
  1057. if ((pData->iInterlace != MNG_INTERLACE_NONE ) &&
  1058. (pData->iInterlace != MNG_INTERLACE_ADAM7) )
  1059. MNG_ERROR (pData, MNG_INVALIDINTERLACE);
  1060. #ifdef MNG_SUPPORT_DISPLAY
  1061. #ifndef MNG_NO_DELTA_PNG
  1062. if (pData->bHasDHDR) /* check the colortype for delta-images ! */
  1063. {
  1064. mng_imagedatap pBuf = ((mng_imagep)pData->pObjzero)->pImgbuf;
  1065. if (pData->iColortype != pBuf->iColortype)
  1066. {
  1067. if ( ( (pData->iColortype != MNG_COLORTYPE_INDEXED) ||
  1068. (pBuf->iColortype == MNG_COLORTYPE_GRAY ) ) &&
  1069. ( (pData->iColortype != MNG_COLORTYPE_GRAY ) ||
  1070. (pBuf->iColortype == MNG_COLORTYPE_INDEXED) ) )
  1071. MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
  1072. }
  1073. }
  1074. #endif
  1075. #endif
  1076. if (!pData->bHasheader) /* first chunk ? */
  1077. {
  1078. pData->bHasheader = MNG_TRUE; /* we've got a header */
  1079. pData->eImagetype = mng_it_png; /* then this must be a PNG */
  1080. pData->iWidth = pData->iDatawidth;
  1081. pData->iHeight = pData->iDataheight;
  1082. /* predict alpha-depth ! */
  1083. if ((pData->iColortype == MNG_COLORTYPE_GRAYA ) ||
  1084. (pData->iColortype == MNG_COLORTYPE_RGBA ) )
  1085. pData->iAlphadepth = pData->iBitdepth;
  1086. else
  1087. if (pData->iColortype == MNG_COLORTYPE_INDEXED)
  1088. pData->iAlphadepth = 8; /* worst case scenario */
  1089. else
  1090. pData->iAlphadepth = 1; /* Possible tRNS cheap binary transparency */
  1091. /* fits on maximum canvas ? */
  1092. if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
  1093. MNG_WARNING (pData, MNG_IMAGETOOLARGE);
  1094. #if !defined(MNG_INCLUDE_MPNG_PROPOSAL) || !defined(MNG_SUPPORT_DISPLAY)
  1095. if (pData->fProcessheader) /* inform the app ? */
  1096. if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
  1097. MNG_ERROR (pData, MNG_APPMISCERROR);
  1098. #endif
  1099. }
  1100. if (!pData->bHasDHDR)
  1101. pData->iImagelevel++; /* one level deeper */
  1102. #ifdef MNG_SUPPORT_DISPLAY
  1103. {
  1104. mng_retcode iRetcode = mng_process_display_ihdr (pData);
  1105. if (iRetcode) /* on error bail out */
  1106. return iRetcode;
  1107. }
  1108. #endif /* MNG_SUPPORT_DISPLAY */
  1109. #ifdef MNG_STORE_CHUNKS
  1110. if (pData->bStorechunks)
  1111. { /* initialize storage */
  1112. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  1113. if (iRetcode) /* on error bail out */
  1114. return iRetcode;
  1115. /* fill the fields */
  1116. ((mng_ihdrp)*ppChunk)->iWidth = mng_get_uint32 (pRawdata);
  1117. ((mng_ihdrp)*ppChunk)->iHeight = mng_get_uint32 (pRawdata+4);
  1118. ((mng_ihdrp)*ppChunk)->iBitdepth = pData->iBitdepth;
  1119. ((mng_ihdrp)*ppChunk)->iColortype = pData->iColortype;
  1120. ((mng_ihdrp)*ppChunk)->iCompression = pData->iCompression;
  1121. ((mng_ihdrp)*ppChunk)->iFilter = pData->iFilter;
  1122. ((mng_ihdrp)*ppChunk)->iInterlace = pData->iInterlace;
  1123. }
  1124. #endif /* MNG_STORE_CHUNKS */
  1125. #ifdef MNG_SUPPORT_TRACE
  1126. MNG_TRACE (pData, MNG_FN_READ_IHDR, MNG_LC_END);
  1127. #endif
  1128. return MNG_NOERROR; /* done */
  1129. }
  1130. #endif /* MNG_OPTIMIZE_CHUNKREADER */
  1131. /* ************************************************************************** */
  1132. #ifndef MNG_OPTIMIZE_CHUNKREADER
  1133. READ_CHUNK (mng_read_plte)
  1134. {
  1135. #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
  1136. mng_uint32 iX;
  1137. mng_uint8p pRawdata2;
  1138. #endif
  1139. #ifdef MNG_SUPPORT_DISPLAY
  1140. mng_uint32 iRawlen2;
  1141. #endif
  1142. #ifdef MNG_SUPPORT_TRACE
  1143. MNG_TRACE (pData, MNG_FN_READ_PLTE, MNG_LC_START);
  1144. #endif
  1145. /* sequence checks */
  1146. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  1147. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  1148. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  1149. #ifdef MNG_INCLUDE_JNG
  1150. if ((pData->bHasIDAT) || (pData->bHasJHDR))
  1151. #else
  1152. if (pData->bHasIDAT)
  1153. #endif
  1154. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  1155. /* multiple PLTE only inside BASI */
  1156. if ((pData->bHasPLTE) && (!pData->bHasBASI))
  1157. MNG_ERROR (pData, MNG_MULTIPLEERROR);
  1158. /* length must be multiple of 3 */
  1159. if (((iRawlen % 3) != 0) || (iRawlen > 768))
  1160. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  1161. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1162. { /* only allowed for indexed-color or
  1163. rgb(a)-color! */
  1164. if ((pData->iColortype != 2) && (pData->iColortype != 3) && (pData->iColortype != 6))
  1165. MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
  1166. /* empty only allowed if global present */
  1167. if ((iRawlen == 0) && (!pData->bHasglobalPLTE))
  1168. MNG_ERROR (pData, MNG_CANNOTBEEMPTY);
  1169. }
  1170. else
  1171. {
  1172. if (iRawlen == 0) /* cannot be empty as global! */
  1173. MNG_ERROR (pData, MNG_CANNOTBEEMPTY);
  1174. }
  1175. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1176. pData->bHasPLTE = MNG_TRUE; /* got it! */
  1177. else
  1178. pData->bHasglobalPLTE = MNG_TRUE;
  1179. pData->iPLTEcount = iRawlen / 3;
  1180. #ifdef MNG_SUPPORT_DISPLAY
  1181. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1182. {
  1183. mng_imagep pImage;
  1184. mng_imagedatap pBuf;
  1185. #ifndef MNG_NO_DELTA_PNG
  1186. if (pData->bHasDHDR) /* processing delta-image ? */
  1187. { /* store in object 0 !!! */
  1188. pImage = (mng_imagep)pData->pObjzero;
  1189. pBuf = pImage->pImgbuf;
  1190. pBuf->bHasPLTE = MNG_TRUE; /* it's definitely got a PLTE now */
  1191. pBuf->iPLTEcount = iRawlen / 3; /* this is the exact length */
  1192. pRawdata2 = pRawdata; /* copy the entries */
  1193. for (iX = 0; iX < iRawlen / 3; iX++)
  1194. {
  1195. pBuf->aPLTEentries[iX].iRed = *pRawdata2;
  1196. pBuf->aPLTEentries[iX].iGreen = *(pRawdata2+1);
  1197. pBuf->aPLTEentries[iX].iBlue = *(pRawdata2+2);
  1198. pRawdata2 += 3;
  1199. }
  1200. }
  1201. else
  1202. #endif
  1203. { /* get the current object */
  1204. pImage = (mng_imagep)pData->pCurrentobj;
  1205. if (!pImage) /* no object then dump it in obj 0 */
  1206. pImage = (mng_imagep)pData->pObjzero;
  1207. pBuf = pImage->pImgbuf; /* address the object buffer */
  1208. pBuf->bHasPLTE = MNG_TRUE; /* and tell it it's got a PLTE now */
  1209. if (!iRawlen) /* if empty, inherit from global */
  1210. {
  1211. pBuf->iPLTEcount = pData->iGlobalPLTEcount;
  1212. MNG_COPY (pBuf->aPLTEentries, pData->aGlobalPLTEentries,
  1213. sizeof (pBuf->aPLTEentries));
  1214. if (pData->bHasglobalTRNS) /* also copy global tRNS ? */
  1215. { /* indicate tRNS available */
  1216. pBuf->bHasTRNS = MNG_TRUE;
  1217. iRawlen2 = pData->iGlobalTRNSrawlen;
  1218. pRawdata2 = (mng_uint8p)(pData->aGlobalTRNSrawdata);
  1219. /* global length oke ? */
  1220. if ((iRawlen2 == 0) || (iRawlen2 > pBuf->iPLTEcount))
  1221. MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
  1222. /* copy it */
  1223. pBuf->iTRNScount = iRawlen2;
  1224. MNG_COPY (pBuf->aTRNSentries, pRawdata2, iRawlen2);
  1225. }
  1226. }
  1227. else
  1228. { /* store fields for future reference */
  1229. pBuf->iPLTEcount = iRawlen / 3;
  1230. pRawdata2 = pRawdata;
  1231. for (iX = 0; iX < pBuf->iPLTEcount; iX++)
  1232. {
  1233. pBuf->aPLTEentries[iX].iRed = *pRawdata2;
  1234. pBuf->aPLTEentries[iX].iGreen = *(pRawdata2+1);
  1235. pBuf->aPLTEentries[iX].iBlue = *(pRawdata2+2);
  1236. pRawdata2 += 3;
  1237. }
  1238. }
  1239. }
  1240. }
  1241. else /* store as global */
  1242. {
  1243. pData->iGlobalPLTEcount = iRawlen / 3;
  1244. pRawdata2 = pRawdata;
  1245. for (iX = 0; iX < pData->iGlobalPLTEcount; iX++)
  1246. {
  1247. pData->aGlobalPLTEentries[iX].iRed = *pRawdata2;
  1248. pData->aGlobalPLTEentries[iX].iGreen = *(pRawdata2+1);
  1249. pData->aGlobalPLTEentries[iX].iBlue = *(pRawdata2+2);
  1250. pRawdata2 += 3;
  1251. }
  1252. { /* create an animation object */
  1253. mng_retcode iRetcode = mng_create_ani_plte (pData, pData->iGlobalPLTEcount,
  1254. pData->aGlobalPLTEentries);
  1255. if (iRetcode) /* on error bail out */
  1256. return iRetcode;
  1257. }
  1258. }
  1259. #endif /* MNG_SUPPORT_DISPLAY */
  1260. #ifdef MNG_STORE_CHUNKS
  1261. if (pData->bStorechunks)
  1262. { /* initialize storage */
  1263. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  1264. if (iRetcode) /* on error bail out */
  1265. return iRetcode;
  1266. /* store the fields */
  1267. ((mng_pltep)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  1268. ((mng_pltep)*ppChunk)->iEntrycount = iRawlen / 3;
  1269. pRawdata2 = pRawdata;
  1270. for (iX = 0; iX < ((mng_pltep)*ppChunk)->iEntrycount; iX++)
  1271. {
  1272. ((mng_pltep)*ppChunk)->aEntries[iX].iRed = *pRawdata2;
  1273. ((mng_pltep)*ppChunk)->aEntries[iX].iGreen = *(pRawdata2+1);
  1274. ((mng_pltep)*ppChunk)->aEntries[iX].iBlue = *(pRawdata2+2);
  1275. pRawdata2 += 3;
  1276. }
  1277. }
  1278. #endif /* MNG_STORE_CHUNKS */
  1279. #ifdef MNG_SUPPORT_TRACE
  1280. MNG_TRACE (pData, MNG_FN_READ_PLTE, MNG_LC_END);
  1281. #endif
  1282. return MNG_NOERROR; /* done */
  1283. }
  1284. #endif /* MNG_OPTIMIZE_CHUNKREADER */
  1285. /* ************************************************************************** */
  1286. #ifndef MNG_OPTIMIZE_CHUNKREADER
  1287. READ_CHUNK (mng_read_idat)
  1288. {
  1289. #ifdef MNG_SUPPORT_TRACE
  1290. MNG_TRACE (pData, MNG_FN_READ_IDAT, MNG_LC_START);
  1291. #endif
  1292. #ifdef MNG_INCLUDE_JNG /* sequence checks */
  1293. if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  1294. #else
  1295. if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR))
  1296. #endif
  1297. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  1298. #ifdef MNG_INCLUDE_JNG
  1299. if ((pData->bHasJHDR) &&
  1300. (pData->iJHDRalphacompression != MNG_COMPRESSION_DEFLATE))
  1301. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  1302. if (pData->bHasJSEP)
  1303. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  1304. #endif
  1305. /* not allowed for deltatype NO_CHANGE */
  1306. #ifndef MNG_NO_DELTA_PNG
  1307. if ((pData->bHasDHDR) && ((pData->iDeltatype == MNG_DELTATYPE_NOCHANGE)))
  1308. MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
  1309. #endif
  1310. /* can only be empty in BASI-block! */
  1311. if ((iRawlen == 0) && (!pData->bHasBASI))
  1312. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  1313. /* indexed-color requires PLTE */
  1314. if ((pData->bHasIHDR) && (pData->iColortype == 3) && (!pData->bHasPLTE))
  1315. MNG_ERROR (pData, MNG_PLTEMISSING);
  1316. pData->bHasIDAT = MNG_TRUE; /* got some IDAT now, don't we */
  1317. #ifdef MNG_SUPPORT_DISPLAY
  1318. if (iRawlen)
  1319. { /* display processing */
  1320. mng_retcode iRetcode = mng_process_display_idat (pData, iRawlen, pRawdata);
  1321. if (iRetcode) /* on error bail out */
  1322. return iRetcode;
  1323. }
  1324. #endif /* MNG_SUPPORT_DISPLAY */
  1325. #ifdef MNG_STORE_CHUNKS
  1326. if (pData->bStorechunks)
  1327. { /* initialize storage */
  1328. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  1329. if (iRetcode) /* on error bail out */
  1330. return iRetcode;
  1331. /* store the fields */
  1332. ((mng_idatp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  1333. ((mng_idatp)*ppChunk)->iDatasize = iRawlen;
  1334. if (iRawlen != 0) /* is there any data ? */
  1335. {
  1336. MNG_ALLOC (pData, ((mng_idatp)*ppChunk)->pData, iRawlen);
  1337. MNG_COPY (((mng_idatp)*ppChunk)->pData, pRawdata, iRawlen);
  1338. }
  1339. }
  1340. #endif /* MNG_STORE_CHUNKS */
  1341. #ifdef MNG_SUPPORT_TRACE
  1342. MNG_TRACE (pData, MNG_FN_READ_IDAT, MNG_LC_END);
  1343. #endif
  1344. return MNG_NOERROR; /* done */
  1345. }
  1346. #endif
  1347. /* ************************************************************************** */
  1348. #ifndef MNG_OPTIMIZE_CHUNKREADER
  1349. READ_CHUNK (mng_read_iend)
  1350. {
  1351. #ifdef MNG_SUPPORT_TRACE
  1352. MNG_TRACE (pData, MNG_FN_READ_IEND, MNG_LC_START);
  1353. #endif
  1354. if (iRawlen > 0) /* must not contain data! */
  1355. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  1356. #ifdef MNG_INCLUDE_JNG /* sequence checks */
  1357. if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  1358. #else
  1359. if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR))
  1360. #endif
  1361. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  1362. /* IHDR-block requires IDAT */
  1363. if ((pData->bHasIHDR) && (!pData->bHasIDAT))
  1364. MNG_ERROR (pData, MNG_IDATMISSING);
  1365. pData->iImagelevel--; /* one level up */
  1366. #ifdef MNG_SUPPORT_DISPLAY
  1367. { /* create an animation object */
  1368. mng_retcode iRetcode = mng_create_ani_image (pData);
  1369. if (iRetcode) /* on error bail out */
  1370. return iRetcode;
  1371. /* display processing */
  1372. iRetcode = mng_process_display_iend (pData);
  1373. if (iRetcode) /* on error bail out */
  1374. return iRetcode;
  1375. }
  1376. #endif /* MNG_SUPPORT_DISPLAY */
  1377. #ifdef MNG_SUPPORT_DISPLAY
  1378. if (!pData->bTimerset) /* reset only if not broken !!! */
  1379. {
  1380. #endif
  1381. /* IEND signals the end for most ... */
  1382. pData->bHasIHDR = MNG_FALSE;
  1383. pData->bHasBASI = MNG_FALSE;
  1384. pData->bHasDHDR = MNG_FALSE;
  1385. #ifdef MNG_INCLUDE_JNG
  1386. pData->bHasJHDR = MNG_FALSE;
  1387. pData->bHasJSEP = MNG_FALSE;
  1388. pData->bHasJDAA = MNG_FALSE;
  1389. pData->bHasJDAT = MNG_FALSE;
  1390. #endif
  1391. pData->bHasPLTE = MNG_FALSE;
  1392. pData->bHasTRNS = MNG_FALSE;
  1393. pData->bHasGAMA = MNG_FALSE;
  1394. pData->bHasCHRM = MNG_FALSE;
  1395. pData->bHasSRGB = MNG_FALSE;
  1396. pData->bHasICCP = MNG_FALSE;
  1397. pData->bHasBKGD = MNG_FALSE;
  1398. pData->bHasIDAT = MNG_FALSE;
  1399. #ifdef MNG_SUPPORT_DISPLAY
  1400. }
  1401. #endif
  1402. #ifdef MNG_STORE_CHUNKS
  1403. if (pData->bStorechunks)
  1404. { /* initialize storage */
  1405. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  1406. if (iRetcode) /* on error bail out */
  1407. return iRetcode;
  1408. }
  1409. #endif /* MNG_STORE_CHUNKS */
  1410. #ifdef MNG_SUPPORT_TRACE
  1411. MNG_TRACE (pData, MNG_FN_READ_IEND, MNG_LC_END);
  1412. #endif
  1413. return MNG_NOERROR; /* done */
  1414. }
  1415. #endif
  1416. /* ************************************************************************** */
  1417. #ifndef MNG_OPTIMIZE_CHUNKREADER
  1418. READ_CHUNK (mng_read_trns)
  1419. {
  1420. #ifdef MNG_SUPPORT_TRACE
  1421. MNG_TRACE (pData, MNG_FN_READ_TRNS, MNG_LC_START);
  1422. #endif
  1423. /* sequence checks */
  1424. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  1425. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  1426. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  1427. #ifdef MNG_INCLUDE_JNG
  1428. if ((pData->bHasIDAT) || (pData->bHasJHDR))
  1429. #else
  1430. if (pData->bHasIDAT)
  1431. #endif
  1432. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  1433. /* multiple tRNS only inside BASI */
  1434. if ((pData->bHasTRNS) && (!pData->bHasBASI))
  1435. MNG_ERROR (pData, MNG_MULTIPLEERROR);
  1436. if (iRawlen > 256) /* it just can't be bigger than that! */
  1437. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  1438. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1439. { /* not allowed with full alpha-channel */
  1440. if ((pData->iColortype == 4) || (pData->iColortype == 6))
  1441. MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
  1442. if (iRawlen != 0) /* filled ? */
  1443. { /* length checks */
  1444. if ((pData->iColortype == 0) && (iRawlen != 2))
  1445. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  1446. if ((pData->iColortype == 2) && (iRawlen != 6))
  1447. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  1448. #ifdef MNG_SUPPORT_DISPLAY
  1449. if (pData->iColortype == 3)
  1450. {
  1451. mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
  1452. mng_imagedatap pBuf;
  1453. if (!pImage) /* no object then check obj 0 */
  1454. pImage = (mng_imagep)pData->pObjzero;
  1455. pBuf = pImage->pImgbuf; /* address object buffer */
  1456. if (iRawlen > pBuf->iPLTEcount)
  1457. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  1458. }
  1459. #endif
  1460. }
  1461. else /* if empty there must be global stuff! */
  1462. {
  1463. if (!pData->bHasglobalTRNS)
  1464. MNG_ERROR (pData, MNG_CANNOTBEEMPTY);
  1465. }
  1466. }
  1467. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1468. pData->bHasTRNS = MNG_TRUE; /* indicate tRNS available */
  1469. else
  1470. pData->bHasglobalTRNS = MNG_TRUE;
  1471. #ifdef MNG_SUPPORT_DISPLAY
  1472. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1473. {
  1474. mng_imagep pImage;
  1475. mng_imagedatap pBuf;
  1476. mng_uint8p pRawdata2;
  1477. mng_uint32 iRawlen2;
  1478. #ifndef MNG_NO_DELTA_PNG
  1479. if (pData->bHasDHDR) /* processing delta-image ? */
  1480. { /* store in object 0 !!! */
  1481. pImage = (mng_imagep)pData->pObjzero;
  1482. pBuf = pImage->pImgbuf; /* address object buffer */
  1483. switch (pData->iColortype) /* store fields for future reference */
  1484. {
  1485. case 0: { /* gray */
  1486. #if defined(MNG_NO_1_2_4BIT_SUPPORT)
  1487. mng_uint8 multiplier[]={0,255,85,0,17,0,0,0,1,
  1488. 0,0,0,0,0,0,0,1};
  1489. #endif
  1490. pBuf->iTRNSgray = mng_get_uint16 (pRawdata);
  1491. pBuf->iTRNSred = 0;
  1492. pBuf->iTRNSgreen = 0;
  1493. pBuf->iTRNSblue = 0;
  1494. pBuf->iTRNScount = 0;
  1495. #if defined(MNG_NO_1_2_4BIT_SUPPORT)
  1496. pBuf->iTRNSgray *= multiplier[pData->iPNGdepth];
  1497. #endif
  1498. #if defined(MNG_NO_16BIT_SUPPORT)
  1499. if (pData->iPNGmult == 2)
  1500. pBuf->iTRNSgray >>= 8;
  1501. #endif
  1502. break;
  1503. }
  1504. case 2: { /* rgb */
  1505. pBuf->iTRNSgray = 0;
  1506. pBuf->iTRNSred = mng_get_uint16 (pRawdata);
  1507. pBuf->iTRNSgreen = mng_get_uint16 (pRawdata+2);
  1508. pBuf->iTRNSblue = mng_get_uint16 (pRawdata+4);
  1509. pBuf->iTRNScount = 0;
  1510. #if defined(MNG_NO_16BIT_SUPPORT)
  1511. if (pData->iPNGmult == 2)
  1512. {
  1513. pBuf->iTRNSred >>= 8;
  1514. pBuf->iTRNSgreen >>= 8;
  1515. pBuf->iTRNSblue >>= 8;
  1516. }
  1517. #endif
  1518. break;
  1519. }
  1520. case 3: { /* indexed */
  1521. pBuf->iTRNSgray = 0;
  1522. pBuf->iTRNSred = 0;
  1523. pBuf->iTRNSgreen = 0;
  1524. pBuf->iTRNSblue = 0;
  1525. pBuf->iTRNScount = iRawlen;
  1526. MNG_COPY (pBuf->aTRNSentries, pRawdata, iRawlen);
  1527. break;
  1528. }
  1529. }
  1530. pBuf->bHasTRNS = MNG_TRUE; /* tell it it's got a tRNS now */
  1531. }
  1532. else
  1533. #endif
  1534. { /* address current object */
  1535. pImage = (mng_imagep)pData->pCurrentobj;
  1536. if (!pImage) /* no object then dump it in obj 0 */
  1537. pImage = (mng_imagep)pData->pObjzero;
  1538. pBuf = pImage->pImgbuf; /* address object buffer */
  1539. pBuf->bHasTRNS = MNG_TRUE; /* and tell it it's got a tRNS now */
  1540. if (iRawlen == 0) /* if empty, inherit from global */
  1541. {
  1542. iRawlen2 = pData->iGlobalTRNSrawlen;
  1543. pRawdata2 = (mng_ptr)(pData->aGlobalTRNSrawdata);
  1544. /* global length oke ? */
  1545. if ((pData->iColortype == 0) && (iRawlen2 != 2))
  1546. MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
  1547. if ((pData->iColortype == 2) && (iRawlen2 != 6))
  1548. MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
  1549. if ((pData->iColortype == 3) && ((iRawlen2 == 0) || (iRawlen2 > pBuf->iPLTEcount)))
  1550. MNG_ERROR (pData, MNG_GLOBALLENGTHERR);
  1551. }
  1552. else
  1553. {
  1554. iRawlen2 = iRawlen;
  1555. pRawdata2 = pRawdata;
  1556. }
  1557. switch (pData->iColortype) /* store fields for future reference */
  1558. {
  1559. case 0: { /* gray */
  1560. pBuf->iTRNSgray = mng_get_uint16 (pRawdata2);
  1561. pBuf->iTRNSred = 0;
  1562. pBuf->iTRNSgreen = 0;
  1563. pBuf->iTRNSblue = 0;
  1564. pBuf->iTRNScount = 0;
  1565. #if defined(MNG_NO_16BIT_SUPPORT)
  1566. if (pData->iPNGmult == 2)
  1567. pBuf->iTRNSgray >>= 8;
  1568. #endif
  1569. break;
  1570. }
  1571. case 2: { /* rgb */
  1572. pBuf->iTRNSgray = 0;
  1573. pBuf->iTRNSred = mng_get_uint16 (pRawdata2);
  1574. pBuf->iTRNSgreen = mng_get_uint16 (pRawdata2+2);
  1575. pBuf->iTRNSblue = mng_get_uint16 (pRawdata2+4);
  1576. pBuf->iTRNScount = 0;
  1577. #if defined(MNG_NO_16BIT_SUPPORT)
  1578. if (pData->iPNGmult == 2)
  1579. {
  1580. pBuf->iTRNSred >>= 8;
  1581. pBuf->iTRNSgreen >>= 8;
  1582. pBuf->iTRNSblue >>= 8;
  1583. }
  1584. #endif
  1585. break;
  1586. }
  1587. case 3: { /* indexed */
  1588. pBuf->iTRNSgray = 0;
  1589. pBuf->iTRNSred = 0;
  1590. pBuf->iTRNSgreen = 0;
  1591. pBuf->iTRNSblue = 0;
  1592. pBuf->iTRNScount = iRawlen2;
  1593. MNG_COPY (pBuf->aTRNSentries, pRawdata2, iRawlen2);
  1594. break;
  1595. }
  1596. }
  1597. }
  1598. }
  1599. else /* store as global */
  1600. {
  1601. pData->iGlobalTRNSrawlen = iRawlen;
  1602. MNG_COPY (pData->aGlobalTRNSrawdata, pRawdata, iRawlen);
  1603. { /* create an animation object */
  1604. mng_retcode iRetcode = mng_create_ani_trns (pData, pData->iGlobalTRNSrawlen,
  1605. pData->aGlobalTRNSrawdata);
  1606. if (iRetcode) /* on error bail out */
  1607. return iRetcode;
  1608. }
  1609. }
  1610. #endif /* MNG_SUPPORT_DISPLAY */
  1611. #ifdef MNG_STORE_CHUNKS
  1612. if (pData->bStorechunks)
  1613. { /* initialize storage */
  1614. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  1615. if (iRetcode) /* on error bail out */
  1616. return iRetcode;
  1617. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1618. { /* not global! */
  1619. ((mng_trnsp)*ppChunk)->bGlobal = MNG_FALSE;
  1620. ((mng_trnsp)*ppChunk)->iType = pData->iColortype;
  1621. if (iRawlen == 0) /* if empty, indicate so */
  1622. ((mng_trnsp)*ppChunk)->bEmpty = MNG_TRUE;
  1623. else
  1624. {
  1625. ((mng_trnsp)*ppChunk)->bEmpty = MNG_FALSE;
  1626. switch (pData->iColortype) /* store fields */
  1627. {
  1628. case 0: { /* gray */
  1629. ((mng_trnsp)*ppChunk)->iGray = mng_get_uint16 (pRawdata);
  1630. break;
  1631. }
  1632. case 2: { /* rgb */
  1633. ((mng_trnsp)*ppChunk)->iRed = mng_get_uint16 (pRawdata);
  1634. ((mng_trnsp)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+2);
  1635. ((mng_trnsp)*ppChunk)->iBlue = mng_get_uint16 (pRawdata+4);
  1636. break;
  1637. }
  1638. case 3: { /* indexed */
  1639. ((mng_trnsp)*ppChunk)->iCount = iRawlen;
  1640. MNG_COPY (((mng_trnsp)*ppChunk)->aEntries, pRawdata, iRawlen);
  1641. break;
  1642. }
  1643. }
  1644. }
  1645. }
  1646. else /* it's global! */
  1647. {
  1648. ((mng_trnsp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  1649. ((mng_trnsp)*ppChunk)->bGlobal = MNG_TRUE;
  1650. ((mng_trnsp)*ppChunk)->iType = 0;
  1651. ((mng_trnsp)*ppChunk)->iRawlen = iRawlen;
  1652. MNG_COPY (((mng_trnsp)*ppChunk)->aRawdata, pRawdata, iRawlen);
  1653. }
  1654. }
  1655. #endif /* MNG_STORE_CHUNKS */
  1656. #ifdef MNG_SUPPORT_TRACE
  1657. MNG_TRACE (pData, MNG_FN_READ_TRNS, MNG_LC_END);
  1658. #endif
  1659. return MNG_NOERROR; /* done */
  1660. }
  1661. #endif
  1662. /* ************************************************************************** */
  1663. #ifndef MNG_OPTIMIZE_CHUNKREADER
  1664. READ_CHUNK (mng_read_gama)
  1665. {
  1666. #ifdef MNG_SUPPORT_TRACE
  1667. MNG_TRACE (pData, MNG_FN_READ_GAMA, MNG_LC_START);
  1668. #endif
  1669. /* sequence checks */
  1670. #ifdef MNG_INCLUDE_JNG
  1671. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  1672. (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  1673. #else
  1674. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  1675. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  1676. #endif
  1677. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  1678. #ifdef MNG_INCLUDE_JNG
  1679. if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
  1680. #else
  1681. if ((pData->bHasIDAT) || (pData->bHasPLTE))
  1682. #endif
  1683. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  1684. #ifdef MNG_INCLUDE_JNG
  1685. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  1686. #else
  1687. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1688. #endif
  1689. { /* length must be exactly 4 */
  1690. if (iRawlen != 4)
  1691. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  1692. }
  1693. else
  1694. { /* length must be empty or exactly 4 */
  1695. if ((iRawlen != 0) && (iRawlen != 4))
  1696. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  1697. }
  1698. #ifdef MNG_INCLUDE_JNG
  1699. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  1700. #else
  1701. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1702. #endif
  1703. pData->bHasGAMA = MNG_TRUE; /* indicate we've got it */
  1704. else
  1705. pData->bHasglobalGAMA = (mng_bool)(iRawlen != 0);
  1706. #ifdef MNG_SUPPORT_DISPLAY
  1707. #ifdef MNG_INCLUDE_JNG
  1708. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  1709. #else
  1710. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1711. #endif
  1712. {
  1713. mng_imagep pImage;
  1714. #ifndef MNG_NO_DELTA_PNG
  1715. if (pData->bHasDHDR) /* update delta image ? */
  1716. { /* store in object 0 ! */
  1717. pImage = (mng_imagep)pData->pObjzero;
  1718. /* store for color-processing routines */
  1719. pImage->pImgbuf->iGamma = mng_get_uint32 (pRawdata);
  1720. pImage->pImgbuf->bHasGAMA = MNG_TRUE;
  1721. }
  1722. else
  1723. #endif
  1724. {
  1725. pImage = (mng_imagep)pData->pCurrentobj;
  1726. if (!pImage) /* no object then dump it in obj 0 */
  1727. pImage = (mng_imagep)pData->pObjzero;
  1728. /* store for color-processing routines */
  1729. pImage->pImgbuf->iGamma = mng_get_uint32 (pRawdata);
  1730. pImage->pImgbuf->bHasGAMA = MNG_TRUE;
  1731. }
  1732. }
  1733. else
  1734. { /* store as global */
  1735. if (iRawlen != 0)
  1736. pData->iGlobalGamma = mng_get_uint32 (pRawdata);
  1737. { /* create an animation object */
  1738. mng_retcode iRetcode = mng_create_ani_gama (pData, (mng_bool)(iRawlen == 0),
  1739. pData->iGlobalGamma);
  1740. if (iRetcode) /* on error bail out */
  1741. return iRetcode;
  1742. }
  1743. }
  1744. #endif /* MNG_SUPPORT_DISPLAY */
  1745. #ifdef MNG_STORE_CHUNKS
  1746. if (pData->bStorechunks)
  1747. { /* initialize storage */
  1748. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  1749. if (iRetcode) /* on error bail out */
  1750. return iRetcode;
  1751. /* store the fields */
  1752. ((mng_gamap)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  1753. if (iRawlen)
  1754. ((mng_gamap)*ppChunk)->iGamma = mng_get_uint32 (pRawdata);
  1755. }
  1756. #endif /* MNG_STORE_CHUNKS */
  1757. #ifdef MNG_SUPPORT_TRACE
  1758. MNG_TRACE (pData, MNG_FN_READ_GAMA, MNG_LC_END);
  1759. #endif
  1760. return MNG_NOERROR; /* done */
  1761. }
  1762. #endif
  1763. /* ************************************************************************** */
  1764. #ifndef MNG_OPTIMIZE_CHUNKREADER
  1765. #ifndef MNG_SKIPCHUNK_cHRM
  1766. READ_CHUNK (mng_read_chrm)
  1767. {
  1768. #ifdef MNG_SUPPORT_TRACE
  1769. MNG_TRACE (pData, MNG_FN_READ_CHRM, MNG_LC_START);
  1770. #endif
  1771. /* sequence checks */
  1772. #ifdef MNG_INCLUDE_JNG
  1773. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  1774. (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  1775. #else
  1776. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  1777. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  1778. #endif
  1779. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  1780. #ifdef MNG_INCLUDE_JNG
  1781. if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
  1782. #else
  1783. if ((pData->bHasIDAT) || (pData->bHasPLTE))
  1784. #endif
  1785. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  1786. #ifdef MNG_INCLUDE_JNG
  1787. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  1788. #else
  1789. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1790. #endif
  1791. { /* length must be exactly 32 */
  1792. if (iRawlen != 32)
  1793. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  1794. }
  1795. else
  1796. { /* length must be empty or exactly 32 */
  1797. if ((iRawlen != 0) && (iRawlen != 32))
  1798. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  1799. }
  1800. #ifdef MNG_INCLUDE_JNG
  1801. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  1802. #else
  1803. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1804. #endif
  1805. pData->bHasCHRM = MNG_TRUE; /* indicate we've got it */
  1806. else
  1807. pData->bHasglobalCHRM = (mng_bool)(iRawlen != 0);
  1808. #ifdef MNG_SUPPORT_DISPLAY
  1809. {
  1810. mng_uint32 iWhitepointx, iWhitepointy;
  1811. mng_uint32 iPrimaryredx, iPrimaryredy;
  1812. mng_uint32 iPrimarygreenx, iPrimarygreeny;
  1813. mng_uint32 iPrimarybluex, iPrimarybluey;
  1814. iWhitepointx = mng_get_uint32 (pRawdata);
  1815. iWhitepointy = mng_get_uint32 (pRawdata+4);
  1816. iPrimaryredx = mng_get_uint32 (pRawdata+8);
  1817. iPrimaryredy = mng_get_uint32 (pRawdata+12);
  1818. iPrimarygreenx = mng_get_uint32 (pRawdata+16);
  1819. iPrimarygreeny = mng_get_uint32 (pRawdata+20);
  1820. iPrimarybluex = mng_get_uint32 (pRawdata+24);
  1821. iPrimarybluey = mng_get_uint32 (pRawdata+28);
  1822. #ifdef MNG_INCLUDE_JNG
  1823. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  1824. #else
  1825. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1826. #endif
  1827. {
  1828. mng_imagep pImage;
  1829. mng_imagedatap pBuf;
  1830. #ifndef MNG_NO_DELTA_PNG
  1831. if (pData->bHasDHDR) /* update delta image ? */
  1832. { /* store it in object 0 ! */
  1833. pImage = (mng_imagep)pData->pObjzero;
  1834. pBuf = pImage->pImgbuf; /* address object buffer */
  1835. pBuf->bHasCHRM = MNG_TRUE; /* and tell it it's got a CHRM now */
  1836. /* store for color-processing routines */
  1837. pBuf->iWhitepointx = iWhitepointx;
  1838. pBuf->iWhitepointy = iWhitepointy;
  1839. pBuf->iPrimaryredx = iPrimaryredx;
  1840. pBuf->iPrimaryredy = iPrimaryredy;
  1841. pBuf->iPrimarygreenx = iPrimarygreenx;
  1842. pBuf->iPrimarygreeny = iPrimarygreeny;
  1843. pBuf->iPrimarybluex = iPrimarybluex;
  1844. pBuf->iPrimarybluey = iPrimarybluey;
  1845. }
  1846. else
  1847. #endif
  1848. {
  1849. pImage = (mng_imagep)pData->pCurrentobj;
  1850. if (!pImage) /* no object then dump it in obj 0 */
  1851. pImage = (mng_imagep)pData->pObjzero;
  1852. pBuf = pImage->pImgbuf; /* address object buffer */
  1853. pBuf->bHasCHRM = MNG_TRUE; /* and tell it it's got a CHRM now */
  1854. /* store for color-processing routines */
  1855. pBuf->iWhitepointx = iWhitepointx;
  1856. pBuf->iWhitepointy = iWhitepointy;
  1857. pBuf->iPrimaryredx = iPrimaryredx;
  1858. pBuf->iPrimaryredy = iPrimaryredy;
  1859. pBuf->iPrimarygreenx = iPrimarygreenx;
  1860. pBuf->iPrimarygreeny = iPrimarygreeny;
  1861. pBuf->iPrimarybluex = iPrimarybluex;
  1862. pBuf->iPrimarybluey = iPrimarybluey;
  1863. }
  1864. }
  1865. else
  1866. { /* store as global */
  1867. if (iRawlen != 0)
  1868. {
  1869. pData->iGlobalWhitepointx = iWhitepointx;
  1870. pData->iGlobalWhitepointy = iWhitepointy;
  1871. pData->iGlobalPrimaryredx = iPrimaryredx;
  1872. pData->iGlobalPrimaryredy = iPrimaryredy;
  1873. pData->iGlobalPrimarygreenx = iPrimarygreenx;
  1874. pData->iGlobalPrimarygreeny = iPrimarygreeny;
  1875. pData->iGlobalPrimarybluex = iPrimarybluex;
  1876. pData->iGlobalPrimarybluey = iPrimarybluey;
  1877. }
  1878. { /* create an animation object */
  1879. mng_retcode iRetcode = mng_create_ani_chrm (pData, (mng_bool)(iRawlen == 0),
  1880. iWhitepointx, iWhitepointy,
  1881. iPrimaryredx, iPrimaryredy,
  1882. iPrimarygreenx, iPrimarygreeny,
  1883. iPrimarybluex, iPrimarybluey);
  1884. if (iRetcode) /* on error bail out */
  1885. return iRetcode;
  1886. }
  1887. }
  1888. }
  1889. #endif /* MNG_SUPPORT_DISPLAY */
  1890. #ifdef MNG_STORE_CHUNKS
  1891. if (pData->bStorechunks)
  1892. { /* initialize storage */
  1893. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  1894. if (iRetcode) /* on error bail out */
  1895. return iRetcode;
  1896. /* store the fields */
  1897. ((mng_chrmp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  1898. if (iRawlen)
  1899. {
  1900. ((mng_chrmp)*ppChunk)->iWhitepointx = mng_get_uint32 (pRawdata);
  1901. ((mng_chrmp)*ppChunk)->iWhitepointy = mng_get_uint32 (pRawdata+4);
  1902. ((mng_chrmp)*ppChunk)->iRedx = mng_get_uint32 (pRawdata+8);
  1903. ((mng_chrmp)*ppChunk)->iRedy = mng_get_uint32 (pRawdata+12);
  1904. ((mng_chrmp)*ppChunk)->iGreenx = mng_get_uint32 (pRawdata+16);
  1905. ((mng_chrmp)*ppChunk)->iGreeny = mng_get_uint32 (pRawdata+20);
  1906. ((mng_chrmp)*ppChunk)->iBluex = mng_get_uint32 (pRawdata+24);
  1907. ((mng_chrmp)*ppChunk)->iBluey = mng_get_uint32 (pRawdata+28);
  1908. }
  1909. }
  1910. #endif /* MNG_STORE_CHUNKS */
  1911. #ifdef MNG_SUPPORT_TRACE
  1912. MNG_TRACE (pData, MNG_FN_READ_CHRM, MNG_LC_END);
  1913. #endif
  1914. return MNG_NOERROR; /* done */
  1915. }
  1916. #endif
  1917. #endif
  1918. /* ************************************************************************** */
  1919. #ifndef MNG_OPTIMIZE_CHUNKREADER
  1920. READ_CHUNK (mng_read_srgb)
  1921. {
  1922. #ifdef MNG_SUPPORT_TRACE
  1923. MNG_TRACE (pData, MNG_FN_READ_SRGB, MNG_LC_START);
  1924. #endif
  1925. /* sequence checks */
  1926. #ifdef MNG_INCLUDE_JNG
  1927. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  1928. (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  1929. #else
  1930. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  1931. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  1932. #endif
  1933. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  1934. #ifdef MNG_INCLUDE_JNG
  1935. if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
  1936. #else
  1937. if ((pData->bHasIDAT) || (pData->bHasPLTE))
  1938. #endif
  1939. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  1940. #ifdef MNG_INCLUDE_JNG
  1941. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  1942. #else
  1943. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1944. #endif
  1945. { /* length must be exactly 1 */
  1946. if (iRawlen != 1)
  1947. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  1948. }
  1949. else
  1950. { /* length must be empty or exactly 1 */
  1951. if ((iRawlen != 0) && (iRawlen != 1))
  1952. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  1953. }
  1954. #ifdef MNG_INCLUDE_JNG
  1955. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  1956. #else
  1957. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1958. #endif
  1959. pData->bHasSRGB = MNG_TRUE; /* indicate we've got it */
  1960. else
  1961. pData->bHasglobalSRGB = (mng_bool)(iRawlen != 0);
  1962. #ifdef MNG_SUPPORT_DISPLAY
  1963. #ifdef MNG_INCLUDE_JNG
  1964. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  1965. #else
  1966. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  1967. #endif
  1968. {
  1969. mng_imagep pImage;
  1970. #ifndef MNG_NO_DELTA_PNG
  1971. if (pData->bHasDHDR) /* update delta image ? */
  1972. { /* store in object 0 ! */
  1973. pImage = (mng_imagep)pData->pObjzero;
  1974. /* store for color-processing routines */
  1975. pImage->pImgbuf->iRenderingintent = *pRawdata;
  1976. pImage->pImgbuf->bHasSRGB = MNG_TRUE;
  1977. }
  1978. else
  1979. #endif
  1980. {
  1981. pImage = (mng_imagep)pData->pCurrentobj;
  1982. if (!pImage) /* no object then dump it in obj 0 */
  1983. pImage = (mng_imagep)pData->pObjzero;
  1984. /* store for color-processing routines */
  1985. pImage->pImgbuf->iRenderingintent = *pRawdata;
  1986. pImage->pImgbuf->bHasSRGB = MNG_TRUE;
  1987. }
  1988. }
  1989. else
  1990. { /* store as global */
  1991. if (iRawlen != 0)
  1992. pData->iGlobalRendintent = *pRawdata;
  1993. { /* create an animation object */
  1994. mng_retcode iRetcode = mng_create_ani_srgb (pData, (mng_bool)(iRawlen == 0),
  1995. pData->iGlobalRendintent);
  1996. if (iRetcode) /* on error bail out */
  1997. return iRetcode;
  1998. }
  1999. }
  2000. #endif /* MNG_SUPPORT_DISPLAY */
  2001. #ifdef MNG_STORE_CHUNKS
  2002. if (pData->bStorechunks)
  2003. { /* initialize storage */
  2004. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  2005. if (iRetcode) /* on error bail out */
  2006. return iRetcode;
  2007. /* store the fields */
  2008. ((mng_srgbp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  2009. if (iRawlen)
  2010. ((mng_srgbp)*ppChunk)->iRenderingintent = *pRawdata;
  2011. }
  2012. #endif /* MNG_STORE_CHUNKS */
  2013. #ifdef MNG_SUPPORT_TRACE
  2014. MNG_TRACE (pData, MNG_FN_READ_SRGB, MNG_LC_END);
  2015. #endif
  2016. return MNG_NOERROR; /* done */
  2017. }
  2018. #endif
  2019. /* ************************************************************************** */
  2020. #ifndef MNG_OPTIMIZE_CHUNKREADER
  2021. #ifndef MNG_SKIPCHUNK_iCCP
  2022. READ_CHUNK (mng_read_iccp)
  2023. {
  2024. mng_retcode iRetcode;
  2025. mng_uint8p pTemp;
  2026. mng_uint32 iCompressedsize;
  2027. mng_uint32 iProfilesize;
  2028. mng_uint32 iBufsize = 0;
  2029. mng_uint8p pBuf = 0;
  2030. #ifdef MNG_SUPPORT_TRACE
  2031. MNG_TRACE (pData, MNG_FN_READ_ICCP, MNG_LC_START);
  2032. #endif
  2033. /* sequence checks */
  2034. #ifdef MNG_INCLUDE_JNG
  2035. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2036. (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  2037. #else
  2038. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2039. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  2040. #endif
  2041. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  2042. #ifdef MNG_INCLUDE_JNG
  2043. if ((pData->bHasIDAT) || (pData->bHasPLTE) || (pData->bHasJDAT) || (pData->bHasJDAA))
  2044. #else
  2045. if ((pData->bHasIDAT) || (pData->bHasPLTE))
  2046. #endif
  2047. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  2048. #ifdef MNG_INCLUDE_JNG
  2049. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  2050. #else
  2051. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  2052. #endif
  2053. { /* length must be at least 2 */
  2054. if (iRawlen < 2)
  2055. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2056. }
  2057. else
  2058. { /* length must be empty or at least 2 */
  2059. if ((iRawlen != 0) && (iRawlen < 2))
  2060. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2061. }
  2062. pTemp = find_null (pRawdata); /* find null-separator */
  2063. /* not found inside input-data ? */
  2064. if ((pTemp - pRawdata) > (mng_int32)iRawlen)
  2065. MNG_ERROR (pData, MNG_NULLNOTFOUND);
  2066. /* determine size of compressed profile */
  2067. iCompressedsize = (mng_uint32)(iRawlen - (pTemp - pRawdata) - 2);
  2068. /* decompress the profile */
  2069. iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize,
  2070. &pBuf, &iBufsize, &iProfilesize);
  2071. #ifdef MNG_CHECK_BAD_ICCP /* Check for bad iCCP chunk */
  2072. if ((iRetcode) && (!strncmp ((char *)pRawdata, "Photoshop ICC profile", 21)))
  2073. {
  2074. if (iRawlen == 2615) /* is it the sRGB profile ? */
  2075. {
  2076. mng_chunk_header chunk_srgb =
  2077. #ifdef MNG_OPTIMIZE_CHUNKINITFREE
  2078. {MNG_UINT_sRGB, mng_init_general, mng_free_general, mng_read_srgb, mng_write_srgb, mng_assign_general, 0, 0, sizeof(mng_srgb)};
  2079. #else
  2080. {MNG_UINT_sRGB, mng_init_srgb, mng_free_srgb, mng_read_srgb, mng_write_srgb, mng_assign_srgb, 0, 0};
  2081. #endif
  2082. /* pretend it's an sRGB chunk then ! */
  2083. iRetcode = mng_read_srgb (pData, &chunk_srgb, 1, (mng_ptr)"0", ppChunk);
  2084. if (iRetcode) /* on error bail out */
  2085. { /* don't forget to drop the temp buffer */
  2086. MNG_FREEX (pData, pBuf, iBufsize);
  2087. return iRetcode;
  2088. }
  2089. }
  2090. }
  2091. else
  2092. {
  2093. #endif /* MNG_CHECK_BAD_ICCP */
  2094. if (iRetcode) /* on error bail out */
  2095. { /* don't forget to drop the temp buffer */
  2096. MNG_FREEX (pData, pBuf, iBufsize);
  2097. return iRetcode;
  2098. }
  2099. #ifdef MNG_INCLUDE_JNG
  2100. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  2101. #else
  2102. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  2103. #endif
  2104. pData->bHasICCP = MNG_TRUE; /* indicate we've got it */
  2105. else
  2106. pData->bHasglobalICCP = (mng_bool)(iRawlen != 0);
  2107. #ifdef MNG_SUPPORT_DISPLAY
  2108. #ifdef MNG_INCLUDE_JNG
  2109. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  2110. #else
  2111. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  2112. #endif
  2113. {
  2114. mng_imagep pImage;
  2115. #ifndef MNG_NO_DELTA_PNG
  2116. if (pData->bHasDHDR) /* update delta image ? */
  2117. { /* store in object 0 ! */
  2118. pImage = (mng_imagep)pData->pObjzero;
  2119. if (pImage->pImgbuf->pProfile) /* profile existed ? */
  2120. MNG_FREEX (pData, pImage->pImgbuf->pProfile, pImage->pImgbuf->iProfilesize);
  2121. /* allocate a buffer & copy it */
  2122. MNG_ALLOC (pData, pImage->pImgbuf->pProfile, iProfilesize);
  2123. MNG_COPY (pImage->pImgbuf->pProfile, pBuf, iProfilesize);
  2124. /* store its length as well */
  2125. pImage->pImgbuf->iProfilesize = iProfilesize;
  2126. pImage->pImgbuf->bHasICCP = MNG_TRUE;
  2127. }
  2128. else
  2129. #endif
  2130. {
  2131. pImage = (mng_imagep)pData->pCurrentobj;
  2132. if (!pImage) /* no object then dump it in obj 0 */
  2133. pImage = (mng_imagep)pData->pObjzero;
  2134. if (pImage->pImgbuf->pProfile) /* profile existed ? */
  2135. MNG_FREEX (pData, pImage->pImgbuf->pProfile, pImage->pImgbuf->iProfilesize);
  2136. /* allocate a buffer & copy it */
  2137. MNG_ALLOC (pData, pImage->pImgbuf->pProfile, iProfilesize);
  2138. MNG_COPY (pImage->pImgbuf->pProfile, pBuf, iProfilesize);
  2139. /* store its length as well */
  2140. pImage->pImgbuf->iProfilesize = iProfilesize;
  2141. pImage->pImgbuf->bHasICCP = MNG_TRUE;
  2142. }
  2143. }
  2144. else
  2145. { /* store as global */
  2146. if (iRawlen == 0) /* empty chunk ? */
  2147. {
  2148. if (pData->pGlobalProfile) /* did we have a global profile ? */
  2149. MNG_FREEX (pData, pData->pGlobalProfile, pData->iGlobalProfilesize);
  2150. pData->iGlobalProfilesize = 0; /* reset to null */
  2151. pData->pGlobalProfile = MNG_NULL;
  2152. }
  2153. else
  2154. { /* allocate a global buffer & copy it */
  2155. MNG_ALLOC (pData, pData->pGlobalProfile, iProfilesize);
  2156. MNG_COPY (pData->pGlobalProfile, pBuf, iProfilesize);
  2157. /* store its length as well */
  2158. pData->iGlobalProfilesize = iProfilesize;
  2159. }
  2160. /* create an animation object */
  2161. iRetcode = mng_create_ani_iccp (pData, (mng_bool)(iRawlen == 0),
  2162. pData->iGlobalProfilesize,
  2163. pData->pGlobalProfile);
  2164. if (iRetcode) /* on error bail out */
  2165. return iRetcode;
  2166. }
  2167. #endif /* MNG_SUPPORT_DISPLAY */
  2168. #ifdef MNG_STORE_CHUNKS
  2169. if (pData->bStorechunks)
  2170. { /* initialize storage */
  2171. iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  2172. if (iRetcode) /* on error bail out */
  2173. { /* don't forget to drop the temp buffer */
  2174. MNG_FREEX (pData, pBuf, iBufsize);
  2175. return iRetcode;
  2176. }
  2177. /* store the fields */
  2178. ((mng_iccpp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  2179. if (iRawlen) /* not empty ? */
  2180. {
  2181. if (!pBuf) /* hasn't been unpuzzled it yet ? */
  2182. { /* find null-separator */
  2183. pTemp = find_null (pRawdata);
  2184. /* not found inside input-data ? */
  2185. if ((pTemp - pRawdata) > (mng_int32)iRawlen)
  2186. MNG_ERROR (pData, MNG_NULLNOTFOUND);
  2187. /* determine size of compressed profile */
  2188. iCompressedsize = iRawlen - (pTemp - pRawdata) - 2;
  2189. /* decompress the profile */
  2190. iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize,
  2191. &pBuf, &iBufsize, &iProfilesize);
  2192. if (iRetcode) /* on error bail out */
  2193. { /* don't forget to drop the temp buffer */
  2194. MNG_FREEX (pData, pBuf, iBufsize);
  2195. return iRetcode;
  2196. }
  2197. }
  2198. ((mng_iccpp)*ppChunk)->iNamesize = (mng_uint32)(pTemp - pRawdata);
  2199. if (((mng_iccpp)*ppChunk)->iNamesize)
  2200. {
  2201. MNG_ALLOC (pData, ((mng_iccpp)*ppChunk)->zName,
  2202. ((mng_iccpp)*ppChunk)->iNamesize + 1);
  2203. MNG_COPY (((mng_iccpp)*ppChunk)->zName, pRawdata,
  2204. ((mng_iccpp)*ppChunk)->iNamesize);
  2205. }
  2206. ((mng_iccpp)*ppChunk)->iCompression = *(pTemp+1);
  2207. ((mng_iccpp)*ppChunk)->iProfilesize = iProfilesize;
  2208. MNG_ALLOC (pData, ((mng_iccpp)*ppChunk)->pProfile, iProfilesize);
  2209. MNG_COPY (((mng_iccpp)*ppChunk)->pProfile, pBuf, iProfilesize);
  2210. }
  2211. }
  2212. #endif /* MNG_STORE_CHUNKS */
  2213. if (pBuf) /* free the temporary buffer */
  2214. MNG_FREEX (pData, pBuf, iBufsize);
  2215. #ifdef MNG_CHECK_BAD_ICCP
  2216. }
  2217. #endif
  2218. #ifdef MNG_SUPPORT_TRACE
  2219. MNG_TRACE (pData, MNG_FN_READ_ICCP, MNG_LC_END);
  2220. #endif
  2221. return MNG_NOERROR; /* done */
  2222. }
  2223. #endif
  2224. #endif
  2225. /* ************************************************************************** */
  2226. #ifndef MNG_OPTIMIZE_CHUNKREADER
  2227. #ifndef MNG_SKIPCHUNK_tEXt
  2228. READ_CHUNK (mng_read_text)
  2229. {
  2230. mng_uint32 iKeywordlen, iTextlen;
  2231. mng_pchar zKeyword, zText;
  2232. mng_uint8p pTemp;
  2233. #ifdef MNG_SUPPORT_TRACE
  2234. MNG_TRACE (pData, MNG_FN_READ_TEXT, MNG_LC_START);
  2235. #endif
  2236. /* sequence checks */
  2237. #ifdef MNG_INCLUDE_JNG
  2238. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2239. (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  2240. #else
  2241. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2242. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  2243. #endif
  2244. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  2245. if (iRawlen < 2) /* length must be at least 2 */
  2246. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2247. pTemp = find_null (pRawdata); /* find the null separator */
  2248. /* not found inside input-data ? */
  2249. if ((pTemp - pRawdata) > (mng_int32)iRawlen)
  2250. MNG_ERROR (pData, MNG_NULLNOTFOUND);
  2251. if (pTemp == pRawdata) /* there must be at least 1 char for keyword */
  2252. MNG_ERROR (pData, MNG_KEYWORDNULL);
  2253. iKeywordlen = (mng_uint32)(pTemp - pRawdata);
  2254. iTextlen = iRawlen - iKeywordlen - 1;
  2255. if (pData->fProcesstext) /* inform the application ? */
  2256. {
  2257. mng_bool bOke;
  2258. MNG_ALLOC (pData, zKeyword, iKeywordlen + 1);
  2259. MNG_COPY (zKeyword, pRawdata, iKeywordlen);
  2260. MNG_ALLOCX (pData, zText, iTextlen + 1);
  2261. if (!zText) /* on error bail out */
  2262. {
  2263. MNG_FREEX (pData, zKeyword, iKeywordlen + 1);
  2264. MNG_ERROR (pData, MNG_OUTOFMEMORY);
  2265. }
  2266. if (iTextlen)
  2267. MNG_COPY (zText, pTemp+1, iTextlen);
  2268. bOke = pData->fProcesstext ((mng_handle)pData, MNG_TYPE_TEXT, zKeyword, zText, 0, 0);
  2269. MNG_FREEX (pData, zText, iTextlen + 1);
  2270. MNG_FREEX (pData, zKeyword, iKeywordlen + 1);
  2271. if (!bOke)
  2272. MNG_ERROR (pData, MNG_APPMISCERROR);
  2273. }
  2274. #ifdef MNG_STORE_CHUNKS
  2275. if (pData->bStorechunks)
  2276. { /* initialize storage */
  2277. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  2278. if (iRetcode) /* on error bail out */
  2279. return iRetcode;
  2280. /* store the fields */
  2281. ((mng_textp)*ppChunk)->iKeywordsize = iKeywordlen;
  2282. ((mng_textp)*ppChunk)->iTextsize = iTextlen;
  2283. if (iKeywordlen)
  2284. {
  2285. MNG_ALLOC (pData, ((mng_textp)*ppChunk)->zKeyword, iKeywordlen+1);
  2286. MNG_COPY (((mng_textp)*ppChunk)->zKeyword, pRawdata, iKeywordlen);
  2287. }
  2288. if (iTextlen)
  2289. {
  2290. MNG_ALLOC (pData, ((mng_textp)*ppChunk)->zText, iTextlen+1);
  2291. MNG_COPY (((mng_textp)*ppChunk)->zText, pTemp+1, iTextlen);
  2292. }
  2293. }
  2294. #endif /* MNG_STORE_CHUNKS */
  2295. #ifdef MNG_SUPPORT_TRACE
  2296. MNG_TRACE (pData, MNG_FN_READ_TEXT, MNG_LC_END);
  2297. #endif
  2298. return MNG_NOERROR; /* done */
  2299. }
  2300. #endif
  2301. #endif
  2302. /* ************************************************************************** */
  2303. #ifndef MNG_OPTIMIZE_CHUNKREADER
  2304. #ifndef MNG_SKIPCHUNK_zTXt
  2305. READ_CHUNK (mng_read_ztxt)
  2306. {
  2307. mng_retcode iRetcode;
  2308. mng_uint32 iKeywordlen, iTextlen;
  2309. mng_pchar zKeyword;
  2310. mng_uint8p pTemp;
  2311. mng_uint32 iCompressedsize;
  2312. mng_uint32 iBufsize;
  2313. mng_uint8p pBuf;
  2314. #ifdef MNG_SUPPORT_TRACE
  2315. MNG_TRACE (pData, MNG_FN_READ_ZTXT, MNG_LC_START);
  2316. #endif
  2317. /* sequence checks */
  2318. #ifdef MNG_INCLUDE_JNG
  2319. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2320. (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  2321. #else
  2322. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2323. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  2324. #endif
  2325. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  2326. if (iRawlen < 3) /* length must be at least 3 */
  2327. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2328. pTemp = find_null (pRawdata); /* find the null separator */
  2329. /* not found inside input-data ? */
  2330. if ((pTemp - pRawdata) > (mng_int32)iRawlen)
  2331. MNG_ERROR (pData, MNG_NULLNOTFOUND);
  2332. if (pTemp == pRawdata) /* there must be at least 1 char for keyword */
  2333. MNG_ERROR (pData, MNG_KEYWORDNULL);
  2334. if (*(pTemp+1) != 0) /* only deflate compression-method allowed */
  2335. MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
  2336. iKeywordlen = (mng_uint32)(pTemp - pRawdata);
  2337. iCompressedsize = (mng_uint32)(iRawlen - iKeywordlen - 2);
  2338. zKeyword = 0; /* there's no keyword buffer yet */
  2339. pBuf = 0; /* or a temporary buffer ! */
  2340. if (pData->fProcesstext) /* inform the application ? */
  2341. { /* decompress the text */
  2342. iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize,
  2343. &pBuf, &iBufsize, &iTextlen);
  2344. if (iRetcode) /* on error bail out */
  2345. { /* don't forget to drop the temp buffers */
  2346. MNG_FREEX (pData, pBuf, iBufsize);
  2347. return iRetcode;
  2348. }
  2349. MNG_ALLOCX (pData, zKeyword, iKeywordlen+1);
  2350. if (!zKeyword) /* on error bail out */
  2351. { /* don't forget to drop the temp buffers */
  2352. MNG_FREEX (pData, pBuf, iBufsize);
  2353. MNG_ERROR (pData, MNG_OUTOFMEMORY);
  2354. }
  2355. MNG_COPY (zKeyword, pRawdata, iKeywordlen);
  2356. if (!pData->fProcesstext ((mng_handle)pData, MNG_TYPE_ZTXT, zKeyword, (mng_pchar)pBuf, 0, 0))
  2357. { /* don't forget to drop the temp buffers */
  2358. MNG_FREEX (pData, pBuf, iBufsize);
  2359. MNG_FREEX (pData, zKeyword, iKeywordlen+1);
  2360. MNG_ERROR (pData, MNG_APPMISCERROR);
  2361. }
  2362. }
  2363. #ifdef MNG_STORE_CHUNKS
  2364. if (pData->bStorechunks)
  2365. { /* initialize storage */
  2366. iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  2367. if (iRetcode) /* on error bail out */
  2368. { /* don't forget to drop the temp buffers */
  2369. MNG_FREEX (pData, pBuf, iBufsize);
  2370. MNG_FREEX (pData, zKeyword, iKeywordlen+1);
  2371. return iRetcode;
  2372. }
  2373. /* store the fields */
  2374. ((mng_ztxtp)*ppChunk)->iKeywordsize = iKeywordlen;
  2375. ((mng_ztxtp)*ppChunk)->iCompression = *(pTemp+1);
  2376. if ((!pBuf) && (iCompressedsize)) /* did we not get a text-buffer yet ? */
  2377. { /* decompress the text */
  2378. iRetcode = mng_inflate_buffer (pData, pTemp+2, iCompressedsize,
  2379. &pBuf, &iBufsize, &iTextlen);
  2380. if (iRetcode) /* on error bail out */
  2381. { /* don't forget to drop the temp buffers */
  2382. MNG_FREEX (pData, pBuf, iBufsize);
  2383. MNG_FREEX (pData, zKeyword, iKeywordlen+1);
  2384. return iRetcode;
  2385. }
  2386. }
  2387. MNG_ALLOCX (pData, ((mng_ztxtp)*ppChunk)->zKeyword, iKeywordlen + 1);
  2388. /* on error bail out */
  2389. if (!((mng_ztxtp)*ppChunk)->zKeyword)
  2390. { /* don't forget to drop the temp buffers */
  2391. MNG_FREEX (pData, pBuf, iBufsize);
  2392. MNG_FREEX (pData, zKeyword, iKeywordlen+1);
  2393. MNG_ERROR (pData, MNG_OUTOFMEMORY);
  2394. }
  2395. MNG_COPY (((mng_ztxtp)*ppChunk)->zKeyword, pRawdata, iKeywordlen);
  2396. ((mng_ztxtp)*ppChunk)->iTextsize = iTextlen;
  2397. if (iCompressedsize)
  2398. {
  2399. MNG_ALLOCX (pData, ((mng_ztxtp)*ppChunk)->zText, iTextlen + 1);
  2400. /* on error bail out */
  2401. if (!((mng_ztxtp)*ppChunk)->zText)
  2402. { /* don't forget to drop the temp buffers */
  2403. MNG_FREEX (pData, pBuf, iBufsize);
  2404. MNG_FREEX (pData, zKeyword, iKeywordlen+1);
  2405. MNG_ERROR (pData, MNG_OUTOFMEMORY);
  2406. }
  2407. MNG_COPY (((mng_ztxtp)*ppChunk)->zText, pBuf, iTextlen);
  2408. }
  2409. }
  2410. #endif /* MNG_STORE_CHUNKS */
  2411. MNG_FREEX (pData, pBuf, iBufsize); /* free the temporary buffers */
  2412. MNG_FREEX (pData, zKeyword, iKeywordlen+1);
  2413. #ifdef MNG_SUPPORT_TRACE
  2414. MNG_TRACE (pData, MNG_FN_READ_ZTXT, MNG_LC_END);
  2415. #endif
  2416. return MNG_NOERROR; /* done */
  2417. }
  2418. #endif
  2419. #endif
  2420. /* ************************************************************************** */
  2421. #ifndef MNG_OPTIMIZE_CHUNKREADER
  2422. #ifndef MNG_SKIPCHUNK_iTXt
  2423. READ_CHUNK (mng_read_itxt)
  2424. {
  2425. mng_retcode iRetcode;
  2426. mng_uint32 iKeywordlen, iTextlen, iLanguagelen, iTranslationlen;
  2427. mng_pchar zKeyword, zLanguage, zTranslation;
  2428. mng_uint8p pNull1, pNull2, pNull3;
  2429. mng_uint32 iCompressedsize;
  2430. mng_uint8 iCompressionflag;
  2431. mng_uint32 iBufsize;
  2432. mng_uint8p pBuf;
  2433. #ifdef MNG_SUPPORT_TRACE
  2434. MNG_TRACE (pData, MNG_FN_READ_ITXT, MNG_LC_START);
  2435. #endif
  2436. /* sequence checks */
  2437. #ifdef MNG_INCLUDE_JNG
  2438. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2439. (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  2440. #else
  2441. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2442. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  2443. #endif
  2444. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  2445. if (iRawlen < 6) /* length must be at least 6 */
  2446. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2447. pNull1 = find_null (pRawdata); /* find the null separators */
  2448. pNull2 = find_null (pNull1+3);
  2449. pNull3 = find_null (pNull2+1);
  2450. /* not found inside input-data ? */
  2451. if (((pNull1 - pRawdata) > (mng_int32)iRawlen) ||
  2452. ((pNull2 - pRawdata) > (mng_int32)iRawlen) ||
  2453. ((pNull3 - pRawdata) > (mng_int32)iRawlen) )
  2454. MNG_ERROR (pData, MNG_NULLNOTFOUND);
  2455. if (pNull1 == pRawdata) /* there must be at least 1 char for keyword */
  2456. MNG_ERROR (pData, MNG_KEYWORDNULL);
  2457. /* compression or not ? */
  2458. if ((*(pNull1+1) != 0) && (*(pNull1+1) != 1))
  2459. MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
  2460. if (*(pNull1+2) != 0) /* only deflate compression-method allowed */
  2461. MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
  2462. iKeywordlen = (mng_uint32)(pNull1 - pRawdata);
  2463. iLanguagelen = (mng_uint32)(pNull2 - pNull1 - 3);
  2464. iTranslationlen = (mng_uint32)(pNull3 - pNull2 - 1);
  2465. iCompressedsize = (mng_uint32)(iRawlen - iKeywordlen - iLanguagelen - iTranslationlen - 5);
  2466. iCompressionflag = *(pNull1+1);
  2467. zKeyword = 0; /* no buffers acquired yet */
  2468. zLanguage = 0;
  2469. zTranslation = 0;
  2470. pBuf = 0;
  2471. iTextlen = 0;
  2472. if (pData->fProcesstext) /* inform the application ? */
  2473. {
  2474. if (iCompressionflag) /* decompress the text ? */
  2475. {
  2476. iRetcode = mng_inflate_buffer (pData, pNull3+1, iCompressedsize,
  2477. &pBuf, &iBufsize, &iTextlen);
  2478. if (iRetcode) /* on error bail out */
  2479. { /* don't forget to drop the temp buffer */
  2480. MNG_FREEX (pData, pBuf, iBufsize);
  2481. return iRetcode;
  2482. }
  2483. }
  2484. else
  2485. {
  2486. iTextlen = iCompressedsize;
  2487. iBufsize = iTextlen+1; /* plus 1 for terminator byte!!! */
  2488. MNG_ALLOC (pData, pBuf, iBufsize);
  2489. MNG_COPY (pBuf, pNull3+1, iTextlen);
  2490. }
  2491. MNG_ALLOCX (pData, zKeyword, iKeywordlen + 1);
  2492. MNG_ALLOCX (pData, zLanguage, iLanguagelen + 1);
  2493. MNG_ALLOCX (pData, zTranslation, iTranslationlen + 1);
  2494. /* on error bail out */
  2495. if ((!zKeyword) || (!zLanguage) || (!zTranslation))
  2496. { /* don't forget to drop the temp buffers */
  2497. MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
  2498. MNG_FREEX (pData, zLanguage, iLanguagelen + 1);
  2499. MNG_FREEX (pData, zKeyword, iKeywordlen + 1);
  2500. MNG_FREEX (pData, pBuf, iBufsize);
  2501. MNG_ERROR (pData, MNG_OUTOFMEMORY);
  2502. }
  2503. MNG_COPY (zKeyword, pRawdata, iKeywordlen);
  2504. MNG_COPY (zLanguage, pNull1+3, iLanguagelen);
  2505. MNG_COPY (zTranslation, pNull2+1, iTranslationlen);
  2506. if (!pData->fProcesstext ((mng_handle)pData, MNG_TYPE_ITXT, zKeyword, (mng_pchar)pBuf,
  2507. zLanguage, zTranslation))
  2508. { /* don't forget to drop the temp buffers */
  2509. MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
  2510. MNG_FREEX (pData, zLanguage, iLanguagelen + 1);
  2511. MNG_FREEX (pData, zKeyword, iKeywordlen + 1);
  2512. MNG_FREEX (pData, pBuf, iBufsize);
  2513. MNG_ERROR (pData, MNG_APPMISCERROR);
  2514. }
  2515. }
  2516. #ifdef MNG_STORE_CHUNKS
  2517. if (pData->bStorechunks)
  2518. { /* initialize storage */
  2519. iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  2520. if (iRetcode) /* on error bail out */
  2521. { /* don't forget to drop the temp buffers */
  2522. MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
  2523. MNG_FREEX (pData, zLanguage, iLanguagelen + 1);
  2524. MNG_FREEX (pData, zKeyword, iKeywordlen + 1);
  2525. MNG_FREEX (pData, pBuf, iBufsize);
  2526. return iRetcode;
  2527. }
  2528. /* store the fields */
  2529. ((mng_itxtp)*ppChunk)->iKeywordsize = iKeywordlen;
  2530. ((mng_itxtp)*ppChunk)->iLanguagesize = iLanguagelen;
  2531. ((mng_itxtp)*ppChunk)->iTranslationsize = iTranslationlen;
  2532. ((mng_itxtp)*ppChunk)->iCompressionflag = *(pNull1+1);
  2533. ((mng_itxtp)*ppChunk)->iCompressionmethod = *(pNull1+2);
  2534. if ((!pBuf) && (iCompressedsize)) /* did we not get a text-buffer yet ? */
  2535. {
  2536. if (iCompressionflag) /* decompress the text ? */
  2537. {
  2538. iRetcode = mng_inflate_buffer (pData, pNull3+1, iCompressedsize,
  2539. &pBuf, &iBufsize, &iTextlen);
  2540. if (iRetcode) /* on error bail out */
  2541. { /* don't forget to drop the temp buffers */
  2542. MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
  2543. MNG_FREEX (pData, zLanguage, iLanguagelen + 1);
  2544. MNG_FREEX (pData, zKeyword, iKeywordlen + 1);
  2545. MNG_FREEX (pData, pBuf, iBufsize);
  2546. return iRetcode;
  2547. }
  2548. }
  2549. else
  2550. {
  2551. iTextlen = iCompressedsize;
  2552. iBufsize = iTextlen+1; /* plus 1 for terminator byte!!! */
  2553. MNG_ALLOC (pData, pBuf, iBufsize);
  2554. MNG_COPY (pBuf, pNull3+1, iTextlen);
  2555. }
  2556. }
  2557. MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zKeyword, iKeywordlen + 1);
  2558. MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zLanguage, iLanguagelen + 1);
  2559. MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zTranslation, iTranslationlen + 1);
  2560. /* on error bail out */
  2561. if ((!((mng_itxtp)*ppChunk)->zKeyword ) ||
  2562. (!((mng_itxtp)*ppChunk)->zLanguage ) ||
  2563. (!((mng_itxtp)*ppChunk)->zTranslation) )
  2564. { /* don't forget to drop the temp buffers */
  2565. MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
  2566. MNG_FREEX (pData, zLanguage, iLanguagelen + 1);
  2567. MNG_FREEX (pData, zKeyword, iKeywordlen + 1);
  2568. MNG_FREEX (pData, pBuf, iBufsize);
  2569. MNG_ERROR (pData, MNG_OUTOFMEMORY);
  2570. }
  2571. MNG_COPY (((mng_itxtp)*ppChunk)->zKeyword, pRawdata, iKeywordlen);
  2572. MNG_COPY (((mng_itxtp)*ppChunk)->zLanguage, pNull1+3, iLanguagelen);
  2573. MNG_COPY (((mng_itxtp)*ppChunk)->zTranslation, pNull2+1, iTranslationlen);
  2574. ((mng_itxtp)*ppChunk)->iTextsize = iTextlen;
  2575. if (iTextlen)
  2576. {
  2577. MNG_ALLOCX (pData, ((mng_itxtp)*ppChunk)->zText, iTextlen + 1);
  2578. if (!((mng_itxtp)*ppChunk)->zText)
  2579. { /* don't forget to drop the temp buffers */
  2580. MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
  2581. MNG_FREEX (pData, zLanguage, iLanguagelen + 1);
  2582. MNG_FREEX (pData, zKeyword, iKeywordlen + 1);
  2583. MNG_FREEX (pData, pBuf, iBufsize);
  2584. MNG_ERROR (pData, MNG_OUTOFMEMORY);
  2585. }
  2586. MNG_COPY (((mng_itxtp)*ppChunk)->zText, pBuf, iTextlen);
  2587. }
  2588. }
  2589. #endif /* MNG_STORE_CHUNKS */
  2590. /* free the temporary buffers */
  2591. MNG_FREEX (pData, zTranslation, iTranslationlen + 1);
  2592. MNG_FREEX (pData, zLanguage, iLanguagelen + 1);
  2593. MNG_FREEX (pData, zKeyword, iKeywordlen + 1);
  2594. MNG_FREEX (pData, pBuf, iBufsize);
  2595. #ifdef MNG_SUPPORT_TRACE
  2596. MNG_TRACE (pData, MNG_FN_READ_ITXT, MNG_LC_END);
  2597. #endif
  2598. return MNG_NOERROR; /* done */
  2599. }
  2600. #endif
  2601. #endif
  2602. /* ************************************************************************** */
  2603. #ifndef MNG_OPTIMIZE_CHUNKREADER
  2604. #ifndef MNG_SKIPCHUNK_bKGD
  2605. READ_CHUNK (mng_read_bkgd)
  2606. {
  2607. #ifdef MNG_SUPPORT_DISPLAY
  2608. mng_imagep pImage = (mng_imagep)pData->pCurrentobj;
  2609. mng_imagedatap pBuf;
  2610. #endif
  2611. #ifdef MNG_SUPPORT_TRACE
  2612. MNG_TRACE (pData, MNG_FN_READ_BKGD, MNG_LC_START);
  2613. #endif
  2614. /* sequence checks */
  2615. #ifdef MNG_INCLUDE_JNG
  2616. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2617. (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  2618. #else
  2619. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2620. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  2621. #endif
  2622. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  2623. #ifdef MNG_INCLUDE_JNG
  2624. if ((pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA))
  2625. #else
  2626. if (pData->bHasIDAT)
  2627. #endif
  2628. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  2629. if (iRawlen > 6) /* it just can't be bigger than that! */
  2630. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2631. #ifdef MNG_INCLUDE_JNG /* length checks */
  2632. if (pData->bHasJHDR)
  2633. {
  2634. if (((pData->iJHDRcolortype == 8) || (pData->iJHDRcolortype == 12)) && (iRawlen != 2))
  2635. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2636. if (((pData->iJHDRcolortype == 10) || (pData->iJHDRcolortype == 14)) && (iRawlen != 6))
  2637. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2638. }
  2639. else
  2640. #endif /* MNG_INCLUDE_JNG */
  2641. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  2642. {
  2643. if (((pData->iColortype == 0) || (pData->iColortype == 4)) && (iRawlen != 2))
  2644. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2645. if (((pData->iColortype == 2) || (pData->iColortype == 6)) && (iRawlen != 6))
  2646. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2647. if ((pData->iColortype == 3) && (iRawlen != 1))
  2648. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2649. }
  2650. else
  2651. {
  2652. if (iRawlen != 6) /* global is always 16-bit RGB ! */
  2653. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2654. }
  2655. #ifdef MNG_INCLUDE_JNG
  2656. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  2657. #else
  2658. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  2659. #endif
  2660. pData->bHasBKGD = MNG_TRUE; /* indicate bKGD available */
  2661. else
  2662. pData->bHasglobalBKGD = (mng_bool)(iRawlen != 0);
  2663. #ifdef MNG_SUPPORT_DISPLAY
  2664. if (!pImage) /* if no object dump it in obj 0 */
  2665. pImage = (mng_imagep)pData->pObjzero;
  2666. pBuf = pImage->pImgbuf; /* address object buffer */
  2667. #ifdef MNG_INCLUDE_JNG
  2668. if (pData->bHasJHDR)
  2669. {
  2670. pBuf->bHasBKGD = MNG_TRUE; /* tell the object it's got bKGD now */
  2671. switch (pData->iJHDRcolortype) /* store fields for future reference */
  2672. {
  2673. case 8 : ; /* gray */
  2674. case 12 : { /* graya */
  2675. pBuf->iBKGDgray = mng_get_uint16 (pRawdata);
  2676. break;
  2677. }
  2678. case 10 : ; /* rgb */
  2679. case 14 : { /* rgba */
  2680. pBuf->iBKGDred = mng_get_uint16 (pRawdata);
  2681. pBuf->iBKGDgreen = mng_get_uint16 (pRawdata+2);
  2682. pBuf->iBKGDblue = mng_get_uint16 (pRawdata+4);
  2683. break;
  2684. }
  2685. }
  2686. }
  2687. else
  2688. #endif /* MNG_INCLUDE_JNG */
  2689. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  2690. {
  2691. pBuf->bHasBKGD = MNG_TRUE; /* tell the object it's got bKGD now */
  2692. switch (pData->iColortype) /* store fields for future reference */
  2693. {
  2694. case 0 : ; /* gray */
  2695. case 4 : { /* graya */
  2696. pBuf->iBKGDgray = mng_get_uint16 (pRawdata);
  2697. break;
  2698. }
  2699. case 2 : ; /* rgb */
  2700. case 6 : { /* rgba */
  2701. pBuf->iBKGDred = mng_get_uint16 (pRawdata);
  2702. pBuf->iBKGDgreen = mng_get_uint16 (pRawdata+2);
  2703. pBuf->iBKGDblue = mng_get_uint16 (pRawdata+4);
  2704. break;
  2705. }
  2706. case 3 : { /* indexed */
  2707. pBuf->iBKGDindex = *pRawdata;
  2708. break;
  2709. }
  2710. }
  2711. }
  2712. else /* store as global */
  2713. {
  2714. if (iRawlen)
  2715. {
  2716. pData->iGlobalBKGDred = mng_get_uint16 (pRawdata);
  2717. pData->iGlobalBKGDgreen = mng_get_uint16 (pRawdata+2);
  2718. pData->iGlobalBKGDblue = mng_get_uint16 (pRawdata+4);
  2719. }
  2720. { /* create an animation object */
  2721. mng_retcode iRetcode = mng_create_ani_bkgd (pData, pData->iGlobalBKGDred,
  2722. pData->iGlobalBKGDgreen,
  2723. pData->iGlobalBKGDblue);
  2724. if (iRetcode) /* on error bail out */
  2725. return iRetcode;
  2726. }
  2727. }
  2728. #endif /* MNG_SUPPORT_DISPLAY */
  2729. #ifdef MNG_STORE_CHUNKS
  2730. if (pData->bStorechunks)
  2731. { /* initialize storage */
  2732. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  2733. if (iRetcode) /* on error bail out */
  2734. return iRetcode;
  2735. /* store the fields */
  2736. ((mng_bkgdp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  2737. ((mng_bkgdp)*ppChunk)->iType = pData->iColortype;
  2738. if (iRawlen)
  2739. {
  2740. switch (iRawlen) /* guess from length */
  2741. {
  2742. case 1 : { /* indexed */
  2743. ((mng_bkgdp)*ppChunk)->iType = 3;
  2744. ((mng_bkgdp)*ppChunk)->iIndex = *pRawdata;
  2745. break;
  2746. }
  2747. case 2 : { /* gray */
  2748. ((mng_bkgdp)*ppChunk)->iType = 0;
  2749. ((mng_bkgdp)*ppChunk)->iGray = mng_get_uint16 (pRawdata);
  2750. break;
  2751. }
  2752. case 6 : { /* rgb */
  2753. ((mng_bkgdp)*ppChunk)->iType = 2;
  2754. ((mng_bkgdp)*ppChunk)->iRed = mng_get_uint16 (pRawdata);
  2755. ((mng_bkgdp)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+2);
  2756. ((mng_bkgdp)*ppChunk)->iBlue = mng_get_uint16 (pRawdata+4);
  2757. break;
  2758. }
  2759. }
  2760. }
  2761. }
  2762. #endif /* MNG_STORE_CHUNKS */
  2763. #ifdef MNG_SUPPORT_TRACE
  2764. MNG_TRACE (pData, MNG_FN_READ_BKGD, MNG_LC_END);
  2765. #endif
  2766. return MNG_NOERROR; /* done */
  2767. }
  2768. #endif
  2769. #endif
  2770. /* ************************************************************************** */
  2771. #ifndef MNG_OPTIMIZE_CHUNKREADER
  2772. #ifndef MNG_SKIPCHUNK_pHYs
  2773. READ_CHUNK (mng_read_phys)
  2774. {
  2775. #ifdef MNG_SUPPORT_TRACE
  2776. MNG_TRACE (pData, MNG_FN_READ_PHYS, MNG_LC_START);
  2777. #endif
  2778. /* sequence checks */
  2779. #ifdef MNG_INCLUDE_JNG
  2780. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2781. (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  2782. #else
  2783. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2784. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  2785. #endif
  2786. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  2787. #ifdef MNG_INCLUDE_JNG
  2788. if ((pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA))
  2789. #else
  2790. if (pData->bHasIDAT)
  2791. #endif
  2792. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  2793. /* it's 9 bytes or empty; no more, no less! */
  2794. if ((iRawlen != 9) && (iRawlen != 0))
  2795. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2796. #ifdef MNG_SUPPORT_DISPLAY
  2797. {
  2798. /* TODO: something !!! */
  2799. }
  2800. #endif /* MNG_SUPPORT_DISPLAY */
  2801. #ifdef MNG_STORE_CHUNKS
  2802. if (pData->bStorechunks)
  2803. { /* initialize storage */
  2804. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  2805. if (iRetcode) /* on error bail out */
  2806. return iRetcode;
  2807. /* store the fields */
  2808. ((mng_physp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  2809. if (iRawlen)
  2810. {
  2811. ((mng_physp)*ppChunk)->iSizex = mng_get_uint32 (pRawdata);
  2812. ((mng_physp)*ppChunk)->iSizey = mng_get_uint32 (pRawdata+4);
  2813. ((mng_physp)*ppChunk)->iUnit = *(pRawdata+8);
  2814. }
  2815. }
  2816. #endif /* MNG_STORE_CHUNKS */
  2817. #ifdef MNG_SUPPORT_TRACE
  2818. MNG_TRACE (pData, MNG_FN_READ_PHYS, MNG_LC_END);
  2819. #endif
  2820. return MNG_NOERROR; /* done */
  2821. }
  2822. #endif
  2823. #endif
  2824. /* ************************************************************************** */
  2825. #ifndef MNG_OPTIMIZE_CHUNKREADER
  2826. #ifndef MNG_SKIPCHUNK_sBIT
  2827. READ_CHUNK (mng_read_sbit)
  2828. {
  2829. #ifdef MNG_SUPPORT_TRACE
  2830. MNG_TRACE (pData, MNG_FN_READ_SBIT, MNG_LC_START);
  2831. #endif
  2832. /* sequence checks */
  2833. #ifdef MNG_INCLUDE_JNG
  2834. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2835. (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  2836. #else
  2837. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2838. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  2839. #endif
  2840. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  2841. #ifdef MNG_INCLUDE_JNG
  2842. if ((pData->bHasPLTE) || (pData->bHasIDAT) || (pData->bHasJDAT) || (pData->bHasJDAA))
  2843. #else
  2844. if ((pData->bHasPLTE) || (pData->bHasIDAT))
  2845. #endif
  2846. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  2847. if (iRawlen > 4) /* it just can't be bigger than that! */
  2848. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2849. #ifdef MNG_INCLUDE_JNG /* length checks */
  2850. if (pData->bHasJHDR)
  2851. {
  2852. if ((pData->iJHDRcolortype == 8) && (iRawlen != 1))
  2853. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2854. if ((pData->iJHDRcolortype == 10) && (iRawlen != 3))
  2855. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2856. if ((pData->iJHDRcolortype == 12) && (iRawlen != 2))
  2857. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2858. if ((pData->iJHDRcolortype == 14) && (iRawlen != 4))
  2859. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2860. }
  2861. else
  2862. #endif /* MNG_INCLUDE_JNG */
  2863. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  2864. {
  2865. if ((pData->iColortype == 0) && (iRawlen != 1))
  2866. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2867. if ((pData->iColortype == 2) && (iRawlen != 3))
  2868. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2869. if ((pData->iColortype == 3) && (iRawlen != 3))
  2870. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2871. if ((pData->iColortype == 4) && (iRawlen != 2))
  2872. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2873. if ((pData->iColortype == 6) && (iRawlen != 4))
  2874. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2875. }
  2876. else
  2877. { /* global = empty or RGBA */
  2878. if ((iRawlen != 0) && (iRawlen != 4))
  2879. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2880. }
  2881. #ifdef MNG_SUPPORT_DISPLAY
  2882. {
  2883. /* TODO: something !!! */
  2884. }
  2885. #endif /* MNG_SUPPORT_DISPLAY */
  2886. #ifdef MNG_STORE_CHUNKS
  2887. if (pData->bStorechunks)
  2888. { /* initialize storage */
  2889. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  2890. if (iRetcode) /* on error bail out */
  2891. return iRetcode;
  2892. /* store the fields */
  2893. ((mng_sbitp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  2894. if (iRawlen)
  2895. {
  2896. #ifdef MNG_INCLUDE_JNG
  2897. if (pData->bHasJHDR)
  2898. ((mng_sbitp)*ppChunk)->iType = pData->iJHDRcolortype;
  2899. else
  2900. #endif
  2901. if (pData->bHasIHDR)
  2902. ((mng_sbitp)*ppChunk)->iType = pData->iColortype;
  2903. else /* global ! */
  2904. ((mng_sbitp)*ppChunk)->iType = 6;
  2905. if (iRawlen > 0)
  2906. ((mng_sbitp)*ppChunk)->aBits [0] = *pRawdata;
  2907. if (iRawlen > 1)
  2908. ((mng_sbitp)*ppChunk)->aBits [1] = *(pRawdata+1);
  2909. if (iRawlen > 2)
  2910. ((mng_sbitp)*ppChunk)->aBits [2] = *(pRawdata+2);
  2911. if (iRawlen > 3)
  2912. ((mng_sbitp)*ppChunk)->aBits [3] = *(pRawdata+3);
  2913. }
  2914. }
  2915. #endif /* MNG_STORE_CHUNKS */
  2916. #ifdef MNG_SUPPORT_TRACE
  2917. MNG_TRACE (pData, MNG_FN_READ_SBIT, MNG_LC_END);
  2918. #endif
  2919. return MNG_NOERROR; /* done */
  2920. }
  2921. #endif
  2922. #endif
  2923. /* ************************************************************************** */
  2924. #ifndef MNG_OPTIMIZE_CHUNKREADER
  2925. #ifndef MNG_SKIPCHUNK_sPLT
  2926. READ_CHUNK (mng_read_splt)
  2927. {
  2928. mng_uint8p pTemp;
  2929. mng_uint32 iNamelen;
  2930. mng_uint8 iSampledepth;
  2931. mng_uint32 iRemain;
  2932. #ifdef MNG_SUPPORT_TRACE
  2933. MNG_TRACE (pData, MNG_FN_READ_SPLT, MNG_LC_START);
  2934. #endif
  2935. /* sequence checks */
  2936. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  2937. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  2938. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  2939. if (pData->bHasIDAT)
  2940. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  2941. if (iRawlen)
  2942. {
  2943. pTemp = find_null (pRawdata); /* find null-separator */
  2944. /* not found inside input-data ? */
  2945. if ((pTemp - pRawdata) > (mng_int32)iRawlen)
  2946. MNG_ERROR (pData, MNG_NULLNOTFOUND);
  2947. iNamelen = (mng_uint32)(pTemp - pRawdata);
  2948. iSampledepth = *(pTemp+1);
  2949. iRemain = (iRawlen - 2 - iNamelen);
  2950. if ((iSampledepth != 1) && (iSampledepth != 2))
  2951. MNG_ERROR (pData, MNG_INVSAMPLEDEPTH);
  2952. /* check remaining length */
  2953. if ( ((iSampledepth == 1) && (iRemain % 6 != 0)) ||
  2954. ((iSampledepth == 2) && (iRemain % 10 != 0)) )
  2955. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  2956. }
  2957. else
  2958. {
  2959. pTemp = MNG_NULL;
  2960. iNamelen = 0;
  2961. iSampledepth = 0;
  2962. iRemain = 0;
  2963. }
  2964. #ifdef MNG_SUPPORT_DISPLAY
  2965. {
  2966. /* TODO: something !!! */
  2967. }
  2968. #endif /* MNG_SUPPORT_DISPLAY */
  2969. #ifdef MNG_STORE_CHUNKS
  2970. if (pData->bStorechunks)
  2971. { /* initialize storage */
  2972. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  2973. if (iRetcode) /* on error bail out */
  2974. return iRetcode;
  2975. /* store the fields */
  2976. ((mng_spltp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  2977. if (iRawlen)
  2978. {
  2979. ((mng_spltp)*ppChunk)->iNamesize = iNamelen;
  2980. ((mng_spltp)*ppChunk)->iSampledepth = iSampledepth;
  2981. if (iSampledepth == 1)
  2982. ((mng_spltp)*ppChunk)->iEntrycount = iRemain / 6;
  2983. else
  2984. ((mng_spltp)*ppChunk)->iEntrycount = iRemain / 10;
  2985. if (iNamelen)
  2986. {
  2987. MNG_ALLOC (pData, ((mng_spltp)*ppChunk)->zName, iNamelen+1);
  2988. MNG_COPY (((mng_spltp)*ppChunk)->zName, pRawdata, iNamelen);
  2989. }
  2990. if (iRemain)
  2991. {
  2992. MNG_ALLOC (pData, ((mng_spltp)*ppChunk)->pEntries, iRemain);
  2993. MNG_COPY (((mng_spltp)*ppChunk)->pEntries, pTemp+2, iRemain);
  2994. }
  2995. }
  2996. }
  2997. #endif /* MNG_STORE_CHUNKS */
  2998. #ifdef MNG_SUPPORT_TRACE
  2999. MNG_TRACE (pData, MNG_FN_READ_SPLT, MNG_LC_END);
  3000. #endif
  3001. return MNG_NOERROR; /* done */
  3002. }
  3003. #endif
  3004. #endif
  3005. /* ************************************************************************** */
  3006. #ifndef MNG_OPTIMIZE_CHUNKREADER
  3007. #ifndef MNG_SKIPCHUNK_hIST
  3008. READ_CHUNK (mng_read_hist)
  3009. {
  3010. #ifdef MNG_SUPPORT_TRACE
  3011. MNG_TRACE (pData, MNG_FN_READ_HIST, MNG_LC_START);
  3012. #endif
  3013. /* sequence checks */
  3014. if ((!pData->bHasIHDR) && (!pData->bHasBASI) && (!pData->bHasDHDR) )
  3015. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3016. if ((!pData->bHasPLTE) || (pData->bHasIDAT))
  3017. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3018. /* length oke ? */
  3019. if ( ((iRawlen & 0x01) != 0) || ((iRawlen >> 1) != pData->iPLTEcount) )
  3020. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  3021. #ifdef MNG_SUPPORT_DISPLAY
  3022. {
  3023. /* TODO: something !!! */
  3024. }
  3025. #endif /* MNG_SUPPORT_DISPLAY */
  3026. #ifdef MNG_STORE_CHUNKS
  3027. if (pData->bStorechunks)
  3028. {
  3029. mng_uint32 iX;
  3030. /* initialize storage */
  3031. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  3032. if (iRetcode) /* on error bail out */
  3033. return iRetcode;
  3034. /* store the fields */
  3035. ((mng_histp)*ppChunk)->iEntrycount = iRawlen >> 1;
  3036. for (iX = 0; iX < (iRawlen >> 1); iX++)
  3037. {
  3038. ((mng_histp)*ppChunk)->aEntries [iX] = mng_get_uint16 (pRawdata);
  3039. pRawdata += 2;
  3040. }
  3041. }
  3042. #endif /* MNG_STORE_CHUNKS */
  3043. #ifdef MNG_SUPPORT_TRACE
  3044. MNG_TRACE (pData, MNG_FN_READ_HIST, MNG_LC_END);
  3045. #endif
  3046. return MNG_NOERROR; /* done */
  3047. }
  3048. #endif
  3049. #endif
  3050. /* ************************************************************************** */
  3051. #ifndef MNG_OPTIMIZE_CHUNKREADER
  3052. #ifndef MNG_SKIPCHUNK_tIME
  3053. READ_CHUNK (mng_read_time)
  3054. {
  3055. #ifdef MNG_SUPPORT_TRACE
  3056. MNG_TRACE (pData, MNG_FN_READ_TIME, MNG_LC_START);
  3057. #endif
  3058. /* sequence checks */
  3059. #ifdef MNG_INCLUDE_JNG
  3060. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  3061. (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  3062. #else
  3063. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  3064. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  3065. #endif
  3066. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3067. if (iRawlen != 7) /* length must be exactly 7 */
  3068. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  3069. /* if (pData->fProcesstime) */ /* inform the application ? */
  3070. /* {
  3071. pData->fProcesstime ((mng_handle)pData, );
  3072. } */
  3073. #ifdef MNG_STORE_CHUNKS
  3074. if (pData->bStorechunks)
  3075. { /* initialize storage */
  3076. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  3077. if (iRetcode) /* on error bail out */
  3078. return iRetcode;
  3079. /* store the fields */
  3080. ((mng_timep)*ppChunk)->iYear = mng_get_uint16 (pRawdata);
  3081. ((mng_timep)*ppChunk)->iMonth = *(pRawdata+2);
  3082. ((mng_timep)*ppChunk)->iDay = *(pRawdata+3);
  3083. ((mng_timep)*ppChunk)->iHour = *(pRawdata+4);
  3084. ((mng_timep)*ppChunk)->iMinute = *(pRawdata+5);
  3085. ((mng_timep)*ppChunk)->iSecond = *(pRawdata+6);
  3086. }
  3087. #endif /* MNG_STORE_CHUNKS */
  3088. #ifdef MNG_SUPPORT_TRACE
  3089. MNG_TRACE (pData, MNG_FN_READ_TIME, MNG_LC_END);
  3090. #endif
  3091. return MNG_NOERROR; /* done */
  3092. }
  3093. #endif
  3094. #endif
  3095. /* ************************************************************************** */
  3096. #ifndef MNG_OPTIMIZE_CHUNKREADER
  3097. READ_CHUNK (mng_read_mhdr)
  3098. {
  3099. #ifdef MNG_SUPPORT_TRACE
  3100. MNG_TRACE (pData, MNG_FN_READ_MHDR, MNG_LC_START);
  3101. #endif
  3102. if (pData->eSigtype != mng_it_mng) /* sequence checks */
  3103. MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
  3104. if (pData->bHasheader) /* can only be the first chunk! */
  3105. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3106. /* correct length ? */
  3107. #ifndef MNG_NO_OLD_VERSIONS
  3108. if ((iRawlen != 28) && (iRawlen != 12))
  3109. #else
  3110. if ((iRawlen != 28))
  3111. #endif
  3112. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  3113. pData->bHasMHDR = MNG_TRUE; /* oh boy, a real MNG */
  3114. pData->bHasheader = MNG_TRUE; /* we've got a header */
  3115. pData->eImagetype = mng_it_mng; /* fill header fields */
  3116. pData->iWidth = mng_get_uint32 (pRawdata);
  3117. pData->iHeight = mng_get_uint32 (pRawdata+4);
  3118. pData->iTicks = mng_get_uint32 (pRawdata+8);
  3119. #ifndef MNG_NO_OLD_VERSIONS
  3120. if (iRawlen == 28) /* proper MHDR ? */
  3121. {
  3122. #endif
  3123. pData->iLayercount = mng_get_uint32 (pRawdata+12);
  3124. pData->iFramecount = mng_get_uint32 (pRawdata+16);
  3125. pData->iPlaytime = mng_get_uint32 (pRawdata+20);
  3126. pData->iSimplicity = mng_get_uint32 (pRawdata+24);
  3127. #ifndef MNG_NO_OLD_VERSIONS
  3128. pData->bPreDraft48 = MNG_FALSE;
  3129. }
  3130. else /* probably pre-draft48 then */
  3131. {
  3132. pData->iLayercount = 0;
  3133. pData->iFramecount = 0;
  3134. pData->iPlaytime = 0;
  3135. pData->iSimplicity = 0;
  3136. pData->bPreDraft48 = MNG_TRUE;
  3137. }
  3138. #endif
  3139. /* predict alpha-depth */
  3140. if ((pData->iSimplicity & 0x00000001) == 0)
  3141. #ifndef MNG_NO_16BIT_SUPPORT
  3142. pData->iAlphadepth = 16; /* no indicators = assume the worst */
  3143. #else
  3144. pData->iAlphadepth = 8; /* anything else = assume the worst */
  3145. #endif
  3146. else
  3147. if ((pData->iSimplicity & 0x00000008) == 0)
  3148. pData->iAlphadepth = 0; /* no transparency at all */
  3149. else
  3150. if ((pData->iSimplicity & 0x00000140) == 0x00000040)
  3151. pData->iAlphadepth = 1; /* no semi-transparency guaranteed */
  3152. else
  3153. #ifndef MNG_NO_16BIT_SUPPORT
  3154. pData->iAlphadepth = 16; /* anything else = assume the worst */
  3155. #else
  3156. pData->iAlphadepth = 8; /* anything else = assume the worst */
  3157. #endif
  3158. #ifdef MNG_INCLUDE_JNG /* can we handle the complexity ? */
  3159. if (pData->iSimplicity & 0x0000FC00)
  3160. #else
  3161. if (pData->iSimplicity & 0x0000FC10)
  3162. #endif
  3163. MNG_ERROR (pData, MNG_MNGTOOCOMPLEX);
  3164. /* fits on maximum canvas ? */
  3165. if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
  3166. MNG_WARNING (pData, MNG_IMAGETOOLARGE);
  3167. if (pData->fProcessheader) /* inform the app ? */
  3168. if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
  3169. MNG_ERROR (pData, MNG_APPMISCERROR);
  3170. pData->iImagelevel++; /* one level deeper */
  3171. #ifdef MNG_STORE_CHUNKS
  3172. if (pData->bStorechunks)
  3173. { /* initialize storage */
  3174. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  3175. if (iRetcode) /* on error bail out */
  3176. return iRetcode;
  3177. /* store the fields */
  3178. ((mng_mhdrp)*ppChunk)->iWidth = pData->iWidth;
  3179. ((mng_mhdrp)*ppChunk)->iHeight = pData->iHeight;
  3180. ((mng_mhdrp)*ppChunk)->iTicks = pData->iTicks;
  3181. ((mng_mhdrp)*ppChunk)->iLayercount = pData->iLayercount;
  3182. ((mng_mhdrp)*ppChunk)->iFramecount = pData->iFramecount;
  3183. ((mng_mhdrp)*ppChunk)->iPlaytime = pData->iPlaytime;
  3184. ((mng_mhdrp)*ppChunk)->iSimplicity = pData->iSimplicity;
  3185. }
  3186. #endif /* MNG_STORE_CHUNKS */
  3187. #ifdef MNG_SUPPORT_TRACE
  3188. MNG_TRACE (pData, MNG_FN_READ_MHDR, MNG_LC_END);
  3189. #endif
  3190. return MNG_NOERROR; /* done */
  3191. }
  3192. #endif
  3193. /* ************************************************************************** */
  3194. #ifndef MNG_OPTIMIZE_CHUNKREADER
  3195. READ_CHUNK (mng_read_mend)
  3196. {
  3197. #ifdef MNG_SUPPORT_TRACE
  3198. MNG_TRACE (pData, MNG_FN_READ_MEND, MNG_LC_START);
  3199. #endif
  3200. if (!pData->bHasMHDR) /* sequence checks */
  3201. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3202. if (iRawlen > 0) /* must not contain data! */
  3203. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  3204. #ifdef MNG_SUPPORT_DISPLAY
  3205. { /* do something */
  3206. mng_retcode iRetcode = mng_process_display_mend (pData);
  3207. if (iRetcode) /* on error bail out */
  3208. return iRetcode;
  3209. if (!pData->iTotalframes) /* save totals */
  3210. pData->iTotalframes = pData->iFrameseq;
  3211. if (!pData->iTotallayers)
  3212. pData->iTotallayers = pData->iLayerseq;
  3213. if (!pData->iTotalplaytime)
  3214. pData->iTotalplaytime = pData->iFrametime;
  3215. }
  3216. #endif /* MNG_SUPPORT_DISPLAY */
  3217. pData->bHasMHDR = MNG_FALSE; /* end of the line, bro! */
  3218. #ifdef MNG_STORE_CHUNKS
  3219. if (pData->bStorechunks)
  3220. { /* initialize storage */
  3221. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  3222. if (iRetcode) /* on error bail out */
  3223. return iRetcode;
  3224. }
  3225. #endif /* MNG_STORE_CHUNKS */
  3226. #ifdef MNG_SUPPORT_TRACE
  3227. MNG_TRACE (pData, MNG_FN_READ_MEND, MNG_LC_END);
  3228. #endif
  3229. return MNG_NOERROR; /* done */
  3230. }
  3231. #endif
  3232. /* ************************************************************************** */
  3233. #ifndef MNG_OPTIMIZE_CHUNKREADER
  3234. #ifndef MNG_SKIPCHUNK_LOOP
  3235. READ_CHUNK (mng_read_loop)
  3236. {
  3237. #ifdef MNG_SUPPORT_TRACE
  3238. MNG_TRACE (pData, MNG_FN_READ_LOOP, MNG_LC_START);
  3239. #endif
  3240. if (!pData->bHasMHDR) /* sequence checks */
  3241. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3242. if (!pData->bCacheplayback) /* must store playback info to work!! */
  3243. MNG_ERROR (pData, MNG_LOOPWITHCACHEOFF);
  3244. #ifdef MNG_INCLUDE_JNG
  3245. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  3246. #else
  3247. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  3248. #endif
  3249. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3250. if (iRawlen >= 5) /* length checks */
  3251. {
  3252. if (iRawlen >= 6)
  3253. {
  3254. if ((iRawlen - 6) % 4 != 0)
  3255. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  3256. }
  3257. }
  3258. else
  3259. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  3260. #ifdef MNG_SUPPORT_DISPLAY
  3261. {
  3262. mng_uint8 iLevel;
  3263. mng_uint32 iRepeat;
  3264. mng_uint8 iTermination = 0;
  3265. mng_uint32 iItermin = 1;
  3266. mng_uint32 iItermax = 0x7fffffffL;
  3267. mng_retcode iRetcode;
  3268. pData->bHasLOOP = MNG_TRUE; /* indicate we're inside a loop */
  3269. iLevel = *pRawdata; /* determine the fields for processing */
  3270. #ifndef MNG_NO_OLD_VERSIONS
  3271. if (pData->bPreDraft48)
  3272. {
  3273. iTermination = *(pRawdata+1);
  3274. iRepeat = mng_get_uint32 (pRawdata+2);
  3275. }
  3276. else
  3277. #endif
  3278. iRepeat = mng_get_uint32 (pRawdata+1);
  3279. if (iRawlen >= 6)
  3280. {
  3281. #ifndef MNG_NO_OLD_VERSIONS
  3282. if (!pData->bPreDraft48)
  3283. #endif
  3284. iTermination = *(pRawdata+5);
  3285. if (iRawlen >= 10)
  3286. {
  3287. iItermin = mng_get_uint32 (pRawdata+6);
  3288. if (iRawlen >= 14)
  3289. {
  3290. iItermax = mng_get_uint32 (pRawdata+10);
  3291. /* TODO: process signals */
  3292. }
  3293. }
  3294. }
  3295. /* create the LOOP ani-object */
  3296. iRetcode = mng_create_ani_loop (pData, iLevel, iRepeat, iTermination,
  3297. iItermin, iItermax, 0, 0);
  3298. if (iRetcode) /* on error bail out */
  3299. return iRetcode;
  3300. /* skip till matching ENDL if iteration=0 */
  3301. if ((!pData->bSkipping) && (iRepeat == 0))
  3302. pData->bSkipping = MNG_TRUE;
  3303. }
  3304. #endif /* MNG_SUPPORT_DISPLAY */
  3305. #ifdef MNG_STORE_CHUNKS
  3306. if (pData->bStorechunks)
  3307. { /* initialize storage */
  3308. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  3309. if (iRetcode) /* on error bail out */
  3310. return iRetcode;
  3311. if (iRawlen >= 5) /* store the fields */
  3312. {
  3313. ((mng_loopp)*ppChunk)->iLevel = *pRawdata;
  3314. #ifndef MNG_NO_OLD_VERSIONS
  3315. if (pData->bPreDraft48)
  3316. {
  3317. ((mng_loopp)*ppChunk)->iTermination = *(pRawdata+1);
  3318. ((mng_loopp)*ppChunk)->iRepeat = mng_get_uint32 (pRawdata+2);
  3319. }
  3320. else
  3321. #endif
  3322. {
  3323. ((mng_loopp)*ppChunk)->iRepeat = mng_get_uint32 (pRawdata+1);
  3324. }
  3325. if (iRawlen >= 6)
  3326. {
  3327. #ifndef MNG_NO_OLD_VERSIONS
  3328. if (!pData->bPreDraft48)
  3329. #endif
  3330. ((mng_loopp)*ppChunk)->iTermination = *(pRawdata+5);
  3331. if (iRawlen >= 10)
  3332. {
  3333. ((mng_loopp)*ppChunk)->iItermin = mng_get_uint32 (pRawdata+6);
  3334. #ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
  3335. if (iRawlen >= 14)
  3336. {
  3337. ((mng_loopp)*ppChunk)->iItermax = mng_get_uint32 (pRawdata+10);
  3338. ((mng_loopp)*ppChunk)->iCount = (iRawlen - 14) / 4;
  3339. if (((mng_loopp)*ppChunk)->iCount)
  3340. {
  3341. MNG_ALLOC (pData, ((mng_loopp)*ppChunk)->pSignals,
  3342. ((mng_loopp)*ppChunk)->iCount << 2);
  3343. #ifndef MNG_BIGENDIAN_SUPPORTED
  3344. {
  3345. mng_uint32 iX;
  3346. mng_uint8p pIn = pRawdata + 14;
  3347. mng_uint32p pOut = (mng_uint32p)((mng_loopp)*ppChunk)->pSignals;
  3348. for (iX = 0; iX < ((mng_loopp)*ppChunk)->iCount; iX++)
  3349. {
  3350. *pOut++ = mng_get_uint32 (pIn);
  3351. pIn += 4;
  3352. }
  3353. }
  3354. #else
  3355. MNG_COPY (((mng_loopp)*ppChunk)->pSignals, pRawdata + 14,
  3356. ((mng_loopp)*ppChunk)->iCount << 2);
  3357. #endif /* !MNG_BIGENDIAN_SUPPORTED */
  3358. }
  3359. }
  3360. #endif
  3361. }
  3362. }
  3363. }
  3364. }
  3365. #endif /* MNG_STORE_CHUNKS */
  3366. #ifdef MNG_SUPPORT_TRACE
  3367. MNG_TRACE (pData, MNG_FN_READ_LOOP, MNG_LC_END);
  3368. #endif
  3369. return MNG_NOERROR; /* done */
  3370. }
  3371. #endif
  3372. #endif
  3373. /* ************************************************************************** */
  3374. #ifndef MNG_OPTIMIZE_CHUNKREADER
  3375. #ifndef MNG_SKIPCHUNK_LOOP
  3376. READ_CHUNK (mng_read_endl)
  3377. {
  3378. #ifdef MNG_SUPPORT_TRACE
  3379. MNG_TRACE (pData, MNG_FN_READ_ENDL, MNG_LC_START);
  3380. #endif
  3381. if (!pData->bHasMHDR) /* sequence checks */
  3382. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3383. #ifdef MNG_INCLUDE_JNG
  3384. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  3385. #else
  3386. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  3387. #endif
  3388. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3389. if (iRawlen != 1) /* length must be exactly 1 */
  3390. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  3391. #ifdef MNG_SUPPORT_DISPLAY
  3392. {
  3393. if (pData->bHasLOOP) /* are we really processing a loop ? */
  3394. {
  3395. mng_uint8 iLevel = *pRawdata; /* get the nest level */
  3396. /* create an ENDL animation object */
  3397. mng_retcode iRetcode = mng_create_ani_endl (pData, iLevel);
  3398. if (iRetcode) /* on error bail out */
  3399. return iRetcode;
  3400. /* {
  3401. mng_ani_endlp pENDL = (mng_ani_endlp)pData->pLastaniobj;
  3402. iRetcode = pENDL->sHeader.fProcess (pData, pENDL);
  3403. if (iRetcode)
  3404. return iRetcode;
  3405. } */
  3406. }
  3407. else
  3408. MNG_ERROR (pData, MNG_NOMATCHINGLOOP);
  3409. }
  3410. #endif /* MNG_SUPPORT_DISPLAY */
  3411. #ifdef MNG_STORE_CHUNKS
  3412. if (pData->bStorechunks)
  3413. { /* initialize storage */
  3414. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  3415. if (iRetcode) /* on error bail out */
  3416. return iRetcode;
  3417. /* store the fields */
  3418. ((mng_endlp)*ppChunk)->iLevel = *pRawdata;
  3419. }
  3420. #endif /* MNG_STORE_CHUNKS */
  3421. #ifdef MNG_SUPPORT_TRACE
  3422. MNG_TRACE (pData, MNG_FN_READ_ENDL, MNG_LC_END);
  3423. #endif
  3424. return MNG_NOERROR; /* done */
  3425. }
  3426. #endif
  3427. #endif
  3428. /* ************************************************************************** */
  3429. #ifndef MNG_OPTIMIZE_CHUNKREADER
  3430. #ifndef MNG_SKIPCHUNK_DEFI
  3431. READ_CHUNK (mng_read_defi)
  3432. {
  3433. #ifdef MNG_SUPPORT_TRACE
  3434. MNG_TRACE (pData, MNG_FN_READ_DEFI, MNG_LC_START);
  3435. #endif
  3436. if (!pData->bHasMHDR) /* sequence checks */
  3437. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3438. #ifdef MNG_INCLUDE_JNG
  3439. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  3440. #else
  3441. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  3442. #endif
  3443. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3444. /* check the length */
  3445. if ((iRawlen != 2) && (iRawlen != 3) && (iRawlen != 4) &&
  3446. (iRawlen != 12) && (iRawlen != 28))
  3447. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  3448. #ifdef MNG_SUPPORT_DISPLAY
  3449. {
  3450. mng_retcode iRetcode;
  3451. pData->iDEFIobjectid = mng_get_uint16 (pRawdata);
  3452. if (iRawlen > 2)
  3453. {
  3454. pData->bDEFIhasdonotshow = MNG_TRUE;
  3455. pData->iDEFIdonotshow = *(pRawdata+2);
  3456. }
  3457. else
  3458. {
  3459. pData->bDEFIhasdonotshow = MNG_FALSE;
  3460. pData->iDEFIdonotshow = 0;
  3461. }
  3462. if (iRawlen > 3)
  3463. {
  3464. pData->bDEFIhasconcrete = MNG_TRUE;
  3465. pData->iDEFIconcrete = *(pRawdata+3);
  3466. }
  3467. else
  3468. {
  3469. pData->bDEFIhasconcrete = MNG_FALSE;
  3470. pData->iDEFIconcrete = 0;
  3471. }
  3472. if (iRawlen > 4)
  3473. {
  3474. pData->bDEFIhasloca = MNG_TRUE;
  3475. pData->iDEFIlocax = mng_get_int32 (pRawdata+4);
  3476. pData->iDEFIlocay = mng_get_int32 (pRawdata+8);
  3477. }
  3478. else
  3479. {
  3480. pData->bDEFIhasloca = MNG_FALSE;
  3481. pData->iDEFIlocax = 0;
  3482. pData->iDEFIlocay = 0;
  3483. }
  3484. if (iRawlen > 12)
  3485. {
  3486. pData->bDEFIhasclip = MNG_TRUE;
  3487. pData->iDEFIclipl = mng_get_int32 (pRawdata+12);
  3488. pData->iDEFIclipr = mng_get_int32 (pRawdata+16);
  3489. pData->iDEFIclipt = mng_get_int32 (pRawdata+20);
  3490. pData->iDEFIclipb = mng_get_int32 (pRawdata+24);
  3491. }
  3492. else
  3493. {
  3494. pData->bDEFIhasclip = MNG_FALSE;
  3495. pData->iDEFIclipl = 0;
  3496. pData->iDEFIclipr = 0;
  3497. pData->iDEFIclipt = 0;
  3498. pData->iDEFIclipb = 0;
  3499. }
  3500. /* create an animation object */
  3501. iRetcode = mng_create_ani_defi (pData);
  3502. if (!iRetcode) /* do display processing */
  3503. iRetcode = mng_process_display_defi (pData);
  3504. if (iRetcode) /* on error bail out */
  3505. return iRetcode;
  3506. }
  3507. #endif /* MNG_SUPPORT_DISPLAY */
  3508. #ifdef MNG_STORE_CHUNKS
  3509. if (pData->bStorechunks)
  3510. { /* initialize storage */
  3511. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  3512. if (iRetcode) /* on error bail out */
  3513. return iRetcode;
  3514. /* store the fields */
  3515. ((mng_defip)*ppChunk)->iObjectid = mng_get_uint16 (pRawdata);
  3516. if (iRawlen > 2)
  3517. {
  3518. ((mng_defip)*ppChunk)->bHasdonotshow = MNG_TRUE;
  3519. ((mng_defip)*ppChunk)->iDonotshow = *(pRawdata+2);
  3520. }
  3521. else
  3522. ((mng_defip)*ppChunk)->bHasdonotshow = MNG_FALSE;
  3523. if (iRawlen > 3)
  3524. {
  3525. ((mng_defip)*ppChunk)->bHasconcrete = MNG_TRUE;
  3526. ((mng_defip)*ppChunk)->iConcrete = *(pRawdata+3);
  3527. }
  3528. else
  3529. ((mng_defip)*ppChunk)->bHasconcrete = MNG_FALSE;
  3530. if (iRawlen > 4)
  3531. {
  3532. ((mng_defip)*ppChunk)->bHasloca = MNG_TRUE;
  3533. ((mng_defip)*ppChunk)->iXlocation = mng_get_int32 (pRawdata+4);
  3534. ((mng_defip)*ppChunk)->iYlocation = mng_get_int32 (pRawdata+8);
  3535. }
  3536. else
  3537. ((mng_defip)*ppChunk)->bHasloca = MNG_FALSE;
  3538. if (iRawlen > 12)
  3539. {
  3540. ((mng_defip)*ppChunk)->bHasclip = MNG_TRUE;
  3541. ((mng_defip)*ppChunk)->iLeftcb = mng_get_int32 (pRawdata+12);
  3542. ((mng_defip)*ppChunk)->iRightcb = mng_get_int32 (pRawdata+16);
  3543. ((mng_defip)*ppChunk)->iTopcb = mng_get_int32 (pRawdata+20);
  3544. ((mng_defip)*ppChunk)->iBottomcb = mng_get_int32 (pRawdata+24);
  3545. }
  3546. else
  3547. ((mng_defip)*ppChunk)->bHasclip = MNG_FALSE;
  3548. }
  3549. #endif /* MNG_STORE_CHUNKS */
  3550. #ifdef MNG_SUPPORT_TRACE
  3551. MNG_TRACE (pData, MNG_FN_READ_DEFI, MNG_LC_END);
  3552. #endif
  3553. return MNG_NOERROR; /* done */
  3554. }
  3555. #endif
  3556. #endif
  3557. /* ************************************************************************** */
  3558. #ifndef MNG_OPTIMIZE_CHUNKREADER
  3559. #ifndef MNG_SKIPCHUNK_BASI
  3560. READ_CHUNK (mng_read_basi)
  3561. {
  3562. #ifdef MNG_SUPPORT_TRACE
  3563. MNG_TRACE (pData, MNG_FN_READ_BASI, MNG_LC_START);
  3564. #endif
  3565. if (!pData->bHasMHDR) /* sequence checks */
  3566. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3567. #ifdef MNG_INCLUDE_JNG
  3568. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  3569. #else
  3570. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  3571. #endif
  3572. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3573. /* check the length */
  3574. if ((iRawlen != 13) && (iRawlen != 19) && (iRawlen != 21) && (iRawlen != 22))
  3575. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  3576. pData->bHasBASI = MNG_TRUE; /* inside a BASI-IEND block now */
  3577. /* store interesting fields */
  3578. pData->iDatawidth = mng_get_uint32 (pRawdata);
  3579. pData->iDataheight = mng_get_uint32 (pRawdata+4);
  3580. pData->iBitdepth = *(pRawdata+8);
  3581. pData->iColortype = *(pRawdata+9);
  3582. pData->iCompression = *(pRawdata+10);
  3583. pData->iFilter = *(pRawdata+11);
  3584. pData->iInterlace = *(pRawdata+12);
  3585. #if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT)
  3586. pData->iPNGmult = 1;
  3587. pData->iPNGdepth = pData->iBitdepth;
  3588. #endif
  3589. #ifdef MNG_NO_1_2_4BIT_SUPPORT
  3590. if (pData->iBitdepth < 8)
  3591. pData->iBitdepth = 8;
  3592. #endif
  3593. #ifdef MNG_NO_16BIT_SUPPORT
  3594. if (pData->iBitdepth > 8)
  3595. {
  3596. pData->iBitdepth = 8;
  3597. pData->iPNGmult = 2;
  3598. }
  3599. #endif
  3600. if ((pData->iBitdepth != 8) /* parameter validity checks */
  3601. #ifndef MNG_NO_1_2_4BIT_SUPPORT
  3602. && (pData->iBitdepth != 1) &&
  3603. (pData->iBitdepth != 2) &&
  3604. (pData->iBitdepth != 4)
  3605. #endif
  3606. #ifndef MNG_NO_16BIT_SUPPORT
  3607. && (pData->iBitdepth != 16)
  3608. #endif
  3609. )
  3610. MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
  3611. if ((pData->iColortype != MNG_COLORTYPE_GRAY ) &&
  3612. (pData->iColortype != MNG_COLORTYPE_RGB ) &&
  3613. (pData->iColortype != MNG_COLORTYPE_INDEXED) &&
  3614. (pData->iColortype != MNG_COLORTYPE_GRAYA ) &&
  3615. (pData->iColortype != MNG_COLORTYPE_RGBA ) )
  3616. MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
  3617. if ((pData->iColortype == MNG_COLORTYPE_INDEXED) && (pData->iBitdepth > 8))
  3618. MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
  3619. if (((pData->iColortype == MNG_COLORTYPE_RGB ) ||
  3620. (pData->iColortype == MNG_COLORTYPE_GRAYA ) ||
  3621. (pData->iColortype == MNG_COLORTYPE_RGBA ) ) &&
  3622. (pData->iBitdepth < 8 ) )
  3623. MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
  3624. if (pData->iCompression != MNG_COMPRESSION_DEFLATE)
  3625. MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
  3626. #if defined(FILTER192) || defined(FILTER193)
  3627. if ((pData->iFilter != MNG_FILTER_ADAPTIVE ) &&
  3628. #if defined(FILTER192) && defined(FILTER193)
  3629. (pData->iFilter != MNG_FILTER_DIFFERING) &&
  3630. (pData->iFilter != MNG_FILTER_NOFILTER ) )
  3631. #else
  3632. #ifdef FILTER192
  3633. (pData->iFilter != MNG_FILTER_DIFFERING) )
  3634. #else
  3635. (pData->iFilter != MNG_FILTER_NOFILTER ) )
  3636. #endif
  3637. #endif
  3638. MNG_ERROR (pData, MNG_INVALIDFILTER);
  3639. #else
  3640. if (pData->iFilter)
  3641. MNG_ERROR (pData, MNG_INVALIDFILTER);
  3642. #endif
  3643. if ((pData->iInterlace != MNG_INTERLACE_NONE ) &&
  3644. (pData->iInterlace != MNG_INTERLACE_ADAM7) )
  3645. MNG_ERROR (pData, MNG_INVALIDINTERLACE);
  3646. pData->iImagelevel++; /* one level deeper */
  3647. #ifdef MNG_SUPPORT_DISPLAY
  3648. {
  3649. mng_uint16 iRed = 0;
  3650. mng_uint16 iGreen = 0;
  3651. mng_uint16 iBlue = 0;
  3652. mng_bool bHasalpha = MNG_FALSE;
  3653. mng_uint16 iAlpha = 0xFFFF;
  3654. mng_uint8 iViewable = 0;
  3655. mng_retcode iRetcode;
  3656. if (iRawlen > 13) /* get remaining fields, if any */
  3657. {
  3658. iRed = mng_get_uint16 (pRawdata+13);
  3659. iGreen = mng_get_uint16 (pRawdata+15);
  3660. iBlue = mng_get_uint16 (pRawdata+17);
  3661. }
  3662. if (iRawlen > 19)
  3663. {
  3664. bHasalpha = MNG_TRUE;
  3665. iAlpha = mng_get_uint16 (pRawdata+19);
  3666. }
  3667. if (iRawlen > 21)
  3668. iViewable = *(pRawdata+21);
  3669. /* create an animation object */
  3670. iRetcode = mng_create_ani_basi (pData, iRed, iGreen, iBlue,
  3671. bHasalpha, iAlpha, iViewable);
  3672. /* if (!iRetcode)
  3673. iRetcode = mng_process_display_basi (pData, iRed, iGreen, iBlue,
  3674. bHasalpha, iAlpha, iViewable); */
  3675. if (iRetcode) /* on error bail out */
  3676. return iRetcode;
  3677. }
  3678. #endif /* MNG_SUPPORT_DISPLAY */
  3679. #ifdef MNG_STORE_CHUNKS
  3680. if (pData->bStorechunks)
  3681. { /* initialize storage */
  3682. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  3683. if (iRetcode) /* on error bail out */
  3684. return iRetcode;
  3685. /* store the fields */
  3686. ((mng_basip)*ppChunk)->iWidth = mng_get_uint32 (pRawdata);
  3687. ((mng_basip)*ppChunk)->iHeight = mng_get_uint32 (pRawdata+4);
  3688. #ifdef MNG_NO_16BIT_SUPPORT
  3689. if (*(pRawdata+8) > 8)
  3690. ((mng_basip)*ppChunk)->iBitdepth = 8;
  3691. else
  3692. #endif
  3693. ((mng_basip)*ppChunk)->iBitdepth = *(pRawdata+8);
  3694. ((mng_basip)*ppChunk)->iColortype = *(pRawdata+9);
  3695. ((mng_basip)*ppChunk)->iCompression = *(pRawdata+10);
  3696. ((mng_basip)*ppChunk)->iFilter = *(pRawdata+11);
  3697. ((mng_basip)*ppChunk)->iInterlace = *(pRawdata+12);
  3698. if (iRawlen > 13)
  3699. {
  3700. ((mng_basip)*ppChunk)->iRed = mng_get_uint16 (pRawdata+13);
  3701. ((mng_basip)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+15);
  3702. ((mng_basip)*ppChunk)->iBlue = mng_get_uint16 (pRawdata+17);
  3703. }
  3704. if (iRawlen > 19)
  3705. ((mng_basip)*ppChunk)->iAlpha = mng_get_uint16 (pRawdata+19);
  3706. if (iRawlen > 21)
  3707. ((mng_basip)*ppChunk)->iViewable = *(pRawdata+21);
  3708. }
  3709. #endif /* MNG_STORE_CHUNKS */
  3710. #ifdef MNG_SUPPORT_TRACE
  3711. MNG_TRACE (pData, MNG_FN_READ_BASI, MNG_LC_END);
  3712. #endif
  3713. return MNG_NOERROR; /* done */
  3714. }
  3715. #endif
  3716. #endif
  3717. /* ************************************************************************** */
  3718. #ifndef MNG_OPTIMIZE_CHUNKREADER
  3719. #ifndef MNG_SKIPCHUNK_CLON
  3720. READ_CHUNK (mng_read_clon)
  3721. {
  3722. #ifdef MNG_SUPPORT_TRACE
  3723. MNG_TRACE (pData, MNG_FN_READ_CLON, MNG_LC_START);
  3724. #endif
  3725. if (!pData->bHasMHDR) /* sequence checks */
  3726. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3727. #ifdef MNG_INCLUDE_JNG
  3728. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  3729. #else
  3730. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  3731. #endif
  3732. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3733. /* check the length */
  3734. if ((iRawlen != 4) && (iRawlen != 5) && (iRawlen != 6) &&
  3735. (iRawlen != 7) && (iRawlen != 16))
  3736. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  3737. #ifdef MNG_SUPPORT_DISPLAY
  3738. {
  3739. mng_uint16 iSourceid, iCloneid;
  3740. mng_uint8 iClonetype = 0;
  3741. mng_bool bHasdonotshow = MNG_FALSE;
  3742. mng_uint8 iDonotshow = 0;
  3743. mng_uint8 iConcrete = 0;
  3744. mng_bool bHasloca = MNG_FALSE;
  3745. mng_uint8 iLocationtype = 0;
  3746. mng_int32 iLocationx = 0;
  3747. mng_int32 iLocationy = 0;
  3748. mng_retcode iRetcode;
  3749. iSourceid = mng_get_uint16 (pRawdata);
  3750. iCloneid = mng_get_uint16 (pRawdata+2);
  3751. if (iRawlen > 4)
  3752. iClonetype = *(pRawdata+4);
  3753. if (iRawlen > 5)
  3754. {
  3755. bHasdonotshow = MNG_TRUE;
  3756. iDonotshow = *(pRawdata+5);
  3757. }
  3758. if (iRawlen > 6)
  3759. iConcrete = *(pRawdata+6);
  3760. if (iRawlen > 7)
  3761. {
  3762. bHasloca = MNG_TRUE;
  3763. iLocationtype = *(pRawdata+7);
  3764. iLocationx = mng_get_int32 (pRawdata+8);
  3765. iLocationy = mng_get_int32 (pRawdata+12);
  3766. }
  3767. iRetcode = mng_create_ani_clon (pData, iSourceid, iCloneid, iClonetype,
  3768. bHasdonotshow, iDonotshow, iConcrete,
  3769. bHasloca, iLocationtype, iLocationx, iLocationy);
  3770. /* if (!iRetcode)
  3771. iRetcode = mng_process_display_clon (pData, iSourceid, iCloneid, iClonetype,
  3772. bHasdonotshow, iDonotshow, iConcrete,
  3773. bHasloca, iLocationtype, iLocationx,
  3774. iLocationy); */
  3775. if (iRetcode) /* on error bail out */
  3776. return iRetcode;
  3777. }
  3778. #endif /* MNG_SUPPORT_DISPLAY */
  3779. #ifdef MNG_STORE_CHUNKS
  3780. if (pData->bStorechunks)
  3781. { /* initialize storage */
  3782. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  3783. if (iRetcode) /* on error bail out */
  3784. return iRetcode;
  3785. /* store the fields */
  3786. ((mng_clonp)*ppChunk)->iSourceid = mng_get_uint16 (pRawdata);
  3787. ((mng_clonp)*ppChunk)->iCloneid = mng_get_uint16 (pRawdata+2);
  3788. if (iRawlen > 4)
  3789. ((mng_clonp)*ppChunk)->iClonetype = *(pRawdata+4);
  3790. if (iRawlen > 5)
  3791. ((mng_clonp)*ppChunk)->iDonotshow = *(pRawdata+5);
  3792. if (iRawlen > 6)
  3793. ((mng_clonp)*ppChunk)->iConcrete = *(pRawdata+6);
  3794. if (iRawlen > 7)
  3795. {
  3796. ((mng_clonp)*ppChunk)->bHasloca = MNG_TRUE;
  3797. ((mng_clonp)*ppChunk)->iLocationtype = *(pRawdata+7);
  3798. ((mng_clonp)*ppChunk)->iLocationx = mng_get_int32 (pRawdata+8);
  3799. ((mng_clonp)*ppChunk)->iLocationy = mng_get_int32 (pRawdata+12);
  3800. }
  3801. else
  3802. {
  3803. ((mng_clonp)*ppChunk)->bHasloca = MNG_FALSE;
  3804. }
  3805. }
  3806. #endif /* MNG_STORE_CHUNKS */
  3807. #ifdef MNG_SUPPORT_TRACE
  3808. MNG_TRACE (pData, MNG_FN_READ_CLON, MNG_LC_END);
  3809. #endif
  3810. return MNG_NOERROR; /* done */
  3811. }
  3812. #endif
  3813. #endif
  3814. /* ************************************************************************** */
  3815. #ifndef MNG_OPTIMIZE_CHUNKREADER
  3816. #ifndef MNG_SKIPCHUNK_PAST
  3817. READ_CHUNK (mng_read_past)
  3818. {
  3819. #if defined(MNG_STORE_CHUNKS) || defined(MNG_SUPPORT_DISPLAY)
  3820. mng_retcode iRetcode;
  3821. mng_uint16 iTargetid;
  3822. mng_uint8 iTargettype;
  3823. mng_int32 iTargetx;
  3824. mng_int32 iTargety;
  3825. mng_uint32 iCount;
  3826. mng_uint32 iSize;
  3827. mng_ptr pSources;
  3828. mng_uint32 iX;
  3829. mng_past_sourcep pSource;
  3830. #endif
  3831. #ifdef MNG_SUPPORT_TRACE
  3832. MNG_TRACE (pData, MNG_FN_READ_PAST, MNG_LC_START);
  3833. #endif
  3834. if (!pData->bHasMHDR) /* sequence checks */
  3835. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3836. #ifdef MNG_INCLUDE_JNG
  3837. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  3838. #else
  3839. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  3840. #endif
  3841. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3842. /* check the length */
  3843. if ((iRawlen < 41) || (((iRawlen - 11) % 30) != 0))
  3844. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  3845. #if defined(MNG_STORE_CHUNKS) || defined(MNG_SUPPORT_DISPLAY)
  3846. iTargetid = mng_get_uint16 (pRawdata);
  3847. iTargettype = *(pRawdata+2);
  3848. iTargetx = mng_get_int32 (pRawdata+3);
  3849. iTargety = mng_get_int32 (pRawdata+7);
  3850. iCount = ((iRawlen - 11) / 30); /* how many entries again? */
  3851. iSize = iCount * sizeof (mng_past_source);
  3852. pRawdata += 11;
  3853. /* get a buffer for all the source blocks */
  3854. MNG_ALLOC (pData, pSources, iSize);
  3855. pSource = (mng_past_sourcep)pSources;
  3856. for (iX = 0; iX < iCount; iX++) /* now copy the source blocks */
  3857. {
  3858. pSource->iSourceid = mng_get_uint16 (pRawdata);
  3859. pSource->iComposition = *(pRawdata+2);
  3860. pSource->iOrientation = *(pRawdata+3);
  3861. pSource->iOffsettype = *(pRawdata+4);
  3862. pSource->iOffsetx = mng_get_int32 (pRawdata+5);
  3863. pSource->iOffsety = mng_get_int32 (pRawdata+9);
  3864. pSource->iBoundarytype = *(pRawdata+13);
  3865. pSource->iBoundaryl = mng_get_int32 (pRawdata+14);
  3866. pSource->iBoundaryr = mng_get_int32 (pRawdata+18);
  3867. pSource->iBoundaryt = mng_get_int32 (pRawdata+22);
  3868. pSource->iBoundaryb = mng_get_int32 (pRawdata+26);
  3869. pSource++;
  3870. pRawdata += 30;
  3871. }
  3872. #endif
  3873. #ifdef MNG_SUPPORT_DISPLAY
  3874. { /* create playback object */
  3875. iRetcode = mng_create_ani_past (pData, iTargetid, iTargettype, iTargetx,
  3876. iTargety, iCount, pSources);
  3877. /* if (!iRetcode)
  3878. iRetcode = mng_process_display_past (pData, iTargetid, iTargettype, iTargetx,
  3879. iTargety, iCount, pSources); */
  3880. if (iRetcode) /* on error bail out */
  3881. {
  3882. MNG_FREEX (pData, pSources, iSize);
  3883. return iRetcode;
  3884. }
  3885. }
  3886. #endif /* MNG_SUPPORT_DISPLAY */
  3887. #ifdef MNG_STORE_CHUNKS
  3888. if (pData->bStorechunks)
  3889. { /* initialize storage */
  3890. iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  3891. if (iRetcode) /* on error bail out */
  3892. {
  3893. MNG_FREEX (pData, pSources, iSize);
  3894. return iRetcode;
  3895. }
  3896. /* store the fields */
  3897. ((mng_pastp)*ppChunk)->iDestid = iTargetid;
  3898. ((mng_pastp)*ppChunk)->iTargettype = iTargettype;
  3899. ((mng_pastp)*ppChunk)->iTargetx = iTargetx;
  3900. ((mng_pastp)*ppChunk)->iTargety = iTargety;
  3901. ((mng_pastp)*ppChunk)->iCount = iCount;
  3902. /* get a buffer & copy the source blocks */
  3903. MNG_ALLOC (pData, ((mng_pastp)*ppChunk)->pSources, iSize);
  3904. MNG_COPY (((mng_pastp)*ppChunk)->pSources, pSources, iSize);
  3905. }
  3906. #endif /* MNG_STORE_CHUNKS */
  3907. #if defined(MNG_STORE_CHUNKS) || defined(MNG_SUPPORT_DISPLAY)
  3908. /* free the source block buffer */
  3909. MNG_FREEX (pData, pSources, iSize);
  3910. #endif
  3911. #ifdef MNG_SUPPORT_TRACE
  3912. MNG_TRACE (pData, MNG_FN_READ_PAST, MNG_LC_END);
  3913. #endif
  3914. return MNG_NOERROR; /* done */
  3915. }
  3916. #endif
  3917. #endif
  3918. /* ************************************************************************** */
  3919. #ifndef MNG_OPTIMIZE_CHUNKREADER
  3920. #ifndef MNG_SKIPCHUNK_DISC
  3921. READ_CHUNK (mng_read_disc)
  3922. {
  3923. #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
  3924. mng_uint32 iCount;
  3925. mng_uint16p pIds = MNG_NULL;
  3926. mng_retcode iRetcode;
  3927. #endif
  3928. #ifdef MNG_SUPPORT_TRACE
  3929. MNG_TRACE (pData, MNG_FN_READ_DISC, MNG_LC_START);
  3930. #endif
  3931. if (!pData->bHasMHDR) /* sequence checks */
  3932. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3933. #ifdef MNG_INCLUDE_JNG
  3934. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  3935. #else
  3936. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  3937. #endif
  3938. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  3939. if ((iRawlen % 2) != 0) /* check the length */
  3940. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  3941. #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
  3942. iCount = (iRawlen / sizeof (mng_uint16));
  3943. if (iCount)
  3944. {
  3945. MNG_ALLOC (pData, pIds, iRawlen);
  3946. #ifndef MNG_BIGENDIAN_SUPPORTED
  3947. {
  3948. mng_uint32 iX;
  3949. mng_uint8p pIn = pRawdata;
  3950. mng_uint16p pOut = pIds;
  3951. for (iX = 0; iX < iCount; iX++)
  3952. {
  3953. *pOut++ = mng_get_uint16 (pIn);
  3954. pIn += 2;
  3955. }
  3956. }
  3957. #else
  3958. MNG_COPY (pIds, pRawdata, iRawlen);
  3959. #endif /* !MNG_BIGENDIAN_SUPPORTED */
  3960. }
  3961. #endif
  3962. #ifdef MNG_SUPPORT_DISPLAY
  3963. { /* create playback object */
  3964. iRetcode = mng_create_ani_disc (pData, iCount, pIds);
  3965. /* if (!iRetcode)
  3966. iRetcode = mng_process_display_disc (pData, iCount, pIds); */
  3967. if (iRetcode) /* on error bail out */
  3968. return iRetcode;
  3969. }
  3970. #endif /* MNG_SUPPORT_DISPLAY */
  3971. #ifdef MNG_STORE_CHUNKS
  3972. if (pData->bStorechunks)
  3973. { /* initialize storage */
  3974. iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  3975. if (iRetcode) /* on error bail out */
  3976. return iRetcode;
  3977. /* store the fields */
  3978. ((mng_discp)*ppChunk)->iCount = iCount;
  3979. if (iRawlen)
  3980. {
  3981. MNG_ALLOC (pData, ((mng_discp)*ppChunk)->pObjectids, iRawlen);
  3982. MNG_COPY (((mng_discp)*ppChunk)->pObjectids, pIds, iRawlen);
  3983. }
  3984. }
  3985. #endif /* MNG_STORE_CHUNKS */
  3986. #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
  3987. if (iRawlen)
  3988. MNG_FREEX (pData, pIds, iRawlen);
  3989. #endif
  3990. #ifdef MNG_SUPPORT_TRACE
  3991. MNG_TRACE (pData, MNG_FN_READ_DISC, MNG_LC_END);
  3992. #endif
  3993. return MNG_NOERROR; /* done */
  3994. }
  3995. #endif
  3996. #endif
  3997. /* ************************************************************************** */
  3998. #ifndef MNG_OPTIMIZE_CHUNKREADER
  3999. #ifndef MNG_SKIPCHUNK_BACK
  4000. READ_CHUNK (mng_read_back)
  4001. {
  4002. #ifdef MNG_SUPPORT_TRACE
  4003. MNG_TRACE (pData, MNG_FN_READ_BACK, MNG_LC_START);
  4004. #endif
  4005. if (!pData->bHasMHDR) /* sequence checks */
  4006. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4007. #ifdef MNG_INCLUDE_JNG
  4008. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  4009. #else
  4010. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  4011. #endif
  4012. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4013. /* check the length */
  4014. if ((iRawlen != 6) && (iRawlen != 7) && (iRawlen != 9) && (iRawlen != 10))
  4015. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  4016. #ifdef MNG_SUPPORT_DISPLAY
  4017. {
  4018. mng_retcode iRetcode;
  4019. /* retrieve the fields */
  4020. pData->bHasBACK = MNG_TRUE;
  4021. pData->iBACKred = mng_get_uint16 (pRawdata);
  4022. pData->iBACKgreen = mng_get_uint16 (pRawdata+2);
  4023. pData->iBACKblue = mng_get_uint16 (pRawdata+4);
  4024. if (iRawlen > 6)
  4025. pData->iBACKmandatory = *(pRawdata+6);
  4026. else
  4027. pData->iBACKmandatory = 0;
  4028. if (iRawlen > 7)
  4029. pData->iBACKimageid = mng_get_uint16 (pRawdata+7);
  4030. else
  4031. pData->iBACKimageid = 0;
  4032. if (iRawlen > 9)
  4033. pData->iBACKtile = *(pRawdata+9);
  4034. else
  4035. pData->iBACKtile = 0;
  4036. iRetcode = mng_create_ani_back (pData, pData->iBACKred, pData->iBACKgreen,
  4037. pData->iBACKblue, pData->iBACKmandatory,
  4038. pData->iBACKimageid, pData->iBACKtile);
  4039. if (iRetcode) /* on error bail out */
  4040. return iRetcode;
  4041. }
  4042. #endif /* MNG_SUPPORT_DISPLAY */
  4043. #ifdef MNG_STORE_CHUNKS
  4044. if (pData->bStorechunks)
  4045. { /* initialize storage */
  4046. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  4047. if (iRetcode) /* on error bail out */
  4048. return iRetcode;
  4049. /* store the fields */
  4050. ((mng_backp)*ppChunk)->iRed = mng_get_uint16 (pRawdata);
  4051. ((mng_backp)*ppChunk)->iGreen = mng_get_uint16 (pRawdata+2);
  4052. ((mng_backp)*ppChunk)->iBlue = mng_get_uint16 (pRawdata+4);
  4053. if (iRawlen > 6)
  4054. ((mng_backp)*ppChunk)->iMandatory = *(pRawdata+6);
  4055. if (iRawlen > 7)
  4056. ((mng_backp)*ppChunk)->iImageid = mng_get_uint16 (pRawdata+7);
  4057. if (iRawlen > 9)
  4058. ((mng_backp)*ppChunk)->iTile = *(pRawdata+9);
  4059. }
  4060. #endif /* MNG_STORE_CHUNKS */
  4061. #ifdef MNG_SUPPORT_TRACE
  4062. MNG_TRACE (pData, MNG_FN_READ_BACK, MNG_LC_END);
  4063. #endif
  4064. return MNG_NOERROR; /* done */
  4065. }
  4066. #endif
  4067. #endif
  4068. /* ************************************************************************** */
  4069. #ifndef MNG_OPTIMIZE_CHUNKREADER
  4070. #ifndef MNG_SKIPCHUNK_FRAM
  4071. READ_CHUNK (mng_read_fram)
  4072. {
  4073. mng_uint8p pTemp;
  4074. #ifdef MNG_STORE_CHUNKS
  4075. mng_uint32 iNamelen;
  4076. #endif
  4077. mng_uint32 iRemain;
  4078. mng_uint32 iRequired = 0;
  4079. #ifdef MNG_SUPPORT_TRACE
  4080. MNG_TRACE (pData, MNG_FN_READ_FRAM, MNG_LC_START);
  4081. #endif
  4082. if (!pData->bHasMHDR) /* sequence checks */
  4083. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4084. #ifdef MNG_INCLUDE_JNG
  4085. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  4086. #else
  4087. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  4088. #endif
  4089. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4090. if (iRawlen <= 1) /* only framing-mode ? */
  4091. {
  4092. #ifdef MNG_STORE_CHUNKS
  4093. iNamelen = 0; /* indicate so */
  4094. #endif
  4095. iRemain = 0;
  4096. pTemp = MNG_NULL;
  4097. }
  4098. else
  4099. {
  4100. pTemp = find_null (pRawdata+1); /* find null-separator */
  4101. /* not found inside input-data ? */
  4102. if ((pTemp - pRawdata) > (mng_int32)iRawlen)
  4103. pTemp = pRawdata + iRawlen; /* than remainder is name */
  4104. #ifdef MNG_STORE_CHUNKS
  4105. iNamelen = (mng_uint32)((pTemp - pRawdata) - 1);
  4106. #endif
  4107. iRemain = (mng_uint32)(iRawlen - (pTemp - pRawdata));
  4108. if (iRemain) /* if there is remaining data it's less 1 byte */
  4109. iRemain--;
  4110. if ((iRemain) && (iRemain < 4)) /* remains must be empty or at least 4 bytes */
  4111. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  4112. if (iRemain)
  4113. {
  4114. iRequired = 4; /* calculate and check required remaining length */
  4115. if (*(pTemp+1)) { iRequired += 4; }
  4116. if (*(pTemp+2)) { iRequired += 4; }
  4117. if (*(pTemp+3)) { iRequired += 17; }
  4118. if (*(pTemp+4))
  4119. {
  4120. if ((iRemain - iRequired) % 4 != 0)
  4121. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  4122. }
  4123. else
  4124. {
  4125. if (iRemain != iRequired)
  4126. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  4127. }
  4128. }
  4129. }
  4130. #ifdef MNG_SUPPORT_DISPLAY
  4131. {
  4132. mng_uint8p pWork = pTemp;
  4133. mng_uint8 iFramemode = 0;
  4134. mng_uint8 iChangedelay = 0;
  4135. mng_uint32 iDelay = 0;
  4136. mng_uint8 iChangetimeout = 0;
  4137. mng_uint32 iTimeout = 0;
  4138. mng_uint8 iChangeclipping = 0;
  4139. mng_uint8 iCliptype = 0;
  4140. mng_int32 iClipl = 0;
  4141. mng_int32 iClipr = 0;
  4142. mng_int32 iClipt = 0;
  4143. mng_int32 iClipb = 0;
  4144. mng_retcode iRetcode;
  4145. if (iRawlen) /* any data specified ? */
  4146. {
  4147. if (*(pRawdata)) /* save the new framing mode ? */
  4148. {
  4149. iFramemode = *(pRawdata);
  4150. #ifndef MNG_NO_OLD_VERSIONS
  4151. if (pData->bPreDraft48) /* old style input-stream ? */
  4152. {
  4153. switch (iFramemode)
  4154. {
  4155. case 0: { break; }
  4156. case 1: { iFramemode = 3; break; }
  4157. case 2: { iFramemode = 4; break; }
  4158. case 3: { iFramemode = 1; break; }
  4159. case 4: { iFramemode = 1; break; }
  4160. case 5: { iFramemode = 2; break; }
  4161. default: { iFramemode = 1; break; }
  4162. }
  4163. }
  4164. #endif
  4165. }
  4166. if (iRemain)
  4167. {
  4168. iChangedelay = *(pWork+1);
  4169. iChangetimeout = *(pWork+2);
  4170. iChangeclipping = *(pWork+3);
  4171. pWork += 5;
  4172. if (iChangedelay) /* delay changed ? */
  4173. {
  4174. iDelay = mng_get_uint32 (pWork);
  4175. pWork += 4;
  4176. }
  4177. if (iChangetimeout) /* timeout changed ? */
  4178. {
  4179. iTimeout = mng_get_uint32 (pWork);
  4180. pWork += 4;
  4181. }
  4182. if (iChangeclipping) /* clipping changed ? */
  4183. {
  4184. iCliptype = *pWork;
  4185. iClipl = mng_get_int32 (pWork+1);
  4186. iClipr = mng_get_int32 (pWork+5);
  4187. iClipt = mng_get_int32 (pWork+9);
  4188. iClipb = mng_get_int32 (pWork+13);
  4189. }
  4190. }
  4191. }
  4192. iRetcode = mng_create_ani_fram (pData, iFramemode, iChangedelay, iDelay,
  4193. iChangetimeout, iTimeout,
  4194. iChangeclipping, iCliptype,
  4195. iClipl, iClipr, iClipt, iClipb);
  4196. /* if (!iRetcode)
  4197. iRetcode = mng_process_display_fram (pData, iFramemode, iChangedelay, iDelay,
  4198. iChangetimeout, iTimeout,
  4199. iChangeclipping, iCliptype,
  4200. iClipl, iClipr, iClipt, iClipb); */
  4201. if (iRetcode) /* on error bail out */
  4202. return iRetcode;
  4203. }
  4204. #endif /* MNG_SUPPORT_DISPLAY */
  4205. #ifdef MNG_STORE_CHUNKS
  4206. if (pData->bStorechunks)
  4207. { /* initialize storage */
  4208. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  4209. if (iRetcode) /* on error bail out */
  4210. return iRetcode;
  4211. /* store the fields */
  4212. ((mng_framp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  4213. if (iRawlen)
  4214. {
  4215. mng_uint8 iFramemode = *(pRawdata);
  4216. #ifndef MNG_NO_OLD_VERSIONS
  4217. if (pData->bPreDraft48) /* old style input-stream ? */
  4218. {
  4219. switch (iFramemode)
  4220. {
  4221. case 1: { iFramemode = 3; break; }
  4222. case 2: { iFramemode = 4; break; }
  4223. case 3: { iFramemode = 5; break; } /* TODO: provision for mode=5 ??? */
  4224. case 4: { iFramemode = 1; break; }
  4225. case 5: { iFramemode = 2; break; }
  4226. default: { iFramemode = 1; break; }
  4227. }
  4228. }
  4229. #endif
  4230. ((mng_framp)*ppChunk)->iMode = iFramemode;
  4231. ((mng_framp)*ppChunk)->iNamesize = iNamelen;
  4232. if (iNamelen)
  4233. {
  4234. MNG_ALLOC (pData, ((mng_framp)*ppChunk)->zName, iNamelen+1);
  4235. MNG_COPY (((mng_framp)*ppChunk)->zName, pRawdata+1, iNamelen);
  4236. }
  4237. if (iRemain)
  4238. {
  4239. ((mng_framp)*ppChunk)->iChangedelay = *(pTemp+1);
  4240. ((mng_framp)*ppChunk)->iChangetimeout = *(pTemp+2);
  4241. ((mng_framp)*ppChunk)->iChangeclipping = *(pTemp+3);
  4242. ((mng_framp)*ppChunk)->iChangesyncid = *(pTemp+4);
  4243. pTemp += 5;
  4244. if (((mng_framp)*ppChunk)->iChangedelay)
  4245. {
  4246. ((mng_framp)*ppChunk)->iDelay = mng_get_uint32 (pTemp);
  4247. pTemp += 4;
  4248. }
  4249. if (((mng_framp)*ppChunk)->iChangetimeout)
  4250. {
  4251. ((mng_framp)*ppChunk)->iTimeout = mng_get_uint32 (pTemp);
  4252. pTemp += 4;
  4253. }
  4254. if (((mng_framp)*ppChunk)->iChangeclipping)
  4255. {
  4256. ((mng_framp)*ppChunk)->iBoundarytype = *pTemp;
  4257. ((mng_framp)*ppChunk)->iBoundaryl = mng_get_int32 (pTemp+1);
  4258. ((mng_framp)*ppChunk)->iBoundaryr = mng_get_int32 (pTemp+5);
  4259. ((mng_framp)*ppChunk)->iBoundaryt = mng_get_int32 (pTemp+9);
  4260. ((mng_framp)*ppChunk)->iBoundaryb = mng_get_int32 (pTemp+13);
  4261. pTemp += 17;
  4262. }
  4263. if (((mng_framp)*ppChunk)->iChangesyncid)
  4264. {
  4265. ((mng_framp)*ppChunk)->iCount = (iRemain - iRequired) / 4;
  4266. if (((mng_framp)*ppChunk)->iCount)
  4267. {
  4268. MNG_ALLOC (pData, ((mng_framp)*ppChunk)->pSyncids,
  4269. ((mng_framp)*ppChunk)->iCount * 4);
  4270. #ifndef MNG_BIGENDIAN_SUPPORTED
  4271. {
  4272. mng_uint32 iX;
  4273. mng_uint32p pOut = ((mng_framp)*ppChunk)->pSyncids;
  4274. for (iX = 0; iX < ((mng_framp)*ppChunk)->iCount; iX++)
  4275. {
  4276. *pOut++ = mng_get_uint32 (pTemp);
  4277. pTemp += 4;
  4278. }
  4279. }
  4280. #else
  4281. MNG_COPY (((mng_framp)*ppChunk)->pSyncids, pTemp,
  4282. ((mng_framp)*ppChunk)->iCount * 4);
  4283. #endif /* !MNG_BIGENDIAN_SUPPORTED */
  4284. }
  4285. }
  4286. }
  4287. }
  4288. }
  4289. #endif /* MNG_STORE_CHUNKS */
  4290. #ifdef MNG_SUPPORT_TRACE
  4291. MNG_TRACE (pData, MNG_FN_READ_FRAM, MNG_LC_END);
  4292. #endif
  4293. return MNG_NOERROR; /* done */
  4294. }
  4295. #endif
  4296. #endif
  4297. /* ************************************************************************** */
  4298. #ifndef MNG_OPTIMIZE_CHUNKREADER
  4299. #ifndef MNG_SKIPCHUNK_MOVE
  4300. READ_CHUNK (mng_read_move)
  4301. {
  4302. #ifdef MNG_SUPPORT_TRACE
  4303. MNG_TRACE (pData, MNG_FN_READ_MOVE, MNG_LC_START);
  4304. #endif
  4305. if (!pData->bHasMHDR) /* sequence checks */
  4306. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4307. #ifdef MNG_INCLUDE_JNG
  4308. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  4309. #else
  4310. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  4311. #endif
  4312. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4313. if (iRawlen != 13) /* check the length */
  4314. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  4315. #ifdef MNG_SUPPORT_DISPLAY
  4316. {
  4317. mng_retcode iRetcode;
  4318. /* create a MOVE animation object */
  4319. iRetcode = mng_create_ani_move (pData, mng_get_uint16 (pRawdata),
  4320. mng_get_uint16 (pRawdata+2),
  4321. *(pRawdata+4),
  4322. mng_get_int32 (pRawdata+5),
  4323. mng_get_int32 (pRawdata+9));
  4324. /* if (!iRetcode)
  4325. iRetcode = mng_process_display_move (pData,
  4326. mng_get_uint16 (pRawdata),
  4327. mng_get_uint16 (pRawdata+2),
  4328. *(pRawdata+4),
  4329. mng_get_int32 (pRawdata+5),
  4330. mng_get_int32 (pRawdata+9)); */
  4331. if (iRetcode) /* on error bail out */
  4332. return iRetcode;
  4333. }
  4334. #endif /* MNG_SUPPORT_DISPLAY */
  4335. #ifdef MNG_STORE_CHUNKS
  4336. if (pData->bStorechunks)
  4337. { /* initialize storage */
  4338. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  4339. if (iRetcode) /* on error bail out */
  4340. return iRetcode;
  4341. /* store the fields */
  4342. ((mng_movep)*ppChunk)->iFirstid = mng_get_uint16 (pRawdata);
  4343. ((mng_movep)*ppChunk)->iLastid = mng_get_uint16 (pRawdata+2);
  4344. ((mng_movep)*ppChunk)->iMovetype = *(pRawdata+4);
  4345. ((mng_movep)*ppChunk)->iMovex = mng_get_int32 (pRawdata+5);
  4346. ((mng_movep)*ppChunk)->iMovey = mng_get_int32 (pRawdata+9);
  4347. }
  4348. #endif /* MNG_STORE_CHUNKS */
  4349. #ifdef MNG_SUPPORT_TRACE
  4350. MNG_TRACE (pData, MNG_FN_READ_MOVE, MNG_LC_END);
  4351. #endif
  4352. return MNG_NOERROR; /* done */
  4353. }
  4354. #endif
  4355. #endif
  4356. /* ************************************************************************** */
  4357. #ifndef MNG_OPTIMIZE_CHUNKREADER
  4358. #ifndef MNG_SKIPCHUNK_CLIP
  4359. READ_CHUNK (mng_read_clip)
  4360. {
  4361. #ifdef MNG_SUPPORT_TRACE
  4362. MNG_TRACE (pData, MNG_FN_READ_CLIP, MNG_LC_START);
  4363. #endif
  4364. if (!pData->bHasMHDR) /* sequence checks */
  4365. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4366. #ifdef MNG_INCLUDE_JNG
  4367. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  4368. #else
  4369. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  4370. #endif
  4371. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4372. if (iRawlen != 21) /* check the length */
  4373. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  4374. #ifdef MNG_SUPPORT_DISPLAY
  4375. {
  4376. mng_retcode iRetcode;
  4377. /* create a CLIP animation object */
  4378. iRetcode = mng_create_ani_clip (pData, mng_get_uint16 (pRawdata),
  4379. mng_get_uint16 (pRawdata+2),
  4380. *(pRawdata+4),
  4381. mng_get_int32 (pRawdata+5),
  4382. mng_get_int32 (pRawdata+9),
  4383. mng_get_int32 (pRawdata+13),
  4384. mng_get_int32 (pRawdata+17));
  4385. /* if (!iRetcode)
  4386. iRetcode = mng_process_display_clip (pData,
  4387. mng_get_uint16 (pRawdata),
  4388. mng_get_uint16 (pRawdata+2),
  4389. *(pRawdata+4),
  4390. mng_get_int32 (pRawdata+5),
  4391. mng_get_int32 (pRawdata+9),
  4392. mng_get_int32 (pRawdata+13),
  4393. mng_get_int32 (pRawdata+17)); */
  4394. if (iRetcode) /* on error bail out */
  4395. return iRetcode;
  4396. }
  4397. #endif /* MNG_SUPPORT_DISPLAY */
  4398. #ifdef MNG_STORE_CHUNKS
  4399. if (pData->bStorechunks)
  4400. { /* initialize storage */
  4401. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  4402. if (iRetcode) /* on error bail out */
  4403. return iRetcode;
  4404. /* store the fields */
  4405. ((mng_clipp)*ppChunk)->iFirstid = mng_get_uint16 (pRawdata);
  4406. ((mng_clipp)*ppChunk)->iLastid = mng_get_uint16 (pRawdata+2);
  4407. ((mng_clipp)*ppChunk)->iCliptype = *(pRawdata+4);
  4408. ((mng_clipp)*ppChunk)->iClipl = mng_get_int32 (pRawdata+5);
  4409. ((mng_clipp)*ppChunk)->iClipr = mng_get_int32 (pRawdata+9);
  4410. ((mng_clipp)*ppChunk)->iClipt = mng_get_int32 (pRawdata+13);
  4411. ((mng_clipp)*ppChunk)->iClipb = mng_get_int32 (pRawdata+17);
  4412. }
  4413. #endif /* MNG_STORE_CHUNKS */
  4414. #ifdef MNG_SUPPORT_TRACE
  4415. MNG_TRACE (pData, MNG_FN_READ_CLIP, MNG_LC_END);
  4416. #endif
  4417. return MNG_NOERROR; /* done */
  4418. }
  4419. #endif
  4420. #endif
  4421. /* ************************************************************************** */
  4422. #ifndef MNG_OPTIMIZE_CHUNKREADER
  4423. #ifndef MNG_SKIPCHUNK_SHOW
  4424. READ_CHUNK (mng_read_show)
  4425. {
  4426. #ifdef MNG_SUPPORT_TRACE
  4427. MNG_TRACE (pData, MNG_FN_READ_SHOW, MNG_LC_START);
  4428. #endif
  4429. if (!pData->bHasMHDR) /* sequence checks */
  4430. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4431. #ifdef MNG_INCLUDE_JNG
  4432. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  4433. #else
  4434. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  4435. #endif
  4436. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4437. /* check the length */
  4438. if ((iRawlen != 0) && (iRawlen != 2) && (iRawlen != 4) && (iRawlen != 5))
  4439. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  4440. #ifdef MNG_SUPPORT_DISPLAY
  4441. {
  4442. mng_retcode iRetcode;
  4443. if (iRawlen) /* determine parameters if any */
  4444. {
  4445. pData->iSHOWfromid = mng_get_uint16 (pRawdata);
  4446. if (iRawlen > 2)
  4447. pData->iSHOWtoid = mng_get_uint16 (pRawdata+2);
  4448. else
  4449. pData->iSHOWtoid = pData->iSHOWfromid;
  4450. if (iRawlen > 4)
  4451. pData->iSHOWmode = *(pRawdata+4);
  4452. else
  4453. pData->iSHOWmode = 0;
  4454. }
  4455. else /* use defaults then */
  4456. {
  4457. pData->iSHOWmode = 2;
  4458. pData->iSHOWfromid = 1;
  4459. pData->iSHOWtoid = 65535;
  4460. }
  4461. /* create a SHOW animation object */
  4462. iRetcode = mng_create_ani_show (pData, pData->iSHOWfromid,
  4463. pData->iSHOWtoid, pData->iSHOWmode);
  4464. if (!iRetcode)
  4465. iRetcode = mng_process_display_show (pData);
  4466. if (iRetcode) /* on error bail out */
  4467. return iRetcode;
  4468. }
  4469. #endif /* MNG_SUPPORT_DISPLAY */
  4470. #ifdef MNG_STORE_CHUNKS
  4471. if (pData->bStorechunks)
  4472. { /* initialize storage */
  4473. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  4474. if (iRetcode) /* on error bail out */
  4475. return iRetcode;
  4476. /* store the fields */
  4477. ((mng_showp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  4478. if (iRawlen)
  4479. {
  4480. ((mng_showp)*ppChunk)->iFirstid = mng_get_uint16 (pRawdata);
  4481. if (iRawlen > 2)
  4482. ((mng_showp)*ppChunk)->iLastid = mng_get_uint16 (pRawdata+2);
  4483. else
  4484. ((mng_showp)*ppChunk)->iLastid = ((mng_showp)*ppChunk)->iFirstid;
  4485. if (iRawlen > 4)
  4486. ((mng_showp)*ppChunk)->iMode = *(pRawdata+4);
  4487. }
  4488. }
  4489. #endif /* MNG_STORE_CHUNKS */
  4490. #ifdef MNG_SUPPORT_TRACE
  4491. MNG_TRACE (pData, MNG_FN_READ_SHOW, MNG_LC_END);
  4492. #endif
  4493. return MNG_NOERROR; /* done */
  4494. }
  4495. #endif
  4496. #endif
  4497. /* ************************************************************************** */
  4498. #ifndef MNG_OPTIMIZE_CHUNKREADER
  4499. #ifndef MNG_SKIPCHUNK_TERM
  4500. READ_CHUNK (mng_read_term)
  4501. {
  4502. mng_uint8 iTermaction;
  4503. mng_uint8 iIteraction = 0;
  4504. mng_uint32 iDelay = 0;
  4505. mng_uint32 iItermax = 0;
  4506. #ifdef MNG_SUPPORT_TRACE
  4507. MNG_TRACE (pData, MNG_FN_READ_TERM, MNG_LC_START);
  4508. #endif
  4509. if (!pData->bHasMHDR) /* sequence checks */
  4510. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4511. #ifdef MNG_INCLUDE_JNG
  4512. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  4513. #else
  4514. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  4515. #endif
  4516. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4517. /* should be behind MHDR or SAVE !! */
  4518. if ((!pData->bHasSAVE) && (pData->iChunkseq > 2))
  4519. {
  4520. pData->bMisplacedTERM = MNG_TRUE; /* indicate we found a misplaced TERM */
  4521. /* and send a warning signal!!! */
  4522. MNG_WARNING (pData, MNG_SEQUENCEERROR);
  4523. }
  4524. if (pData->bHasLOOP) /* no way, jose! */
  4525. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4526. if (pData->bHasTERM) /* only 1 allowed! */
  4527. MNG_ERROR (pData, MNG_MULTIPLEERROR);
  4528. /* check the length */
  4529. if ((iRawlen != 1) && (iRawlen != 10))
  4530. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  4531. pData->bHasTERM = MNG_TRUE;
  4532. iTermaction = *pRawdata; /* get the fields */
  4533. if (iRawlen > 1)
  4534. {
  4535. iIteraction = *(pRawdata+1);
  4536. iDelay = mng_get_uint32 (pRawdata+2);
  4537. iItermax = mng_get_uint32 (pRawdata+6);
  4538. }
  4539. if (pData->fProcessterm) /* inform the app ? */
  4540. if (!pData->fProcessterm (((mng_handle)pData), iTermaction, iIteraction,
  4541. iDelay, iItermax))
  4542. MNG_ERROR (pData, MNG_APPMISCERROR);
  4543. #ifdef MNG_SUPPORT_DISPLAY
  4544. { /* create the TERM ani-object */
  4545. mng_retcode iRetcode = mng_create_ani_term (pData, iTermaction, iIteraction,
  4546. iDelay, iItermax);
  4547. if (iRetcode) /* on error bail out */
  4548. return iRetcode;
  4549. /* save for future reference */
  4550. pData->pTermaniobj = pData->pLastaniobj;
  4551. }
  4552. #endif /* MNG_SUPPORT_DISPLAY */
  4553. #ifdef MNG_STORE_CHUNKS
  4554. if (pData->bStorechunks)
  4555. { /* initialize storage */
  4556. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  4557. if (iRetcode) /* on error bail out */
  4558. return iRetcode;
  4559. /* store the fields */
  4560. ((mng_termp)*ppChunk)->iTermaction = iTermaction;
  4561. ((mng_termp)*ppChunk)->iIteraction = iIteraction;
  4562. ((mng_termp)*ppChunk)->iDelay = iDelay;
  4563. ((mng_termp)*ppChunk)->iItermax = iItermax;
  4564. }
  4565. #endif /* MNG_STORE_CHUNKS */
  4566. #ifdef MNG_SUPPORT_TRACE
  4567. MNG_TRACE (pData, MNG_FN_READ_TERM, MNG_LC_END);
  4568. #endif
  4569. return MNG_NOERROR; /* done */
  4570. }
  4571. #endif
  4572. #endif
  4573. /* ************************************************************************** */
  4574. #ifndef MNG_OPTIMIZE_CHUNKREADER
  4575. #ifndef MNG_SKIPCHUNK_SAVE
  4576. READ_CHUNK (mng_read_save)
  4577. {
  4578. #ifdef MNG_SUPPORT_TRACE
  4579. MNG_TRACE (pData, MNG_FN_READ_SAVE, MNG_LC_START);
  4580. #endif
  4581. /* sequence checks */
  4582. if ((!pData->bHasMHDR) || (pData->bHasSAVE))
  4583. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4584. #ifdef MNG_INCLUDE_JNG
  4585. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  4586. #else
  4587. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  4588. #endif
  4589. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4590. pData->bHasSAVE = MNG_TRUE;
  4591. if (pData->fProcesssave) /* inform the application ? */
  4592. {
  4593. mng_bool bOke = pData->fProcesssave ((mng_handle)pData);
  4594. if (!bOke)
  4595. MNG_ERROR (pData, MNG_APPMISCERROR);
  4596. }
  4597. #ifdef MNG_SUPPORT_DISPLAY
  4598. {
  4599. mng_retcode iRetcode;
  4600. /* TODO: something with the parameters */
  4601. /* create a SAVE animation object */
  4602. iRetcode = mng_create_ani_save (pData);
  4603. if (!iRetcode)
  4604. iRetcode = mng_process_display_save (pData);
  4605. if (iRetcode) /* on error bail out */
  4606. return iRetcode;
  4607. }
  4608. #endif /* MNG_SUPPORT_DISPLAY */
  4609. #ifdef MNG_STORE_CHUNKS
  4610. if (pData->bStorechunks)
  4611. { /* initialize storage */
  4612. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  4613. if (iRetcode) /* on error bail out */
  4614. return iRetcode;
  4615. /* store the fields */
  4616. ((mng_savep)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  4617. if (iRawlen) /* not empty ? */
  4618. {
  4619. mng_uint8 iOtype = *pRawdata;
  4620. mng_uint8 iEtype;
  4621. mng_uint32 iCount = 0;
  4622. mng_uint8p pTemp;
  4623. mng_uint8p pNull;
  4624. mng_uint32 iLen;
  4625. mng_uint32 iOffset[2];
  4626. mng_uint32 iStarttime[2];
  4627. mng_uint32 iFramenr;
  4628. mng_uint32 iLayernr;
  4629. mng_uint32 iX;
  4630. mng_save_entryp pEntry = MNG_NULL;
  4631. mng_uint32 iNamesize;
  4632. if ((iOtype != 4) && (iOtype != 8))
  4633. MNG_ERROR (pData, MNG_INVOFFSETSIZE);
  4634. ((mng_savep)*ppChunk)->iOffsettype = iOtype;
  4635. for (iX = 0; iX < 2; iX++) /* do this twice to get the count first ! */
  4636. {
  4637. pTemp = pRawdata + 1;
  4638. iLen = iRawlen - 1;
  4639. if (iX) /* second run ? */
  4640. {
  4641. MNG_ALLOC (pData, pEntry, (iCount * sizeof (mng_save_entry)));
  4642. ((mng_savep)*ppChunk)->iCount = iCount;
  4643. ((mng_savep)*ppChunk)->pEntries = pEntry;
  4644. }
  4645. while (iLen) /* anything left ? */
  4646. {
  4647. iEtype = *pTemp; /* entrytype */
  4648. if ((iEtype != 0) && (iEtype != 1) && (iEtype != 2) && (iEtype != 3))
  4649. MNG_ERROR (pData, MNG_INVENTRYTYPE);
  4650. pTemp++;
  4651. if (iEtype > 1)
  4652. {
  4653. iOffset [0] = 0;
  4654. iOffset [1] = 0;
  4655. iStarttime [0] = 0;
  4656. iStarttime [1] = 0;
  4657. iLayernr = 0;
  4658. iFramenr = 0;
  4659. }
  4660. else
  4661. {
  4662. if (iOtype == 4)
  4663. {
  4664. iOffset [0] = 0;
  4665. iOffset [1] = mng_get_uint32 (pTemp);
  4666. pTemp += 4;
  4667. }
  4668. else
  4669. {
  4670. iOffset [0] = mng_get_uint32 (pTemp);
  4671. iOffset [1] = mng_get_uint32 (pTemp+4);
  4672. pTemp += 8;
  4673. }
  4674. if (iEtype > 0)
  4675. {
  4676. iStarttime [0] = 0;
  4677. iStarttime [1] = 0;
  4678. iLayernr = 0;
  4679. iFramenr = 0;
  4680. }
  4681. else
  4682. {
  4683. if (iOtype == 4)
  4684. {
  4685. iStarttime [0] = 0;
  4686. iStarttime [1] = mng_get_uint32 (pTemp+0);
  4687. iLayernr = mng_get_uint32 (pTemp+4);
  4688. iFramenr = mng_get_uint32 (pTemp+8);
  4689. pTemp += 12;
  4690. }
  4691. else
  4692. {
  4693. iStarttime [0] = mng_get_uint32 (pTemp+0);
  4694. iStarttime [1] = mng_get_uint32 (pTemp+4);
  4695. iLayernr = mng_get_uint32 (pTemp+8);
  4696. iFramenr = mng_get_uint32 (pTemp+12);
  4697. pTemp += 16;
  4698. }
  4699. }
  4700. }
  4701. pNull = find_null (pTemp); /* get the name length */
  4702. if ((pNull - pRawdata) > (mng_int32)iRawlen)
  4703. {
  4704. iNamesize = iLen; /* no null found; so end of SAVE */
  4705. iLen = 0;
  4706. }
  4707. else
  4708. {
  4709. iNamesize = pNull - pTemp; /* should be another entry */
  4710. iLen -= iNamesize;
  4711. if (!iLen) /* must not end with a null ! */
  4712. MNG_ERROR (pData, MNG_ENDWITHNULL);
  4713. }
  4714. if (!pEntry)
  4715. {
  4716. iCount++;
  4717. }
  4718. else
  4719. {
  4720. pEntry->iEntrytype = iEtype;
  4721. pEntry->iOffset [0] = iOffset [0];
  4722. pEntry->iOffset [1] = iOffset [1];
  4723. pEntry->iStarttime [0] = iStarttime [0];
  4724. pEntry->iStarttime [1] = iStarttime [1];
  4725. pEntry->iLayernr = iLayernr;
  4726. pEntry->iFramenr = iFramenr;
  4727. pEntry->iNamesize = iNamesize;
  4728. if (iNamesize)
  4729. {
  4730. MNG_ALLOC (pData, pEntry->zName, iNamesize+1);
  4731. MNG_COPY (pEntry->zName, pTemp, iNamesize);
  4732. }
  4733. pEntry++;
  4734. }
  4735. pTemp += iNamesize;
  4736. }
  4737. }
  4738. }
  4739. }
  4740. #endif /* MNG_STORE_CHUNKS */
  4741. #ifdef MNG_SUPPORT_TRACE
  4742. MNG_TRACE (pData, MNG_FN_READ_SAVE, MNG_LC_END);
  4743. #endif
  4744. return MNG_NOERROR; /* done */
  4745. }
  4746. #endif
  4747. #endif
  4748. /* ************************************************************************** */
  4749. #ifndef MNG_OPTIMIZE_CHUNKREADER
  4750. #ifndef MNG_SKIPCHUNK_SEEK
  4751. READ_CHUNK (mng_read_seek)
  4752. {
  4753. mng_retcode iRetcode;
  4754. #ifdef MNG_SUPPORT_TRACE
  4755. MNG_TRACE (pData, MNG_FN_READ_SEEK, MNG_LC_START);
  4756. #endif
  4757. /* sequence checks */
  4758. if ((!pData->bHasMHDR) || (!pData->bHasSAVE))
  4759. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4760. #ifdef MNG_INCLUDE_JNG
  4761. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  4762. #else
  4763. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  4764. #endif
  4765. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4766. #ifdef MNG_SUPPORT_DISPLAY
  4767. /* create a SEEK animation object */
  4768. iRetcode = mng_create_ani_seek (pData, iRawlen, (mng_pchar)pRawdata);
  4769. if (iRetcode) /* on error bail out */
  4770. return iRetcode;
  4771. #endif /* MNG_SUPPORT_DISPLAY */
  4772. if (pData->fProcessseek) /* inform the app ? */
  4773. {
  4774. mng_bool bOke;
  4775. mng_pchar zName;
  4776. MNG_ALLOC (pData, zName, iRawlen + 1);
  4777. if (iRawlen)
  4778. MNG_COPY (zName, pRawdata, iRawlen);
  4779. bOke = pData->fProcessseek ((mng_handle)pData, zName);
  4780. MNG_FREEX (pData, zName, iRawlen + 1);
  4781. if (!bOke)
  4782. MNG_ERROR (pData, MNG_APPMISCERROR);
  4783. }
  4784. #ifdef MNG_SUPPORT_DISPLAY
  4785. /* do display processing of the SEEK */
  4786. iRetcode = mng_process_display_seek (pData);
  4787. if (iRetcode) /* on error bail out */
  4788. return iRetcode;
  4789. #endif /* MNG_SUPPORT_DISPLAY */
  4790. #ifdef MNG_STORE_CHUNKS
  4791. if (pData->bStorechunks)
  4792. { /* initialize storage */
  4793. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  4794. if (iRetcode) /* on error bail out */
  4795. return iRetcode;
  4796. /* store the fields */
  4797. ((mng_seekp)*ppChunk)->iNamesize = iRawlen;
  4798. if (iRawlen)
  4799. {
  4800. MNG_ALLOC (pData, ((mng_seekp)*ppChunk)->zName, iRawlen+1);
  4801. MNG_COPY (((mng_seekp)*ppChunk)->zName, pRawdata, iRawlen);
  4802. }
  4803. }
  4804. #endif /* MNG_STORE_CHUNKS */
  4805. #ifdef MNG_SUPPORT_TRACE
  4806. MNG_TRACE (pData, MNG_FN_READ_SEEK, MNG_LC_END);
  4807. #endif
  4808. return MNG_NOERROR; /* done */
  4809. }
  4810. #endif
  4811. #endif
  4812. /* ************************************************************************** */
  4813. #ifndef MNG_OPTIMIZE_CHUNKREADER
  4814. #ifndef MNG_SKIPCHUNK_eXPI
  4815. READ_CHUNK (mng_read_expi)
  4816. {
  4817. #ifdef MNG_SUPPORT_TRACE
  4818. MNG_TRACE (pData, MNG_FN_READ_EXPI, MNG_LC_START);
  4819. #endif
  4820. if (!pData->bHasMHDR) /* sequence checks */
  4821. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4822. #ifdef MNG_INCLUDE_JNG
  4823. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  4824. #else
  4825. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  4826. #endif
  4827. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4828. if (iRawlen < 3) /* check the length */
  4829. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  4830. #ifdef MNG_SUPPORT_DISPLAY
  4831. {
  4832. /* TODO: something !!! */
  4833. }
  4834. #endif /* MNG_SUPPORT_DISPLAY */
  4835. #ifdef MNG_STORE_CHUNKS
  4836. if (pData->bStorechunks)
  4837. { /* initialize storage */
  4838. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  4839. if (iRetcode) /* on error bail out */
  4840. return iRetcode;
  4841. /* store the fields */
  4842. ((mng_expip)*ppChunk)->iSnapshotid = mng_get_uint16 (pRawdata);
  4843. ((mng_expip)*ppChunk)->iNamesize = iRawlen - 2;
  4844. if (((mng_expip)*ppChunk)->iNamesize)
  4845. {
  4846. MNG_ALLOC (pData, ((mng_expip)*ppChunk)->zName,
  4847. ((mng_expip)*ppChunk)->iNamesize + 1);
  4848. MNG_COPY (((mng_expip)*ppChunk)->zName, pRawdata+2,
  4849. ((mng_expip)*ppChunk)->iNamesize);
  4850. }
  4851. }
  4852. #endif /* MNG_STORE_CHUNKS */
  4853. #ifdef MNG_SUPPORT_TRACE
  4854. MNG_TRACE (pData, MNG_FN_READ_EXPI, MNG_LC_END);
  4855. #endif
  4856. return MNG_NOERROR; /* done */
  4857. }
  4858. #endif
  4859. #endif
  4860. /* ************************************************************************** */
  4861. #ifndef MNG_OPTIMIZE_CHUNKREADER
  4862. #ifndef MNG_SKIPCHUNK_fPRI
  4863. READ_CHUNK (mng_read_fpri)
  4864. {
  4865. #ifdef MNG_SUPPORT_TRACE
  4866. MNG_TRACE (pData, MNG_FN_READ_FPRI, MNG_LC_START);
  4867. #endif
  4868. if (!pData->bHasMHDR) /* sequence checks */
  4869. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4870. #ifdef MNG_INCLUDE_JNG
  4871. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  4872. #else
  4873. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  4874. #endif
  4875. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  4876. if (iRawlen != 2) /* must be two bytes long */
  4877. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  4878. #ifdef MNG_SUPPORT_DISPLAY
  4879. {
  4880. /* TODO: something !!! */
  4881. }
  4882. #endif /* MNG_SUPPORT_DISPLAY */
  4883. #ifdef MNG_STORE_CHUNKS
  4884. if (pData->bStorechunks)
  4885. { /* initialize storage */
  4886. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  4887. if (iRetcode) /* on error bail out */
  4888. return iRetcode;
  4889. /* store the fields */
  4890. ((mng_fprip)*ppChunk)->iDeltatype = *pRawdata;
  4891. ((mng_fprip)*ppChunk)->iPriority = *(pRawdata+1);
  4892. }
  4893. #endif /* MNG_STORE_CHUNKS */
  4894. #ifdef MNG_SUPPORT_TRACE
  4895. MNG_TRACE (pData, MNG_FN_READ_FPRI, MNG_LC_END);
  4896. #endif
  4897. return MNG_NOERROR; /* done */
  4898. }
  4899. #endif
  4900. #endif
  4901. /* ************************************************************************** */
  4902. #ifndef MNG_OPTIMIZE_CHUNKREADER
  4903. #ifndef MNG_SKIPCHUNK_nEED
  4904. MNG_LOCAL mng_bool CheckKeyword (mng_datap pData,
  4905. mng_uint8p pKeyword)
  4906. {
  4907. mng_chunkid handled_chunks [] =
  4908. {
  4909. MNG_UINT_BACK, /* keep it sorted !!!! */
  4910. MNG_UINT_BASI,
  4911. MNG_UINT_CLIP,
  4912. MNG_UINT_CLON,
  4913. #ifndef MNG_NO_DELTA_PNG
  4914. /* TODO: MNG_UINT_DBYK, */
  4915. #endif
  4916. MNG_UINT_DEFI,
  4917. #ifndef MNG_NO_DELTA_PNG
  4918. MNG_UINT_DHDR,
  4919. #endif
  4920. MNG_UINT_DISC,
  4921. #ifndef MNG_NO_DELTA_PNG
  4922. /* TODO: MNG_UINT_DROP, */
  4923. #endif
  4924. MNG_UINT_ENDL,
  4925. MNG_UINT_FRAM,
  4926. MNG_UINT_IDAT,
  4927. MNG_UINT_IEND,
  4928. MNG_UINT_IHDR,
  4929. #ifndef MNG_NO_DELTA_PNG
  4930. #ifdef MNG_INCLUDE_JNG
  4931. MNG_UINT_IJNG,
  4932. #endif
  4933. MNG_UINT_IPNG,
  4934. #endif
  4935. #ifdef MNG_INCLUDE_JNG
  4936. MNG_UINT_JDAA,
  4937. MNG_UINT_JDAT,
  4938. MNG_UINT_JHDR,
  4939. /* TODO: MNG_UINT_JSEP, */
  4940. MNG_UINT_JdAA,
  4941. #endif
  4942. MNG_UINT_LOOP,
  4943. MNG_UINT_MAGN,
  4944. MNG_UINT_MEND,
  4945. MNG_UINT_MHDR,
  4946. MNG_UINT_MOVE,
  4947. /* TODO: MNG_UINT_ORDR, */
  4948. MNG_UINT_PAST,
  4949. MNG_UINT_PLTE,
  4950. #ifndef MNG_NO_DELTA_PNG
  4951. MNG_UINT_PPLT,
  4952. MNG_UINT_PROM,
  4953. #endif
  4954. MNG_UINT_SAVE,
  4955. MNG_UINT_SEEK,
  4956. MNG_UINT_SHOW,
  4957. MNG_UINT_TERM,
  4958. #ifdef MNG_INCLUDE_ANG_PROPOSAL
  4959. MNG_UINT_adAT,
  4960. MNG_UINT_ahDR,
  4961. #endif
  4962. MNG_UINT_bKGD,
  4963. MNG_UINT_cHRM,
  4964. /* TODO: MNG_UINT_eXPI, */
  4965. MNG_UINT_evNT,
  4966. /* TODO: MNG_UINT_fPRI, */
  4967. MNG_UINT_gAMA,
  4968. /* TODO: MNG_UINT_hIST, */
  4969. MNG_UINT_iCCP,
  4970. MNG_UINT_iTXt,
  4971. #ifdef MNG_INCLUDE_MPNG_PROPOSAL
  4972. MNG_UINT_mpNG,
  4973. #endif
  4974. MNG_UINT_nEED,
  4975. /* TODO: MNG_UINT_oFFs, */
  4976. /* TODO: MNG_UINT_pCAL, */
  4977. /* TODO: MNG_UINT_pHYg, */
  4978. /* TODO: MNG_UINT_pHYs, */
  4979. /* TODO: MNG_UINT_sBIT, */
  4980. /* TODO: MNG_UINT_sCAL, */
  4981. /* TODO: MNG_UINT_sPLT, */
  4982. MNG_UINT_sRGB,
  4983. MNG_UINT_tEXt,
  4984. MNG_UINT_tIME,
  4985. MNG_UINT_tRNS,
  4986. MNG_UINT_zTXt,
  4987. };
  4988. mng_bool bOke = MNG_FALSE;
  4989. if (pData->fProcessneed) /* does the app handle it ? */
  4990. bOke = pData->fProcessneed ((mng_handle)pData, (mng_pchar)pKeyword);
  4991. if (!bOke)
  4992. { /* find the keyword length */
  4993. mng_uint8p pNull = find_null (pKeyword);
  4994. if (pNull - pKeyword == 4) /* test a chunk ? */
  4995. { /* get the chunk-id */
  4996. mng_chunkid iChunkid = (*pKeyword << 24) + (*(pKeyword+1) << 16) +
  4997. (*(pKeyword+2) << 8) + (*(pKeyword+3) );
  4998. /* binary search variables */
  4999. mng_int32 iTop, iLower, iUpper, iMiddle;
  5000. /* determine max index of table */
  5001. iTop = (sizeof (handled_chunks) / sizeof (handled_chunks [0])) - 1;
  5002. /* binary search; with 52 chunks, worst-case is 7 comparisons */
  5003. iLower = 0;
  5004. iMiddle = iTop >> 1;
  5005. iUpper = iTop;
  5006. do /* the binary search itself */
  5007. {
  5008. if (handled_chunks [iMiddle] < iChunkid)
  5009. iLower = iMiddle + 1;
  5010. else if (handled_chunks [iMiddle] > iChunkid)
  5011. iUpper = iMiddle - 1;
  5012. else
  5013. {
  5014. bOke = MNG_TRUE;
  5015. break;
  5016. }
  5017. iMiddle = (iLower + iUpper) >> 1;
  5018. }
  5019. while (iLower <= iUpper);
  5020. }
  5021. /* test draft ? */
  5022. if ((!bOke) && (pNull - pKeyword == 8) &&
  5023. (*pKeyword == 'd') && (*(pKeyword+1) == 'r') &&
  5024. (*(pKeyword+2) == 'a') && (*(pKeyword+3) == 'f') &&
  5025. (*(pKeyword+4) == 't') && (*(pKeyword+5) == ' '))
  5026. {
  5027. mng_uint32 iDraft;
  5028. iDraft = (*(pKeyword+6) - '0') * 10 + (*(pKeyword+7) - '0');
  5029. bOke = (mng_bool)(iDraft <= MNG_MNG_DRAFT);
  5030. }
  5031. /* test MNG 1.0/1.1 ? */
  5032. if ((!bOke) && (pNull - pKeyword == 7) &&
  5033. (*pKeyword == 'M') && (*(pKeyword+1) == 'N') &&
  5034. (*(pKeyword+2) == 'G') && (*(pKeyword+3) == '-') &&
  5035. (*(pKeyword+4) == '1') && (*(pKeyword+5) == '.') &&
  5036. ((*(pKeyword+6) == '0') || (*(pKeyword+6) == '1')))
  5037. bOke = MNG_TRUE;
  5038. /* test CACHEOFF ? */
  5039. if ((!bOke) && (pNull - pKeyword == 8) &&
  5040. (*pKeyword == 'C') && (*(pKeyword+1) == 'A') &&
  5041. (*(pKeyword+2) == 'C') && (*(pKeyword+3) == 'H') &&
  5042. (*(pKeyword+4) == 'E') && (*(pKeyword+5) == 'O') &&
  5043. (*(pKeyword+6) == 'F') && (*(pKeyword+7) == 'F'))
  5044. {
  5045. if (!pData->pFirstaniobj) /* only if caching hasn't started yet ! */
  5046. {
  5047. bOke = MNG_TRUE;
  5048. pData->bCacheplayback = MNG_FALSE;
  5049. pData->bStorechunks = MNG_FALSE;
  5050. }
  5051. }
  5052. }
  5053. return bOke;
  5054. }
  5055. #endif
  5056. #endif
  5057. /* ************************************************************************** */
  5058. #ifndef MNG_OPTIMIZE_CHUNKREADER
  5059. #ifndef MNG_SKIPCHUNK_nEED
  5060. READ_CHUNK (mng_read_need)
  5061. {
  5062. #ifdef MNG_SUPPORT_TRACE
  5063. MNG_TRACE (pData, MNG_FN_READ_NEED, MNG_LC_START);
  5064. #endif
  5065. if (!pData->bHasMHDR) /* sequence checks */
  5066. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5067. #ifdef MNG_INCLUDE_JNG
  5068. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  5069. #else
  5070. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  5071. #endif
  5072. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5073. if (iRawlen < 1) /* check the length */
  5074. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5075. { /* let's check it */
  5076. mng_bool bOke = MNG_TRUE;
  5077. mng_pchar zKeywords;
  5078. mng_uint8p pNull, pTemp;
  5079. MNG_ALLOC (pData, zKeywords, iRawlen + 1);
  5080. if (iRawlen)
  5081. MNG_COPY (zKeywords, pRawdata, iRawlen);
  5082. pTemp = (mng_uint8p)zKeywords;
  5083. pNull = find_null (pTemp);
  5084. while ((bOke) && (pNull < (mng_uint8p)zKeywords + iRawlen))
  5085. {
  5086. bOke = CheckKeyword (pData, pTemp);
  5087. pTemp = pNull + 1;
  5088. pNull = find_null (pTemp);
  5089. }
  5090. if (bOke)
  5091. bOke = CheckKeyword (pData, pTemp);
  5092. MNG_FREEX (pData, zKeywords, iRawlen + 1);
  5093. if (!bOke)
  5094. MNG_ERROR (pData, MNG_UNSUPPORTEDNEED);
  5095. }
  5096. #ifdef MNG_STORE_CHUNKS
  5097. if (pData->bStorechunks)
  5098. { /* initialize storage */
  5099. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  5100. if (iRetcode) /* on error bail out */
  5101. return iRetcode;
  5102. /* store the fields */
  5103. ((mng_needp)*ppChunk)->iKeywordssize = iRawlen;
  5104. if (iRawlen)
  5105. {
  5106. MNG_ALLOC (pData, ((mng_needp)*ppChunk)->zKeywords, iRawlen+1);
  5107. MNG_COPY (((mng_needp)*ppChunk)->zKeywords, pRawdata, iRawlen);
  5108. }
  5109. }
  5110. #endif /* MNG_STORE_CHUNKS */
  5111. #ifdef MNG_SUPPORT_TRACE
  5112. MNG_TRACE (pData, MNG_FN_READ_NEED, MNG_LC_END);
  5113. #endif
  5114. return MNG_NOERROR; /* done */
  5115. }
  5116. #endif
  5117. #endif
  5118. /* ************************************************************************** */
  5119. #ifndef MNG_OPTIMIZE_CHUNKREADER
  5120. #ifndef MNG_SKIPCHUNK_pHYg
  5121. READ_CHUNK (mng_read_phyg)
  5122. {
  5123. #ifdef MNG_SUPPORT_TRACE
  5124. MNG_TRACE (pData, MNG_FN_READ_PHYG, MNG_LC_START);
  5125. #endif
  5126. if (!pData->bHasMHDR) /* sequence checks */
  5127. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5128. #ifdef MNG_INCLUDE_JNG
  5129. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  5130. #else
  5131. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  5132. #endif
  5133. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5134. /* it's 9 bytes or empty; no more, no less! */
  5135. if ((iRawlen != 9) && (iRawlen != 0))
  5136. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5137. #ifdef MNG_SUPPORT_DISPLAY
  5138. {
  5139. /* TODO: something !!! */
  5140. }
  5141. #endif /* MNG_SUPPORT_DISPLAY */
  5142. #ifdef MNG_STORE_CHUNKS
  5143. if (pData->bStorechunks)
  5144. { /* initialize storage */
  5145. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  5146. if (iRetcode) /* on error bail out */
  5147. return iRetcode;
  5148. /* store the fields */
  5149. ((mng_phygp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  5150. if (iRawlen)
  5151. {
  5152. ((mng_phygp)*ppChunk)->iSizex = mng_get_uint32 (pRawdata);
  5153. ((mng_phygp)*ppChunk)->iSizey = mng_get_uint32 (pRawdata+4);
  5154. ((mng_phygp)*ppChunk)->iUnit = *(pRawdata+8);
  5155. }
  5156. }
  5157. #endif /* MNG_STORE_CHUNKS */
  5158. #ifdef MNG_SUPPORT_TRACE
  5159. MNG_TRACE (pData, MNG_FN_READ_PHYG, MNG_LC_END);
  5160. #endif
  5161. return MNG_NOERROR; /* done */
  5162. }
  5163. #endif
  5164. #endif
  5165. /* ************************************************************************** */
  5166. #ifndef MNG_OPTIMIZE_CHUNKREADER
  5167. #ifdef MNG_INCLUDE_JNG
  5168. READ_CHUNK (mng_read_jhdr)
  5169. {
  5170. #ifdef MNG_SUPPORT_TRACE
  5171. MNG_TRACE (pData, MNG_FN_READ_JHDR, MNG_LC_START);
  5172. #endif
  5173. /* sequence checks */
  5174. if ((pData->eSigtype != mng_it_jng) && (pData->eSigtype != mng_it_mng))
  5175. MNG_ERROR (pData, MNG_CHUNKNOTALLOWED);
  5176. if ((pData->eSigtype == mng_it_jng) && (pData->iChunkseq > 1))
  5177. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5178. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  5179. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5180. if (iRawlen != 16) /* length oke ? */
  5181. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5182. /* inside a JHDR-IEND block now */
  5183. pData->bHasJHDR = MNG_TRUE;
  5184. /* and store interesting fields */
  5185. pData->iDatawidth = mng_get_uint32 (pRawdata);
  5186. pData->iDataheight = mng_get_uint32 (pRawdata+4);
  5187. pData->iJHDRcolortype = *(pRawdata+8);
  5188. pData->iJHDRimgbitdepth = *(pRawdata+9);
  5189. pData->iJHDRimgcompression = *(pRawdata+10);
  5190. pData->iJHDRimginterlace = *(pRawdata+11);
  5191. pData->iJHDRalphabitdepth = *(pRawdata+12);
  5192. pData->iJHDRalphacompression = *(pRawdata+13);
  5193. pData->iJHDRalphafilter = *(pRawdata+14);
  5194. pData->iJHDRalphainterlace = *(pRawdata+15);
  5195. #if defined(MNG_NO_1_2_4BIT_SUPPORT) || defined(MNG_NO_16BIT_SUPPORT)
  5196. pData->iPNGmult = 1;
  5197. pData->iPNGdepth = pData->iJHDRalphabitdepth;
  5198. #endif
  5199. #ifdef MNG_NO_1_2_4BIT_SUPPORT
  5200. if (pData->iJHDRalphabitdepth < 8)
  5201. pData->iJHDRalphabitdepth = 8;
  5202. #endif
  5203. #ifdef MNG_NO_16BIT_SUPPORT
  5204. if (pData->iJHDRalphabitdepth > 8)
  5205. {
  5206. pData->iPNGmult = 2;
  5207. pData->iJHDRalphabitdepth = 8;
  5208. }
  5209. #endif
  5210. /* parameter validity checks */
  5211. if ((pData->iJHDRcolortype != MNG_COLORTYPE_JPEGGRAY ) &&
  5212. (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGCOLOR ) &&
  5213. (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGGRAYA ) &&
  5214. (pData->iJHDRcolortype != MNG_COLORTYPE_JPEGCOLORA) )
  5215. MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
  5216. if ((pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG8 ) &&
  5217. (pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG12 ) &&
  5218. (pData->iJHDRimgbitdepth != MNG_BITDEPTH_JPEG8AND12) )
  5219. MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
  5220. if (pData->iJHDRimgcompression != MNG_COMPRESSION_BASELINEJPEG)
  5221. MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
  5222. if ((pData->iJHDRimginterlace != MNG_INTERLACE_SEQUENTIAL ) &&
  5223. (pData->iJHDRimginterlace != MNG_INTERLACE_PROGRESSIVE) )
  5224. MNG_ERROR (pData, MNG_INVALIDINTERLACE);
  5225. if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
  5226. (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) )
  5227. {
  5228. if ((pData->iJHDRalphabitdepth != MNG_BITDEPTH_8 )
  5229. #ifndef MNG_NO_1_2_4BIT_SUPPORT
  5230. && (pData->iJHDRalphabitdepth != MNG_BITDEPTH_1 ) &&
  5231. (pData->iJHDRalphabitdepth != MNG_BITDEPTH_2 ) &&
  5232. (pData->iJHDRalphabitdepth != MNG_BITDEPTH_4 )
  5233. #endif
  5234. #ifndef MNG_NO_16BIT_SUPPORT
  5235. && (pData->iJHDRalphabitdepth != MNG_BITDEPTH_16)
  5236. #endif
  5237. )
  5238. MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
  5239. if ((pData->iJHDRalphacompression != MNG_COMPRESSION_DEFLATE ) &&
  5240. (pData->iJHDRalphacompression != MNG_COMPRESSION_BASELINEJPEG) )
  5241. MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
  5242. if ((pData->iJHDRalphacompression == MNG_COMPRESSION_BASELINEJPEG) &&
  5243. (pData->iJHDRalphabitdepth != MNG_BITDEPTH_8 ) )
  5244. MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
  5245. #if defined(FILTER192) || defined(FILTER193)
  5246. if ((pData->iJHDRalphafilter != MNG_FILTER_ADAPTIVE ) &&
  5247. #if defined(FILTER192) && defined(FILTER193)
  5248. (pData->iJHDRalphafilter != MNG_FILTER_DIFFERING) &&
  5249. (pData->iJHDRalphafilter != MNG_FILTER_NOFILTER ) )
  5250. #else
  5251. #ifdef FILTER192
  5252. (pData->iJHDRalphafilter != MNG_FILTER_DIFFERING) )
  5253. #else
  5254. (pData->iJHDRalphafilter != MNG_FILTER_NOFILTER ) )
  5255. #endif
  5256. #endif
  5257. MNG_ERROR (pData, MNG_INVALIDFILTER);
  5258. #else
  5259. if (pData->iJHDRalphafilter)
  5260. MNG_ERROR (pData, MNG_INVALIDFILTER);
  5261. #endif
  5262. if ((pData->iJHDRalphainterlace != MNG_INTERLACE_NONE ) &&
  5263. (pData->iJHDRalphainterlace != MNG_INTERLACE_ADAM7) )
  5264. MNG_ERROR (pData, MNG_INVALIDINTERLACE);
  5265. }
  5266. else
  5267. {
  5268. if (pData->iJHDRalphabitdepth)
  5269. MNG_ERROR (pData, MNG_INVALIDBITDEPTH);
  5270. if (pData->iJHDRalphacompression)
  5271. MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
  5272. if (pData->iJHDRalphafilter)
  5273. MNG_ERROR (pData, MNG_INVALIDFILTER);
  5274. if (pData->iJHDRalphainterlace)
  5275. MNG_ERROR (pData, MNG_INVALIDINTERLACE);
  5276. }
  5277. if (!pData->bHasheader) /* first chunk ? */
  5278. {
  5279. pData->bHasheader = MNG_TRUE; /* we've got a header */
  5280. pData->eImagetype = mng_it_jng; /* then this must be a JNG */
  5281. pData->iWidth = mng_get_uint32 (pRawdata);
  5282. pData->iHeight = mng_get_uint32 (pRawdata+4);
  5283. /* predict alpha-depth ! */
  5284. if ((pData->iJHDRcolortype == MNG_COLORTYPE_JPEGGRAYA ) ||
  5285. (pData->iJHDRcolortype == MNG_COLORTYPE_JPEGCOLORA) )
  5286. pData->iAlphadepth = pData->iJHDRalphabitdepth;
  5287. else
  5288. pData->iAlphadepth = 0;
  5289. /* fits on maximum canvas ? */
  5290. if ((pData->iWidth > pData->iMaxwidth) || (pData->iHeight > pData->iMaxheight))
  5291. MNG_WARNING (pData, MNG_IMAGETOOLARGE);
  5292. if (pData->fProcessheader) /* inform the app ? */
  5293. if (!pData->fProcessheader (((mng_handle)pData), pData->iWidth, pData->iHeight))
  5294. MNG_ERROR (pData, MNG_APPMISCERROR);
  5295. }
  5296. pData->iColortype = 0; /* fake grayscale for other routines */
  5297. pData->iImagelevel++; /* one level deeper */
  5298. #ifdef MNG_SUPPORT_DISPLAY
  5299. {
  5300. mng_retcode iRetcode = mng_process_display_jhdr (pData);
  5301. if (iRetcode) /* on error bail out */
  5302. return iRetcode;
  5303. }
  5304. #endif /* MNG_SUPPORT_DISPLAY */
  5305. #ifdef MNG_STORE_CHUNKS
  5306. if (pData->bStorechunks)
  5307. { /* initialize storage */
  5308. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  5309. if (iRetcode) /* on error bail out */
  5310. return iRetcode;
  5311. /* store the fields */
  5312. ((mng_jhdrp)*ppChunk)->iWidth = mng_get_uint32 (pRawdata);
  5313. ((mng_jhdrp)*ppChunk)->iHeight = mng_get_uint32 (pRawdata+4);
  5314. ((mng_jhdrp)*ppChunk)->iColortype = *(pRawdata+8);
  5315. ((mng_jhdrp)*ppChunk)->iImagesampledepth = *(pRawdata+9);
  5316. ((mng_jhdrp)*ppChunk)->iImagecompression = *(pRawdata+10);
  5317. ((mng_jhdrp)*ppChunk)->iImageinterlace = *(pRawdata+11);
  5318. ((mng_jhdrp)*ppChunk)->iAlphasampledepth = *(pRawdata+12);
  5319. #ifdef MNG_NO_16BIT_SUPPORT
  5320. if (*(pRawdata+12) > 8)
  5321. ((mng_jhdrp)*ppChunk)->iAlphasampledepth = 8;
  5322. #endif
  5323. ((mng_jhdrp)*ppChunk)->iAlphacompression = *(pRawdata+13);
  5324. ((mng_jhdrp)*ppChunk)->iAlphafilter = *(pRawdata+14);
  5325. ((mng_jhdrp)*ppChunk)->iAlphainterlace = *(pRawdata+15);
  5326. }
  5327. #endif /* MNG_STORE_CHUNKS */
  5328. #ifdef MNG_SUPPORT_TRACE
  5329. MNG_TRACE (pData, MNG_FN_READ_JHDR, MNG_LC_END);
  5330. #endif
  5331. return MNG_NOERROR; /* done */
  5332. }
  5333. #else
  5334. #define read_jhdr 0
  5335. #endif /* MNG_INCLUDE_JNG */
  5336. #endif
  5337. /* ************************************************************************** */
  5338. #ifndef MNG_OPTIMIZE_CHUNKREADER
  5339. #ifdef MNG_INCLUDE_JNG
  5340. READ_CHUNK (mng_read_jdaa)
  5341. {
  5342. #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
  5343. volatile mng_retcode iRetcode;
  5344. iRetcode=MNG_NOERROR;
  5345. #endif
  5346. #ifdef MNG_SUPPORT_TRACE
  5347. MNG_TRACE (pData, MNG_FN_READ_JDAA, MNG_LC_START);
  5348. #endif
  5349. /* sequence checks */
  5350. if ((!pData->bHasJHDR) && (!pData->bHasDHDR))
  5351. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5352. if (pData->bHasJSEP)
  5353. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5354. if (pData->iJHDRalphacompression != MNG_COMPRESSION_BASELINEJPEG)
  5355. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5356. if (iRawlen == 0) /* can never be empty */
  5357. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5358. pData->bHasJDAA = MNG_TRUE; /* got some JDAA now, don't we */
  5359. #ifdef MNG_SUPPORT_DISPLAY
  5360. iRetcode = mng_process_display_jdaa (pData, iRawlen, pRawdata);
  5361. if (iRetcode) /* on error bail out */
  5362. return iRetcode;
  5363. #endif /* MNG_SUPPORT_DISPLAY */
  5364. #ifdef MNG_STORE_CHUNKS
  5365. if (pData->bStorechunks)
  5366. { /* initialize storage */
  5367. iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  5368. if (iRetcode) /* on error bail out */
  5369. return iRetcode;
  5370. /* store the fields */
  5371. ((mng_jdaap)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  5372. ((mng_jdaap)*ppChunk)->iDatasize = iRawlen;
  5373. if (iRawlen != 0) /* is there any data ? */
  5374. {
  5375. MNG_ALLOC (pData, ((mng_jdaap)*ppChunk)->pData, iRawlen);
  5376. MNG_COPY (((mng_jdaap)*ppChunk)->pData, pRawdata, iRawlen);
  5377. }
  5378. }
  5379. #endif /* MNG_STORE_CHUNKS */
  5380. #ifdef MNG_SUPPORT_TRACE
  5381. MNG_TRACE (pData, MNG_FN_READ_JDAA, MNG_LC_END);
  5382. #endif
  5383. return MNG_NOERROR; /* done */
  5384. }
  5385. #else
  5386. #define read_jdaa 0
  5387. #endif /* MNG_INCLUDE_JNG */
  5388. #endif
  5389. /* ************************************************************************** */
  5390. #ifndef MNG_OPTIMIZE_CHUNKREADER
  5391. #ifdef MNG_INCLUDE_JNG
  5392. READ_CHUNK (mng_read_jdat)
  5393. {
  5394. #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
  5395. volatile mng_retcode iRetcode;
  5396. iRetcode=MNG_NOERROR;
  5397. #endif
  5398. #ifdef MNG_SUPPORT_TRACE
  5399. MNG_TRACE (pData, MNG_FN_READ_JDAT, MNG_LC_START);
  5400. #endif
  5401. /* sequence checks */
  5402. if ((!pData->bHasJHDR) && (!pData->bHasDHDR))
  5403. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5404. if (iRawlen == 0) /* can never be empty */
  5405. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5406. pData->bHasJDAT = MNG_TRUE; /* got some JDAT now, don't we */
  5407. #ifdef MNG_SUPPORT_DISPLAY
  5408. iRetcode = mng_process_display_jdat (pData, iRawlen, pRawdata);
  5409. if (iRetcode) /* on error bail out */
  5410. return iRetcode;
  5411. #endif /* MNG_SUPPORT_DISPLAY */
  5412. #ifdef MNG_STORE_CHUNKS
  5413. if (pData->bStorechunks)
  5414. { /* initialize storage */
  5415. iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  5416. if (iRetcode) /* on error bail out */
  5417. return iRetcode;
  5418. /* store the fields */
  5419. ((mng_jdatp)*ppChunk)->bEmpty = (mng_bool)(iRawlen == 0);
  5420. ((mng_jdatp)*ppChunk)->iDatasize = iRawlen;
  5421. if (iRawlen != 0) /* is there any data ? */
  5422. {
  5423. MNG_ALLOC (pData, ((mng_jdatp)*ppChunk)->pData, iRawlen);
  5424. MNG_COPY (((mng_jdatp)*ppChunk)->pData, pRawdata, iRawlen);
  5425. }
  5426. }
  5427. #endif /* MNG_STORE_CHUNKS */
  5428. #ifdef MNG_SUPPORT_TRACE
  5429. MNG_TRACE (pData, MNG_FN_READ_JDAT, MNG_LC_END);
  5430. #endif
  5431. return MNG_NOERROR; /* done */
  5432. }
  5433. #else
  5434. #define read_jdat 0
  5435. #endif /* MNG_INCLUDE_JNG */
  5436. #endif
  5437. /* ************************************************************************** */
  5438. #ifndef MNG_OPTIMIZE_CHUNKREADER
  5439. #ifdef MNG_INCLUDE_JNG
  5440. READ_CHUNK (mng_read_jsep)
  5441. {
  5442. #ifdef MNG_SUPPORT_TRACE
  5443. MNG_TRACE (pData, MNG_FN_READ_JSEP, MNG_LC_START);
  5444. #endif
  5445. if (!pData->bHasJHDR) /* sequence checks */
  5446. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5447. if (iRawlen != 0) /* must be empty ! */
  5448. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5449. pData->bHasJSEP = MNG_TRUE; /* indicate we've had the 8-/12-bit separator */
  5450. #ifdef MNG_STORE_CHUNKS
  5451. if (pData->bStorechunks)
  5452. { /* initialize storage */
  5453. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  5454. if (iRetcode) /* on error bail out */
  5455. return iRetcode;
  5456. }
  5457. #endif /* MNG_STORE_CHUNKS */
  5458. #ifdef MNG_SUPPORT_TRACE
  5459. MNG_TRACE (pData, MNG_FN_READ_JSEP, MNG_LC_END);
  5460. #endif
  5461. return MNG_NOERROR; /* done */
  5462. }
  5463. #else
  5464. #define read_jsep 0
  5465. #endif /* MNG_INCLUDE_JNG */
  5466. #endif
  5467. /* ************************************************************************** */
  5468. #ifndef MNG_OPTIMIZE_CHUNKREADER
  5469. #ifndef MNG_NO_DELTA_PNG
  5470. READ_CHUNK (mng_read_dhdr)
  5471. {
  5472. mng_uint8 iImagetype, iDeltatype;
  5473. #ifdef MNG_SUPPORT_TRACE
  5474. MNG_TRACE (pData, MNG_FN_READ_DHDR, MNG_LC_START);
  5475. #endif
  5476. if (!pData->bHasMHDR) /* sequence checks */
  5477. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5478. #ifdef MNG_INCLUDE_JNG
  5479. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR) || (pData->bHasJHDR))
  5480. #else
  5481. if ((pData->bHasIHDR) || (pData->bHasBASI) || (pData->bHasDHDR))
  5482. #endif
  5483. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5484. /* check for valid length */
  5485. if ((iRawlen != 4) && (iRawlen != 12) && (iRawlen != 20))
  5486. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5487. iImagetype = *(pRawdata+2); /* check fields for validity */
  5488. iDeltatype = *(pRawdata+3);
  5489. if (iImagetype > MNG_IMAGETYPE_JNG)
  5490. MNG_ERROR (pData, MNG_INVIMAGETYPE);
  5491. if (iDeltatype > MNG_DELTATYPE_NOCHANGE)
  5492. MNG_ERROR (pData, MNG_INVDELTATYPE);
  5493. if ((iDeltatype == MNG_DELTATYPE_REPLACE) && (iRawlen > 12))
  5494. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5495. if ((iDeltatype == MNG_DELTATYPE_NOCHANGE) && (iRawlen > 4))
  5496. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5497. pData->bHasDHDR = MNG_TRUE; /* inside a DHDR-IEND block now */
  5498. pData->iDeltatype = iDeltatype;
  5499. pData->iImagelevel++; /* one level deeper */
  5500. #ifdef MNG_SUPPORT_DISPLAY
  5501. {
  5502. mng_uint16 iObjectid = mng_get_uint16 (pRawdata);
  5503. mng_uint32 iBlockwidth = 0;
  5504. mng_uint32 iBlockheight = 0;
  5505. mng_uint32 iBlockx = 0;
  5506. mng_uint32 iBlocky = 0;
  5507. mng_retcode iRetcode;
  5508. if (iRawlen > 4)
  5509. {
  5510. iBlockwidth = mng_get_uint32 (pRawdata+4);
  5511. iBlockheight = mng_get_uint32 (pRawdata+8);
  5512. }
  5513. if (iRawlen > 12)
  5514. {
  5515. iBlockx = mng_get_uint32 (pRawdata+12);
  5516. iBlocky = mng_get_uint32 (pRawdata+16);
  5517. }
  5518. iRetcode = mng_create_ani_dhdr (pData, iObjectid, iImagetype, iDeltatype,
  5519. iBlockwidth, iBlockheight, iBlockx, iBlocky);
  5520. /* if (!iRetcode)
  5521. iRetcode = mng_process_display_dhdr (pData, iObjectid, iImagetype, iDeltatype,
  5522. iBlockwidth, iBlockheight, iBlockx, iBlocky); */
  5523. if (iRetcode) /* on error bail out */
  5524. return iRetcode;
  5525. }
  5526. #endif /* MNG_SUPPORT_DISPLAY */
  5527. #ifdef MNG_STORE_CHUNKS
  5528. if (pData->bStorechunks)
  5529. { /* initialize storage */
  5530. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  5531. if (iRetcode) /* on error bail out */
  5532. return iRetcode;
  5533. /* store the fields */
  5534. ((mng_dhdrp)*ppChunk)->iObjectid = mng_get_uint16 (pRawdata);
  5535. ((mng_dhdrp)*ppChunk)->iImagetype = iImagetype;
  5536. ((mng_dhdrp)*ppChunk)->iDeltatype = iDeltatype;
  5537. if (iRawlen > 4)
  5538. {
  5539. ((mng_dhdrp)*ppChunk)->iBlockwidth = mng_get_uint32 (pRawdata+4);
  5540. ((mng_dhdrp)*ppChunk)->iBlockheight = mng_get_uint32 (pRawdata+8);
  5541. }
  5542. if (iRawlen > 12)
  5543. {
  5544. ((mng_dhdrp)*ppChunk)->iBlockx = mng_get_uint32 (pRawdata+12);
  5545. ((mng_dhdrp)*ppChunk)->iBlocky = mng_get_uint32 (pRawdata+16);
  5546. }
  5547. }
  5548. #endif /* MNG_STORE_CHUNKS */
  5549. #ifdef MNG_SUPPORT_TRACE
  5550. MNG_TRACE (pData, MNG_FN_READ_DHDR, MNG_LC_END);
  5551. #endif
  5552. return MNG_NOERROR; /* done */
  5553. }
  5554. #endif
  5555. #endif
  5556. /* ************************************************************************** */
  5557. #ifndef MNG_OPTIMIZE_CHUNKREADER
  5558. #ifndef MNG_NO_DELTA_PNG
  5559. READ_CHUNK (mng_read_prom)
  5560. {
  5561. mng_uint8 iColortype;
  5562. mng_uint8 iSampledepth;
  5563. mng_uint8 iFilltype;
  5564. #ifdef MNG_SUPPORT_TRACE
  5565. MNG_TRACE (pData, MNG_FN_READ_PROM, MNG_LC_START);
  5566. #endif
  5567. /* sequence checks */
  5568. if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
  5569. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5570. if (iRawlen != 3) /* gotta be exactly 3 bytes */
  5571. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5572. iColortype = *pRawdata; /* check fields for validity */
  5573. iSampledepth = *(pRawdata+1);
  5574. iFilltype = *(pRawdata+2);
  5575. if ((iColortype != MNG_COLORTYPE_GRAY ) &&
  5576. (iColortype != MNG_COLORTYPE_RGB ) &&
  5577. (iColortype != MNG_COLORTYPE_INDEXED) &&
  5578. (iColortype != MNG_COLORTYPE_GRAYA ) &&
  5579. (iColortype != MNG_COLORTYPE_RGBA ) )
  5580. MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
  5581. #ifdef MNG_NO_16BIT_SUPPORT
  5582. if (iSampledepth == MNG_BITDEPTH_16 )
  5583. iSampledepth = MNG_BITDEPTH_8;
  5584. #endif
  5585. if ((iSampledepth != MNG_BITDEPTH_1 ) &&
  5586. (iSampledepth != MNG_BITDEPTH_2 ) &&
  5587. (iSampledepth != MNG_BITDEPTH_4 ) &&
  5588. (iSampledepth != MNG_BITDEPTH_8 )
  5589. #ifndef MNG_NO_16BIT_SUPPORT
  5590. && (iSampledepth != MNG_BITDEPTH_16)
  5591. #endif
  5592. )
  5593. MNG_ERROR (pData, MNG_INVSAMPLEDEPTH);
  5594. if ((iFilltype != MNG_FILLMETHOD_LEFTBITREPLICATE) &&
  5595. (iFilltype != MNG_FILLMETHOD_ZEROFILL ) )
  5596. MNG_ERROR (pData, MNG_INVFILLMETHOD);
  5597. #ifdef MNG_SUPPORT_DISPLAY
  5598. {
  5599. mng_retcode iRetcode = mng_create_ani_prom (pData, iSampledepth,
  5600. iColortype, iFilltype);
  5601. /* if (!iRetcode)
  5602. iRetcode = mng_process_display_prom (pData, iSampledepth,
  5603. iColortype, iFilltype); */
  5604. if (iRetcode) /* on error bail out */
  5605. return iRetcode;
  5606. }
  5607. #endif /* MNG_SUPPORT_DISPLAY */
  5608. #ifdef MNG_STORE_CHUNKS
  5609. if (pData->bStorechunks)
  5610. { /* initialize storage */
  5611. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  5612. if (iRetcode) /* on error bail out */
  5613. return iRetcode;
  5614. /* store the fields */
  5615. ((mng_promp)*ppChunk)->iColortype = iColortype;
  5616. ((mng_promp)*ppChunk)->iSampledepth = iSampledepth;
  5617. ((mng_promp)*ppChunk)->iFilltype = iFilltype;
  5618. }
  5619. #endif /* MNG_STORE_CHUNKS */
  5620. #ifdef MNG_SUPPORT_TRACE
  5621. MNG_TRACE (pData, MNG_FN_READ_PROM, MNG_LC_END);
  5622. #endif
  5623. return MNG_NOERROR; /* done */
  5624. }
  5625. #endif
  5626. #endif
  5627. /* ************************************************************************** */
  5628. #ifndef MNG_OPTIMIZE_CHUNKREADER
  5629. #ifndef MNG_NO_DELTA_PNG
  5630. READ_CHUNK (mng_read_ipng)
  5631. {
  5632. #ifdef MNG_SUPPORT_TRACE
  5633. MNG_TRACE (pData, MNG_FN_READ_IPNG, MNG_LC_START);
  5634. #endif
  5635. /* sequence checks */
  5636. if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
  5637. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5638. if (iRawlen != 0) /* gotta be empty */
  5639. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5640. #ifdef MNG_SUPPORT_DISPLAY
  5641. {
  5642. mng_retcode iRetcode = mng_create_ani_ipng (pData);
  5643. if (!iRetcode)
  5644. iRetcode = mng_process_display_ipng (pData);
  5645. if (iRetcode) /* on error bail out */
  5646. return iRetcode;
  5647. }
  5648. #endif /* MNG_SUPPORT_DISPLAY */
  5649. #ifdef MNG_STORE_CHUNKS
  5650. if (pData->bStorechunks)
  5651. { /* initialize storage */
  5652. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  5653. if (iRetcode) /* on error bail out */
  5654. return iRetcode;
  5655. }
  5656. #endif /* MNG_STORE_CHUNKS */
  5657. #ifdef MNG_SUPPORT_TRACE
  5658. MNG_TRACE (pData, MNG_FN_READ_IPNG, MNG_LC_END);
  5659. #endif
  5660. return MNG_NOERROR; /* done */
  5661. }
  5662. #endif
  5663. #endif
  5664. /* ************************************************************************** */
  5665. #ifndef MNG_OPTIMIZE_CHUNKREADER
  5666. #ifndef MNG_NO_DELTA_PNG
  5667. READ_CHUNK (mng_read_pplt)
  5668. {
  5669. mng_uint8 iDeltatype;
  5670. mng_uint8p pTemp;
  5671. mng_uint32 iLen;
  5672. mng_uint8 iX, iM;
  5673. mng_uint32 iY;
  5674. mng_uint32 iMax;
  5675. mng_rgbpaltab aIndexentries;
  5676. mng_uint8arr aAlphaentries;
  5677. mng_uint8arr aUsedentries;
  5678. #ifdef MNG_SUPPORT_TRACE
  5679. MNG_TRACE (pData, MNG_FN_READ_PPLT, MNG_LC_START);
  5680. #endif
  5681. /* sequence checks */
  5682. if ((!pData->bHasMHDR) && (!pData->bHasDHDR))
  5683. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5684. if (iRawlen < 1) /* must have at least 1 byte */
  5685. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5686. iDeltatype = *pRawdata;
  5687. /* valid ? */
  5688. if (iDeltatype > MNG_DELTATYPE_DELTARGBA)
  5689. MNG_ERROR (pData, MNG_INVDELTATYPE);
  5690. /* must be indexed color ! */
  5691. if (pData->iColortype != MNG_COLORTYPE_INDEXED)
  5692. MNG_ERROR (pData, MNG_INVALIDCOLORTYPE);
  5693. pTemp = pRawdata + 1;
  5694. iLen = iRawlen - 1;
  5695. iMax = 0;
  5696. for (iY = 0; iY < 256; iY++) /* reset arrays */
  5697. {
  5698. aIndexentries [iY].iRed = 0;
  5699. aIndexentries [iY].iGreen = 0;
  5700. aIndexentries [iY].iBlue = 0;
  5701. aAlphaentries [iY] = 255;
  5702. aUsedentries [iY] = 0;
  5703. }
  5704. while (iLen) /* as long as there are entries left ... */
  5705. {
  5706. mng_uint32 iDiff;
  5707. if (iLen < 2)
  5708. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5709. iX = *pTemp; /* get start and end index */
  5710. iM = *(pTemp+1);
  5711. if (iM < iX)
  5712. MNG_ERROR (pData, MNG_INVALIDINDEX);
  5713. if ((mng_uint32)iM >= iMax) /* determine highest used index */
  5714. iMax = (mng_uint32)iM + 1;
  5715. pTemp += 2;
  5716. iLen -= 2;
  5717. iDiff = (iM - iX + 1);
  5718. if ((iDeltatype == MNG_DELTATYPE_REPLACERGB ) ||
  5719. (iDeltatype == MNG_DELTATYPE_DELTARGB ) )
  5720. iDiff = iDiff * 3;
  5721. else
  5722. if ((iDeltatype == MNG_DELTATYPE_REPLACERGBA) ||
  5723. (iDeltatype == MNG_DELTATYPE_DELTARGBA ) )
  5724. iDiff = iDiff * 4;
  5725. if (iLen < iDiff)
  5726. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5727. if ((iDeltatype == MNG_DELTATYPE_REPLACERGB ) ||
  5728. (iDeltatype == MNG_DELTATYPE_DELTARGB ) )
  5729. {
  5730. for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++)
  5731. {
  5732. aIndexentries [iY].iRed = *pTemp;
  5733. aIndexentries [iY].iGreen = *(pTemp+1);
  5734. aIndexentries [iY].iBlue = *(pTemp+2);
  5735. aUsedentries [iY] = 1;
  5736. pTemp += 3;
  5737. iLen -= 3;
  5738. }
  5739. }
  5740. else
  5741. if ((iDeltatype == MNG_DELTATYPE_REPLACEALPHA) ||
  5742. (iDeltatype == MNG_DELTATYPE_DELTAALPHA ) )
  5743. {
  5744. for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++)
  5745. {
  5746. aAlphaentries [iY] = *pTemp;
  5747. aUsedentries [iY] = 1;
  5748. pTemp++;
  5749. iLen--;
  5750. }
  5751. }
  5752. else
  5753. {
  5754. for (iY = (mng_uint32)iX; iY <= (mng_uint32)iM; iY++)
  5755. {
  5756. aIndexentries [iY].iRed = *pTemp;
  5757. aIndexentries [iY].iGreen = *(pTemp+1);
  5758. aIndexentries [iY].iBlue = *(pTemp+2);
  5759. aAlphaentries [iY] = *(pTemp+3);
  5760. aUsedentries [iY] = 1;
  5761. pTemp += 4;
  5762. iLen -= 4;
  5763. }
  5764. }
  5765. }
  5766. switch (pData->iBitdepth) /* check maximum allowed entries for bitdepth */
  5767. {
  5768. case MNG_BITDEPTH_1 : {
  5769. if (iMax > 2)
  5770. MNG_ERROR (pData, MNG_INVALIDINDEX);
  5771. break;
  5772. }
  5773. case MNG_BITDEPTH_2 : {
  5774. if (iMax > 4)
  5775. MNG_ERROR (pData, MNG_INVALIDINDEX);
  5776. break;
  5777. }
  5778. case MNG_BITDEPTH_4 : {
  5779. if (iMax > 16)
  5780. MNG_ERROR (pData, MNG_INVALIDINDEX);
  5781. break;
  5782. }
  5783. }
  5784. #ifdef MNG_SUPPORT_DISPLAY
  5785. { /* create animation object */
  5786. mng_retcode iRetcode = mng_create_ani_pplt (pData, iDeltatype, iMax,
  5787. aIndexentries, aAlphaentries,
  5788. aUsedentries);
  5789. /* if (!iRetcode)
  5790. iRetcode = mng_process_display_pplt (pData, iDeltatype, iMax, aIndexentries,
  5791. aAlphaentries, aUsedentries); */
  5792. if (iRetcode) /* on error bail out */
  5793. return iRetcode;
  5794. }
  5795. #endif /* MNG_SUPPORT_DISPLAY */
  5796. #ifdef MNG_STORE_CHUNKS
  5797. if (pData->bStorechunks)
  5798. { /* initialize storage */
  5799. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  5800. if (iRetcode) /* on error bail out */
  5801. return iRetcode;
  5802. /* store the fields */
  5803. ((mng_ppltp)*ppChunk)->iDeltatype = iDeltatype;
  5804. ((mng_ppltp)*ppChunk)->iCount = iMax;
  5805. for (iY = 0; iY < 256; iY++)
  5806. {
  5807. ((mng_ppltp)*ppChunk)->aEntries [iY].iRed = aIndexentries [iY].iRed;
  5808. ((mng_ppltp)*ppChunk)->aEntries [iY].iGreen = aIndexentries [iY].iGreen;
  5809. ((mng_ppltp)*ppChunk)->aEntries [iY].iBlue = aIndexentries [iY].iBlue;
  5810. ((mng_ppltp)*ppChunk)->aEntries [iY].iAlpha = aAlphaentries [iY];
  5811. ((mng_ppltp)*ppChunk)->aEntries [iY].bUsed = (mng_bool)(aUsedentries [iY]);
  5812. }
  5813. }
  5814. #endif /* MNG_STORE_CHUNKS */
  5815. #ifdef MNG_SUPPORT_TRACE
  5816. MNG_TRACE (pData, MNG_FN_READ_PPLT, MNG_LC_END);
  5817. #endif
  5818. return MNG_NOERROR; /* done */
  5819. }
  5820. #endif
  5821. #endif
  5822. /* ************************************************************************** */
  5823. #ifndef MNG_OPTIMIZE_CHUNKREADER
  5824. #ifndef MNG_NO_DELTA_PNG
  5825. #ifdef MNG_INCLUDE_JNG
  5826. READ_CHUNK (mng_read_ijng)
  5827. {
  5828. #ifdef MNG_SUPPORT_TRACE
  5829. MNG_TRACE (pData, MNG_FN_READ_IJNG, MNG_LC_START);
  5830. #endif
  5831. /* sequence checks */
  5832. if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
  5833. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5834. if (iRawlen != 0) /* gotta be empty */
  5835. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5836. #ifdef MNG_SUPPORT_DISPLAY
  5837. {
  5838. mng_retcode iRetcode = mng_create_ani_ijng (pData);
  5839. if (!iRetcode)
  5840. iRetcode = mng_process_display_ijng (pData);
  5841. if (iRetcode) /* on error bail out */
  5842. return iRetcode;
  5843. }
  5844. #endif /* MNG_SUPPORT_DISPLAY */
  5845. #ifdef MNG_STORE_CHUNKS
  5846. if (pData->bStorechunks)
  5847. { /* initialize storage */
  5848. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  5849. if (iRetcode) /* on error bail out */
  5850. return iRetcode;
  5851. }
  5852. #endif /* MNG_STORE_CHUNKS */
  5853. #ifdef MNG_SUPPORT_TRACE
  5854. MNG_TRACE (pData, MNG_FN_READ_IJNG, MNG_LC_END);
  5855. #endif
  5856. return MNG_NOERROR; /* done */
  5857. }
  5858. #endif
  5859. #endif
  5860. #endif
  5861. /* ************************************************************************** */
  5862. #ifndef MNG_OPTIMIZE_CHUNKREADER
  5863. #ifndef MNG_NO_DELTA_PNG
  5864. READ_CHUNK (mng_read_drop)
  5865. {
  5866. #ifdef MNG_SUPPORT_TRACE
  5867. MNG_TRACE (pData, MNG_FN_READ_DROP, MNG_LC_START);
  5868. #endif
  5869. /* sequence checks */
  5870. if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
  5871. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5872. /* check length */
  5873. if ((iRawlen < 4) || ((iRawlen % 4) != 0))
  5874. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5875. #ifdef MNG_SUPPORT_DISPLAY
  5876. {
  5877. /* TODO: something !!! */
  5878. }
  5879. #endif /* MNG_SUPPORT_DISPLAY */
  5880. #ifdef MNG_STORE_CHUNKS
  5881. if (pData->bStorechunks)
  5882. { /* initialize storage */
  5883. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  5884. if (iRetcode) /* on error bail out */
  5885. return iRetcode;
  5886. /* store the fields */
  5887. ((mng_dropp)*ppChunk)->iCount = iRawlen / 4;
  5888. if (iRawlen)
  5889. {
  5890. mng_uint32 iX;
  5891. mng_uint8p pTemp = pRawdata;
  5892. mng_uint32p pEntry;
  5893. MNG_ALLOC (pData, pEntry, iRawlen);
  5894. ((mng_dropp)*ppChunk)->pChunknames = (mng_ptr)pEntry;
  5895. for (iX = 0; iX < iRawlen / 4; iX++)
  5896. {
  5897. *pEntry = mng_get_uint32 (pTemp);
  5898. pTemp += 4;
  5899. pEntry++;
  5900. }
  5901. }
  5902. }
  5903. #endif /* MNG_STORE_CHUNKS */
  5904. #ifdef MNG_SUPPORT_TRACE
  5905. MNG_TRACE (pData, MNG_FN_READ_DROP, MNG_LC_END);
  5906. #endif
  5907. return MNG_NOERROR; /* done */
  5908. }
  5909. #endif
  5910. #endif
  5911. /* ************************************************************************** */
  5912. #ifndef MNG_OPTIMIZE_CHUNKREADER
  5913. #ifndef MNG_NO_DELTA_PNG
  5914. #ifndef MNG_SKIPCHUNK_DBYK
  5915. READ_CHUNK (mng_read_dbyk)
  5916. {
  5917. #ifdef MNG_SUPPORT_TRACE
  5918. MNG_TRACE (pData, MNG_FN_READ_DBYK, MNG_LC_START);
  5919. #endif
  5920. /* sequence checks */
  5921. if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
  5922. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5923. if (iRawlen < 6) /* must be at least 6 long */
  5924. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5925. #ifdef MNG_SUPPORT_DISPLAY
  5926. {
  5927. /* TODO: something !!! */
  5928. }
  5929. #endif /* MNG_SUPPORT_DISPLAY */
  5930. #ifdef MNG_STORE_CHUNKS
  5931. if (pData->bStorechunks)
  5932. { /* initialize storage */
  5933. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  5934. if (iRetcode) /* on error bail out */
  5935. return iRetcode;
  5936. /* store the fields */
  5937. ((mng_dbykp)*ppChunk)->iChunkname = mng_get_uint32 (pRawdata);
  5938. ((mng_dbykp)*ppChunk)->iPolarity = *(pRawdata+4);
  5939. ((mng_dbykp)*ppChunk)->iKeywordssize = iRawlen - 5;
  5940. if (iRawlen > 5)
  5941. {
  5942. MNG_ALLOC (pData, ((mng_dbykp)*ppChunk)->zKeywords, iRawlen-4);
  5943. MNG_COPY (((mng_dbykp)*ppChunk)->zKeywords, pRawdata+5, iRawlen-5);
  5944. }
  5945. }
  5946. #endif /* MNG_STORE_CHUNKS */
  5947. #ifdef MNG_SUPPORT_TRACE
  5948. MNG_TRACE (pData, MNG_FN_READ_DBYK, MNG_LC_END);
  5949. #endif
  5950. return MNG_NOERROR; /* done */
  5951. }
  5952. #endif
  5953. #endif
  5954. #endif
  5955. /* ************************************************************************** */
  5956. #ifndef MNG_OPTIMIZE_CHUNKREADER
  5957. #ifndef MNG_NO_DELTA_PNG
  5958. #ifndef MNG_SKIPCHUNK_ORDR
  5959. READ_CHUNK (mng_read_ordr)
  5960. {
  5961. #ifdef MNG_SUPPORT_TRACE
  5962. MNG_TRACE (pData, MNG_FN_READ_ORDR, MNG_LC_START);
  5963. #endif
  5964. /* sequence checks */
  5965. if ((!pData->bHasMHDR) || (!pData->bHasDHDR))
  5966. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  5967. /* check length */
  5968. if ((iRawlen < 5) || ((iRawlen % 5) != 0))
  5969. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  5970. #ifdef MNG_SUPPORT_DISPLAY
  5971. {
  5972. /* TODO: something !!! */
  5973. }
  5974. #endif /* MNG_SUPPORT_DISPLAY */
  5975. #ifdef MNG_STORE_CHUNKS
  5976. if (pData->bStorechunks)
  5977. { /* initialize storage */
  5978. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  5979. if (iRetcode) /* on error bail out */
  5980. return iRetcode;
  5981. /* store the fields */
  5982. ((mng_ordrp)*ppChunk)->iCount = iRawlen / 5;
  5983. if (iRawlen)
  5984. {
  5985. mng_uint32 iX;
  5986. mng_ordr_entryp pEntry;
  5987. mng_uint8p pTemp = pRawdata;
  5988. MNG_ALLOC (pData, pEntry, iRawlen);
  5989. ((mng_ordrp)*ppChunk)->pEntries = pEntry;
  5990. for (iX = 0; iX < iRawlen / 5; iX++)
  5991. {
  5992. pEntry->iChunkname = mng_get_uint32 (pTemp);
  5993. pEntry->iOrdertype = *(pTemp+4);
  5994. pTemp += 5;
  5995. pEntry++;
  5996. }
  5997. }
  5998. }
  5999. #endif /* MNG_STORE_CHUNKS */
  6000. #ifdef MNG_SUPPORT_TRACE
  6001. MNG_TRACE (pData, MNG_FN_READ_ORDR, MNG_LC_END);
  6002. #endif
  6003. return MNG_NOERROR; /* done */
  6004. }
  6005. #endif
  6006. #endif
  6007. #endif
  6008. /* ************************************************************************** */
  6009. #ifndef MNG_OPTIMIZE_CHUNKREADER
  6010. #ifndef MNG_SKIPCHUNK_MAGN
  6011. READ_CHUNK (mng_read_magn)
  6012. {
  6013. mng_uint16 iFirstid, iLastid;
  6014. mng_uint8 iMethodX, iMethodY;
  6015. mng_uint16 iMX, iMY, iML, iMR, iMT, iMB;
  6016. mng_bool bFaulty;
  6017. #ifdef MNG_SUPPORT_TRACE
  6018. MNG_TRACE (pData, MNG_FN_READ_MAGN, MNG_LC_START);
  6019. #endif
  6020. /* sequence checks */
  6021. #ifdef MNG_SUPPORT_JNG
  6022. if ((!pData->bHasMHDR) || (pData->bHasIHDR) || (pData->bHasDHDR) || (pData->bHasJHDR))
  6023. #else
  6024. if ((!pData->bHasMHDR) || (pData->bHasIHDR) || (pData->bHasDHDR))
  6025. #endif
  6026. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  6027. /* check length */
  6028. if (iRawlen > 20)
  6029. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6030. /* following is an ugly hack to allow faulty layout caused by previous
  6031. versions of libmng and MNGeye, which wrote MAGN with a 16-bit
  6032. MethodX/MethodY (as opposed to the proper 8-bit as defined in the spec!) */
  6033. if ((iRawlen == 6) || (iRawlen == 8) || (iRawlen == 10) || (iRawlen == 12) ||
  6034. (iRawlen == 14) || (iRawlen == 16) || (iRawlen == 20))
  6035. bFaulty = MNG_TRUE; /* these lengths are all wrong */
  6036. else /* length 18 can be right or wrong !!! */
  6037. if ((iRawlen == 18) && (mng_get_uint16 (pRawdata+4) <= 5) &&
  6038. (mng_get_uint16 (pRawdata+6) < 256) &&
  6039. (mng_get_uint16 (pRawdata+8) < 256) &&
  6040. (mng_get_uint16 (pRawdata+10) < 256) &&
  6041. (mng_get_uint16 (pRawdata+12) < 256) &&
  6042. (mng_get_uint16 (pRawdata+14) < 256) &&
  6043. (mng_get_uint16 (pRawdata+16) < 256))
  6044. bFaulty = MNG_TRUE; /* this is very likely the wrong layout */
  6045. else
  6046. bFaulty = MNG_FALSE; /* all other cases are handled as right */
  6047. if (bFaulty) /* wrong layout ? */
  6048. {
  6049. if (iRawlen > 0) /* get the fields */
  6050. iFirstid = mng_get_uint16 (pRawdata);
  6051. else
  6052. iFirstid = 0;
  6053. if (iRawlen > 2)
  6054. iLastid = mng_get_uint16 (pRawdata+2);
  6055. else
  6056. iLastid = iFirstid;
  6057. if (iRawlen > 4)
  6058. iMethodX = (mng_uint8)(mng_get_uint16 (pRawdata+4));
  6059. else
  6060. iMethodX = 0;
  6061. if (iRawlen > 6)
  6062. iMX = mng_get_uint16 (pRawdata+6);
  6063. else
  6064. iMX = 1;
  6065. if (iRawlen > 8)
  6066. iMY = mng_get_uint16 (pRawdata+8);
  6067. else
  6068. iMY = iMX;
  6069. if (iRawlen > 10)
  6070. iML = mng_get_uint16 (pRawdata+10);
  6071. else
  6072. iML = iMX;
  6073. if (iRawlen > 12)
  6074. iMR = mng_get_uint16 (pRawdata+12);
  6075. else
  6076. iMR = iMX;
  6077. if (iRawlen > 14)
  6078. iMT = mng_get_uint16 (pRawdata+14);
  6079. else
  6080. iMT = iMY;
  6081. if (iRawlen > 16)
  6082. iMB = mng_get_uint16 (pRawdata+16);
  6083. else
  6084. iMB = iMY;
  6085. if (iRawlen > 18)
  6086. iMethodY = (mng_uint8)(mng_get_uint16 (pRawdata+18));
  6087. else
  6088. iMethodY = iMethodX;
  6089. }
  6090. else /* proper layout !!!! */
  6091. {
  6092. if (iRawlen > 0) /* get the fields */
  6093. iFirstid = mng_get_uint16 (pRawdata);
  6094. else
  6095. iFirstid = 0;
  6096. if (iRawlen > 2)
  6097. iLastid = mng_get_uint16 (pRawdata+2);
  6098. else
  6099. iLastid = iFirstid;
  6100. if (iRawlen > 4)
  6101. iMethodX = *(pRawdata+4);
  6102. else
  6103. iMethodX = 0;
  6104. if (iRawlen > 5)
  6105. iMX = mng_get_uint16 (pRawdata+5);
  6106. else
  6107. iMX = 1;
  6108. if (iRawlen > 7)
  6109. iMY = mng_get_uint16 (pRawdata+7);
  6110. else
  6111. iMY = iMX;
  6112. if (iRawlen > 9)
  6113. iML = mng_get_uint16 (pRawdata+9);
  6114. else
  6115. iML = iMX;
  6116. if (iRawlen > 11)
  6117. iMR = mng_get_uint16 (pRawdata+11);
  6118. else
  6119. iMR = iMX;
  6120. if (iRawlen > 13)
  6121. iMT = mng_get_uint16 (pRawdata+13);
  6122. else
  6123. iMT = iMY;
  6124. if (iRawlen > 15)
  6125. iMB = mng_get_uint16 (pRawdata+15);
  6126. else
  6127. iMB = iMY;
  6128. if (iRawlen > 17)
  6129. iMethodY = *(pRawdata+17);
  6130. else
  6131. iMethodY = iMethodX;
  6132. }
  6133. /* check field validity */
  6134. if ((iMethodX > 5) || (iMethodY > 5))
  6135. MNG_ERROR (pData, MNG_INVALIDMETHOD);
  6136. #ifdef MNG_SUPPORT_DISPLAY
  6137. {
  6138. mng_retcode iRetcode;
  6139. iRetcode = mng_create_ani_magn (pData, iFirstid, iLastid, iMethodX,
  6140. iMX, iMY, iML, iMR, iMT, iMB, iMethodY);
  6141. /* if (!iRetcode)
  6142. iRetcode = mng_process_display_magn (pData, iFirstid, iLastid, iMethodX,
  6143. iMX, iMY, iML, iMR, iMT, iMB, iMethodY); */
  6144. if (iRetcode) /* on error bail out */
  6145. return iRetcode;
  6146. }
  6147. #endif /* MNG_SUPPORT_DISPLAY */
  6148. #ifdef MNG_STORE_CHUNKS
  6149. if (pData->bStorechunks)
  6150. { /* initialize storage */
  6151. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  6152. if (iRetcode) /* on error bail out */
  6153. return iRetcode;
  6154. /* store the fields */
  6155. ((mng_magnp)*ppChunk)->iFirstid = iFirstid;
  6156. ((mng_magnp)*ppChunk)->iLastid = iLastid;
  6157. ((mng_magnp)*ppChunk)->iMethodX = iMethodX;
  6158. ((mng_magnp)*ppChunk)->iMX = iMX;
  6159. ((mng_magnp)*ppChunk)->iMY = iMY;
  6160. ((mng_magnp)*ppChunk)->iML = iML;
  6161. ((mng_magnp)*ppChunk)->iMR = iMR;
  6162. ((mng_magnp)*ppChunk)->iMT = iMT;
  6163. ((mng_magnp)*ppChunk)->iMB = iMB;
  6164. ((mng_magnp)*ppChunk)->iMethodY = iMethodY;
  6165. }
  6166. #endif /* MNG_STORE_CHUNKS */
  6167. #ifdef MNG_SUPPORT_TRACE
  6168. MNG_TRACE (pData, MNG_FN_READ_MAGN, MNG_LC_END);
  6169. #endif
  6170. return MNG_NOERROR; /* done */
  6171. }
  6172. #endif
  6173. #endif
  6174. /* ************************************************************************** */
  6175. #ifndef MNG_OPTIMIZE_CHUNKREADER
  6176. #ifdef MNG_INCLUDE_MPNG_PROPOSAL
  6177. READ_CHUNK (mng_read_mpng)
  6178. {
  6179. mng_uint32 iFramewidth;
  6180. mng_uint32 iFrameheight;
  6181. mng_uint16 iTickspersec;
  6182. mng_uint32 iFramessize;
  6183. mng_uint32 iCompressedsize;
  6184. #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
  6185. mng_retcode iRetcode;
  6186. mng_uint16 iNumplays;
  6187. mng_uint32 iBufsize;
  6188. mng_uint8p pBuf = 0;
  6189. #endif
  6190. #ifdef MNG_SUPPORT_TRACE
  6191. MNG_TRACE (pData, MNG_FN_READ_MPNG, MNG_LC_START);
  6192. #endif
  6193. /* sequence checks */
  6194. if (!pData->bHasIHDR)
  6195. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  6196. if (iRawlen < 41) /* length must be at least 41 */
  6197. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6198. iFramewidth = mng_get_int32 (pRawdata);
  6199. if (iFramewidth == 0) /* frame_width must not be zero */
  6200. MNG_ERROR (pData, MNG_INVALIDWIDTH);
  6201. iFrameheight = mng_get_int32 (pRawdata+4);
  6202. if (iFrameheight == 0) /* frame_height must not be zero */
  6203. MNG_ERROR (pData, MNG_INVALIDHEIGHT);
  6204. iTickspersec = mng_get_uint16 (pRawdata+10);
  6205. if (iTickspersec == 0) /* delay_den must not be zero */
  6206. MNG_ERROR (pData, MNG_INVALIDFIELDVAL);
  6207. if (*(pRawdata+12) != 0) /* only deflate compression-method allowed */
  6208. MNG_ERROR (pData, MNG_INVALIDCOMPRESS);
  6209. #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
  6210. iNumplays = mng_get_uint16 (pRawdata+8);
  6211. iCompressedsize = (mng_uint32)(iRawlen - 13);
  6212. #endif
  6213. #ifdef MNG_SUPPORT_DISPLAY
  6214. {
  6215. iRetcode = mng_inflate_buffer (pData, pRawdata+13, iCompressedsize,
  6216. &pBuf, &iBufsize, &iFramessize);
  6217. if (iRetcode) /* on error bail out */
  6218. {
  6219. MNG_FREEX (pData, pBuf, iBufsize);
  6220. return iRetcode;
  6221. }
  6222. if (iFramessize % 26)
  6223. {
  6224. MNG_FREEX (pData, pBuf, iBufsize);
  6225. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6226. }
  6227. iRetcode = mng_create_mpng_obj (pData, iFramewidth, iFrameheight, iNumplays,
  6228. iTickspersec, iFramessize, pBuf);
  6229. if (iRetcode) /* on error bail out */
  6230. {
  6231. MNG_FREEX (pData, pBuf, iBufsize);
  6232. return iRetcode;
  6233. }
  6234. }
  6235. #endif /* MNG_SUPPORT_DISPLAY */
  6236. #ifdef MNG_STORE_CHUNKS
  6237. if (pData->bStorechunks)
  6238. { /* initialize storage */
  6239. iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  6240. if (iRetcode) /* on error bail out */
  6241. return iRetcode;
  6242. /* store the fields */
  6243. ((mng_mpngp)*ppChunk)->iFramewidth = iFramewidth;
  6244. ((mng_mpngp)*ppChunk)->iFrameheight = iFrameheight;
  6245. ((mng_mpngp)*ppChunk)->iNumplays = iNumplays;
  6246. ((mng_mpngp)*ppChunk)->iTickspersec = iTickspersec;
  6247. ((mng_mpngp)*ppChunk)->iCompressionmethod = *(pRawdata+14);
  6248. #ifndef MNG_SUPPORT_DISPLAY
  6249. iRetcode = mng_inflate_buffer (pData, pRawdata+13, iCompressedsize,
  6250. &pBuf, &iBufsize, &iFramessize);
  6251. if (iRetcode) /* on error bail out */
  6252. {
  6253. MNG_FREEX (pData, pBuf, iBufsize);
  6254. return iRetcode;
  6255. }
  6256. if (iFramessize % 26)
  6257. {
  6258. MNG_FREEX (pData, pBuf, iBufsize);
  6259. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6260. }
  6261. #endif
  6262. if (iFramessize)
  6263. {
  6264. MNG_ALLOCX (pData, ((mng_mpngp)*ppChunk)->pFrames, iFramessize);
  6265. if (((mng_mpngp)*ppChunk)->pFrames == 0)
  6266. {
  6267. MNG_FREEX (pData, pBuf, iBufsize);
  6268. MNG_ERROR (pData, MNG_OUTOFMEMORY);
  6269. }
  6270. ((mng_mpngp)*ppChunk)->iFramessize = iFramessize;
  6271. MNG_COPY (((mng_mpngp)*ppChunk)->pFrames, pBuf, iFramessize);
  6272. }
  6273. }
  6274. #endif /* MNG_STORE_CHUNKS */
  6275. #if defined(MNG_SUPPORT_DISPLAY) || defined(MNG_STORE_CHUNKS)
  6276. MNG_FREEX (pData, pBuf, iBufsize);
  6277. #endif
  6278. #ifdef MNG_SUPPORT_TRACE
  6279. MNG_TRACE (pData, MNG_FN_READ_MPNG, MNG_LC_END);
  6280. #endif
  6281. return MNG_NOERROR; /* done */
  6282. }
  6283. #endif
  6284. #endif
  6285. /* ************************************************************************** */
  6286. #ifndef MNG_OPTIMIZE_CHUNKREADER
  6287. #ifndef MNG_SKIPCHUNK_evNT
  6288. READ_CHUNK (mng_read_evnt)
  6289. {
  6290. #ifdef MNG_SUPPORT_TRACE
  6291. MNG_TRACE (pData, MNG_FN_READ_EVNT, MNG_LC_START);
  6292. #endif
  6293. /* sequence checks */
  6294. if ((!pData->bHasMHDR) || (pData->bHasSAVE))
  6295. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  6296. if (iRawlen < 2) /* must have at least 1 entry ! */
  6297. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6298. #if defined(MNG_SUPPORT_DISPLAY) && defined(MNG_SUPPORT_DYNAMICMNG)
  6299. {
  6300. if (iRawlen) /* not empty ? */
  6301. {
  6302. mng_retcode iRetcode;
  6303. mng_uint8p pTemp;
  6304. mng_uint8p pNull;
  6305. mng_uint32 iLen;
  6306. mng_uint8 iEventtype;
  6307. mng_uint8 iMasktype;
  6308. mng_int32 iLeft;
  6309. mng_int32 iRight;
  6310. mng_int32 iTop;
  6311. mng_int32 iBottom;
  6312. mng_uint16 iObjectid;
  6313. mng_uint8 iIndex;
  6314. mng_uint32 iNamesize;
  6315. pTemp = pRawdata;
  6316. iLen = iRawlen;
  6317. while (iLen) /* anything left ? */
  6318. {
  6319. iEventtype = *pTemp; /* eventtype */
  6320. if (iEventtype > 5)
  6321. MNG_ERROR (pData, MNG_INVALIDEVENT);
  6322. pTemp++;
  6323. iMasktype = *pTemp; /* masktype */
  6324. if (iMasktype > 5)
  6325. MNG_ERROR (pData, MNG_INVALIDMASK);
  6326. pTemp++;
  6327. iLen -= 2;
  6328. iLeft = 0;
  6329. iRight = 0;
  6330. iTop = 0;
  6331. iBottom = 0;
  6332. iObjectid = 0;
  6333. iIndex = 0;
  6334. switch (iMasktype)
  6335. {
  6336. case 1 :
  6337. {
  6338. if (iLen > 16)
  6339. {
  6340. iLeft = mng_get_int32 (pTemp);
  6341. iRight = mng_get_int32 (pTemp+4);
  6342. iTop = mng_get_int32 (pTemp+8);
  6343. iBottom = mng_get_int32 (pTemp+12);
  6344. pTemp += 16;
  6345. iLen -= 16;
  6346. }
  6347. else
  6348. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6349. break;
  6350. }
  6351. case 2 :
  6352. {
  6353. if (iLen > 2)
  6354. {
  6355. iObjectid = mng_get_uint16 (pTemp);
  6356. pTemp += 2;
  6357. iLen -= 2;
  6358. }
  6359. else
  6360. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6361. break;
  6362. }
  6363. case 3 :
  6364. {
  6365. if (iLen > 3)
  6366. {
  6367. iObjectid = mng_get_uint16 (pTemp);
  6368. iIndex = *(pTemp+2);
  6369. pTemp += 3;
  6370. iLen -= 3;
  6371. }
  6372. else
  6373. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6374. break;
  6375. }
  6376. case 4 :
  6377. {
  6378. if (iLen > 18)
  6379. {
  6380. iLeft = mng_get_int32 (pTemp);
  6381. iRight = mng_get_int32 (pTemp+4);
  6382. iTop = mng_get_int32 (pTemp+8);
  6383. iBottom = mng_get_int32 (pTemp+12);
  6384. iObjectid = mng_get_uint16 (pTemp+16);
  6385. pTemp += 18;
  6386. iLen -= 18;
  6387. }
  6388. else
  6389. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6390. break;
  6391. }
  6392. case 5 :
  6393. {
  6394. if (iLen > 19)
  6395. {
  6396. iLeft = mng_get_int32 (pTemp);
  6397. iRight = mng_get_int32 (pTemp+4);
  6398. iTop = mng_get_int32 (pTemp+8);
  6399. iBottom = mng_get_int32 (pTemp+12);
  6400. iObjectid = mng_get_uint16 (pTemp+16);
  6401. iIndex = *(pTemp+18);
  6402. pTemp += 19;
  6403. iLen -= 19;
  6404. }
  6405. else
  6406. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6407. break;
  6408. }
  6409. }
  6410. pNull = find_null (pTemp); /* get the name length */
  6411. if ((pNull - pTemp) > (mng_int32)iLen)
  6412. {
  6413. iNamesize = iLen; /* no null found; so end of evNT */
  6414. iLen = 0;
  6415. }
  6416. else
  6417. {
  6418. iNamesize = pNull - pTemp; /* should be another entry */
  6419. iLen = iLen - iNamesize - 1;
  6420. if (!iLen) /* must not end with a null ! */
  6421. MNG_ERROR (pData, MNG_ENDWITHNULL);
  6422. }
  6423. iRetcode = mng_create_event (pData, iEventtype, iMasktype, iLeft, iRight,
  6424. iTop, iBottom, iObjectid, iIndex,
  6425. iNamesize, (mng_pchar)pTemp);
  6426. if (iRetcode) /* on error bail out */
  6427. return iRetcode;
  6428. pTemp = pTemp + iNamesize + 1;
  6429. }
  6430. }
  6431. }
  6432. #endif /* MNG_SUPPORT_DISPLAY && MNG_SUPPORT_DYNAMICMNG */
  6433. #ifdef MNG_STORE_CHUNKS
  6434. if (pData->bStorechunks)
  6435. { /* initialize storage */
  6436. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  6437. if (iRetcode) /* on error bail out */
  6438. return iRetcode;
  6439. if (iRawlen) /* not empty ? */
  6440. {
  6441. mng_uint32 iX;
  6442. mng_uint32 iCount = 0;
  6443. mng_uint8p pTemp;
  6444. mng_uint8p pNull;
  6445. mng_uint32 iLen;
  6446. mng_uint8 iEventtype;
  6447. mng_uint8 iMasktype;
  6448. mng_int32 iLeft;
  6449. mng_int32 iRight;
  6450. mng_int32 iTop;
  6451. mng_int32 iBottom;
  6452. mng_uint16 iObjectid;
  6453. mng_uint8 iIndex;
  6454. mng_uint32 iNamesize;
  6455. mng_evnt_entryp pEntry = MNG_NULL;
  6456. for (iX = 0; iX < 2; iX++) /* do this twice to get the count first ! */
  6457. {
  6458. pTemp = pRawdata;
  6459. iLen = iRawlen;
  6460. if (iX) /* second run ? */
  6461. {
  6462. MNG_ALLOC (pData, pEntry, (iCount * sizeof (mng_evnt_entry)));
  6463. ((mng_evntp)*ppChunk)->iCount = iCount;
  6464. ((mng_evntp)*ppChunk)->pEntries = pEntry;
  6465. }
  6466. while (iLen) /* anything left ? */
  6467. {
  6468. iEventtype = *pTemp; /* eventtype */
  6469. if (iEventtype > 5)
  6470. MNG_ERROR (pData, MNG_INVALIDEVENT);
  6471. pTemp++;
  6472. iMasktype = *pTemp; /* masktype */
  6473. if (iMasktype > 5)
  6474. MNG_ERROR (pData, MNG_INVALIDMASK);
  6475. pTemp++;
  6476. iLen -= 2;
  6477. iLeft = 0;
  6478. iRight = 0;
  6479. iTop = 0;
  6480. iBottom = 0;
  6481. iObjectid = 0;
  6482. iIndex = 0;
  6483. switch (iMasktype)
  6484. {
  6485. case 1 :
  6486. {
  6487. if (iLen > 16)
  6488. {
  6489. iLeft = mng_get_int32 (pTemp);
  6490. iRight = mng_get_int32 (pTemp+4);
  6491. iTop = mng_get_int32 (pTemp+8);
  6492. iBottom = mng_get_int32 (pTemp+12);
  6493. pTemp += 16;
  6494. iLen -= 16;
  6495. }
  6496. else
  6497. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6498. break;
  6499. }
  6500. case 2 :
  6501. {
  6502. if (iLen > 2)
  6503. {
  6504. iObjectid = mng_get_uint16 (pTemp);
  6505. pTemp += 2;
  6506. iLen -= 2;
  6507. }
  6508. else
  6509. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6510. break;
  6511. }
  6512. case 3 :
  6513. {
  6514. if (iLen > 3)
  6515. {
  6516. iObjectid = mng_get_uint16 (pTemp);
  6517. iIndex = *(pTemp+2);
  6518. pTemp += 3;
  6519. iLen -= 3;
  6520. }
  6521. else
  6522. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6523. break;
  6524. }
  6525. case 4 :
  6526. {
  6527. if (iLen > 18)
  6528. {
  6529. iLeft = mng_get_int32 (pTemp);
  6530. iRight = mng_get_int32 (pTemp+4);
  6531. iTop = mng_get_int32 (pTemp+8);
  6532. iBottom = mng_get_int32 (pTemp+12);
  6533. iObjectid = mng_get_uint16 (pTemp+16);
  6534. pTemp += 18;
  6535. iLen -= 18;
  6536. }
  6537. else
  6538. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6539. break;
  6540. }
  6541. case 5 :
  6542. {
  6543. if (iLen > 19)
  6544. {
  6545. iLeft = mng_get_int32 (pTemp);
  6546. iRight = mng_get_int32 (pTemp+4);
  6547. iTop = mng_get_int32 (pTemp+8);
  6548. iBottom = mng_get_int32 (pTemp+12);
  6549. iObjectid = mng_get_uint16 (pTemp+16);
  6550. iIndex = *(pTemp+18);
  6551. pTemp += 19;
  6552. iLen -= 19;
  6553. }
  6554. else
  6555. MNG_ERROR (pData, MNG_INVALIDLENGTH);
  6556. break;
  6557. }
  6558. }
  6559. pNull = find_null (pTemp); /* get the name length */
  6560. if ((pNull - pTemp) > (mng_int32)iLen)
  6561. {
  6562. iNamesize = iLen; /* no null found; so end of evNT */
  6563. iLen = 0;
  6564. }
  6565. else
  6566. {
  6567. iNamesize = pNull - pTemp; /* should be another entry */
  6568. iLen = iLen - iNamesize - 1;
  6569. if (!iLen) /* must not end with a null ! */
  6570. MNG_ERROR (pData, MNG_ENDWITHNULL);
  6571. }
  6572. if (!iX)
  6573. {
  6574. iCount++;
  6575. }
  6576. else
  6577. {
  6578. pEntry->iEventtype = iEventtype;
  6579. pEntry->iMasktype = iMasktype;
  6580. pEntry->iLeft = iLeft;
  6581. pEntry->iRight = iRight;
  6582. pEntry->iTop = iTop;
  6583. pEntry->iBottom = iBottom;
  6584. pEntry->iObjectid = iObjectid;
  6585. pEntry->iIndex = iIndex;
  6586. pEntry->iSegmentnamesize = iNamesize;
  6587. if (iNamesize)
  6588. {
  6589. MNG_ALLOC (pData, pEntry->zSegmentname, iNamesize+1);
  6590. MNG_COPY (pEntry->zSegmentname, pTemp, iNamesize);
  6591. }
  6592. pEntry++;
  6593. }
  6594. pTemp = pTemp + iNamesize + 1;
  6595. }
  6596. }
  6597. }
  6598. }
  6599. #endif /* MNG_STORE_CHUNKS */
  6600. #ifdef MNG_SUPPORT_TRACE
  6601. MNG_TRACE (pData, MNG_FN_READ_EVNT, MNG_LC_END);
  6602. #endif
  6603. return MNG_NOERROR; /* done */
  6604. }
  6605. #endif
  6606. #endif
  6607. /* ************************************************************************** */
  6608. #ifndef MNG_OPTIMIZE_CHUNKREADER
  6609. READ_CHUNK (mng_read_unknown)
  6610. {
  6611. #ifdef MNG_SUPPORT_TRACE
  6612. MNG_TRACE (pData, MNG_FN_READ_UNKNOWN, MNG_LC_START);
  6613. #endif
  6614. /* sequence checks */
  6615. #ifdef MNG_INCLUDE_JNG
  6616. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  6617. (!pData->bHasBASI) && (!pData->bHasDHDR) && (!pData->bHasJHDR))
  6618. #else
  6619. if ((!pData->bHasMHDR) && (!pData->bHasIHDR) &&
  6620. (!pData->bHasBASI) && (!pData->bHasDHDR) )
  6621. #endif
  6622. MNG_ERROR (pData, MNG_SEQUENCEERROR);
  6623. /* critical chunk ? */
  6624. if ((((mng_uint32)pData->iChunkname & 0x20000000) == 0)
  6625. #ifdef MNG_SKIPCHUNK_SAVE
  6626. && (pData->iChunkname != MNG_UINT_SAVE)
  6627. #endif
  6628. #ifdef MNG_SKIPCHUNK_SEEK
  6629. && (pData->iChunkname != MNG_UINT_SEEK)
  6630. #endif
  6631. #ifdef MNG_SKIPCHUNK_DBYK
  6632. && (pData->iChunkname != MNG_UINT_DBYK)
  6633. #endif
  6634. #ifdef MNG_SKIPCHUNK_ORDR
  6635. && (pData->iChunkname != MNG_UINT_ORDR)
  6636. #endif
  6637. )
  6638. MNG_ERROR (pData, MNG_UNKNOWNCRITICAL);
  6639. if (pData->fProcessunknown) /* let the app handle it ? */
  6640. {
  6641. mng_bool bOke = pData->fProcessunknown ((mng_handle)pData, pData->iChunkname,
  6642. iRawlen, (mng_ptr)pRawdata);
  6643. if (!bOke)
  6644. MNG_ERROR (pData, MNG_APPMISCERROR);
  6645. }
  6646. #ifdef MNG_STORE_CHUNKS
  6647. if (pData->bStorechunks)
  6648. { /* initialize storage */
  6649. mng_retcode iRetcode = ((mng_chunk_headerp)pHeader)->fCreate (pData, pHeader, ppChunk);
  6650. if (iRetcode) /* on error bail out */
  6651. return iRetcode;
  6652. /* store the length */
  6653. ((mng_chunk_headerp)*ppChunk)->iChunkname = pData->iChunkname;
  6654. ((mng_unknown_chunkp)*ppChunk)->iDatasize = iRawlen;
  6655. if (iRawlen == 0) /* any data at all ? */
  6656. ((mng_unknown_chunkp)*ppChunk)->pData = 0;
  6657. else
  6658. { /* then store it */
  6659. MNG_ALLOC (pData, ((mng_unknown_chunkp)*ppChunk)->pData, iRawlen);
  6660. MNG_COPY (((mng_unknown_chunkp)*ppChunk)->pData, pRawdata, iRawlen);
  6661. }
  6662. }
  6663. #endif /* MNG_STORE_CHUNKS */
  6664. #ifdef MNG_SUPPORT_TRACE
  6665. MNG_TRACE (pData, MNG_FN_READ_UNKNOWN, MNG_LC_END);
  6666. #endif
  6667. return MNG_NOERROR; /* done */
  6668. }
  6669. #endif
  6670. /* ************************************************************************** */
  6671. #endif /* MNG_INCLUDE_READ_PROCS */
  6672. /* ************************************************************************** */
  6673. /* * * */
  6674. /* * chunk write functions * */
  6675. /* * * */
  6676. /* ************************************************************************** */
  6677. #ifdef MNG_INCLUDE_WRITE_PROCS
  6678. /* ************************************************************************** */
  6679. WRITE_CHUNK (mng_write_ihdr)
  6680. {
  6681. mng_ihdrp pIHDR;
  6682. mng_uint8p pRawdata;
  6683. mng_uint32 iRawlen;
  6684. mng_retcode iRetcode;
  6685. #ifdef MNG_SUPPORT_TRACE
  6686. MNG_TRACE (pData, MNG_FN_WRITE_IHDR, MNG_LC_START);
  6687. #endif
  6688. pIHDR = (mng_ihdrp)pChunk; /* address the proper chunk */
  6689. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  6690. iRawlen = 13;
  6691. /* fill the output buffer */
  6692. mng_put_uint32 (pRawdata, pIHDR->iWidth);
  6693. mng_put_uint32 (pRawdata+4, pIHDR->iHeight);
  6694. *(pRawdata+8) = pIHDR->iBitdepth;
  6695. *(pRawdata+9) = pIHDR->iColortype;
  6696. *(pRawdata+10) = pIHDR->iCompression;
  6697. *(pRawdata+11) = pIHDR->iFilter;
  6698. *(pRawdata+12) = pIHDR->iInterlace;
  6699. /* and write it */
  6700. iRetcode = write_raw_chunk (pData, pIHDR->sHeader.iChunkname, iRawlen, pRawdata);
  6701. #ifdef MNG_SUPPORT_TRACE
  6702. MNG_TRACE (pData, MNG_FN_WRITE_IHDR, MNG_LC_END);
  6703. #endif
  6704. return iRetcode;
  6705. }
  6706. /* ************************************************************************** */
  6707. WRITE_CHUNK (mng_write_plte)
  6708. {
  6709. mng_pltep pPLTE;
  6710. mng_uint8p pRawdata;
  6711. mng_uint32 iRawlen;
  6712. mng_retcode iRetcode;
  6713. mng_uint8p pTemp;
  6714. mng_uint32 iX;
  6715. #ifdef MNG_SUPPORT_TRACE
  6716. MNG_TRACE (pData, MNG_FN_WRITE_PLTE, MNG_LC_START);
  6717. #endif
  6718. pPLTE = (mng_pltep)pChunk; /* address the proper chunk */
  6719. if (pPLTE->bEmpty) /* write empty chunk ? */
  6720. iRetcode = write_raw_chunk (pData, pPLTE->sHeader.iChunkname, 0, 0);
  6721. else
  6722. {
  6723. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  6724. iRawlen = pPLTE->iEntrycount * 3;
  6725. /* fill the output buffer */
  6726. pTemp = pRawdata;
  6727. for (iX = 0; iX < pPLTE->iEntrycount; iX++)
  6728. {
  6729. *pTemp = pPLTE->aEntries [iX].iRed;
  6730. *(pTemp+1) = pPLTE->aEntries [iX].iGreen;
  6731. *(pTemp+2) = pPLTE->aEntries [iX].iBlue;
  6732. pTemp += 3;
  6733. }
  6734. /* and write it */
  6735. iRetcode = write_raw_chunk (pData, pPLTE->sHeader.iChunkname, iRawlen, pRawdata);
  6736. }
  6737. #ifdef MNG_SUPPORT_TRACE
  6738. MNG_TRACE (pData, MNG_FN_WRITE_PLTE, MNG_LC_END);
  6739. #endif
  6740. return iRetcode;
  6741. }
  6742. /* ************************************************************************** */
  6743. WRITE_CHUNK (mng_write_idat)
  6744. {
  6745. mng_idatp pIDAT;
  6746. mng_retcode iRetcode;
  6747. #ifdef MNG_SUPPORT_TRACE
  6748. MNG_TRACE (pData, MNG_FN_WRITE_IDAT, MNG_LC_START);
  6749. #endif
  6750. pIDAT = (mng_idatp)pChunk; /* address the proper chunk */
  6751. if (pIDAT->bEmpty) /* and write it */
  6752. iRetcode = write_raw_chunk (pData, pIDAT->sHeader.iChunkname, 0, 0);
  6753. else
  6754. iRetcode = write_raw_chunk (pData, pIDAT->sHeader.iChunkname,
  6755. pIDAT->iDatasize, pIDAT->pData);
  6756. #ifdef MNG_SUPPORT_TRACE
  6757. MNG_TRACE (pData, MNG_FN_WRITE_IDAT, MNG_LC_END);
  6758. #endif
  6759. return iRetcode;
  6760. }
  6761. /* ************************************************************************** */
  6762. WRITE_CHUNK (mng_write_iend)
  6763. {
  6764. mng_iendp pIEND;
  6765. mng_retcode iRetcode;
  6766. #ifdef MNG_SUPPORT_TRACE
  6767. MNG_TRACE (pData, MNG_FN_WRITE_IEND, MNG_LC_START);
  6768. #endif
  6769. pIEND = (mng_iendp)pChunk; /* address the proper chunk */
  6770. /* and write it */
  6771. iRetcode = write_raw_chunk (pData, pIEND->sHeader.iChunkname, 0, 0);
  6772. #ifdef MNG_SUPPORT_TRACE
  6773. MNG_TRACE (pData, MNG_FN_WRITE_IEND, MNG_LC_END);
  6774. #endif
  6775. return iRetcode;
  6776. }
  6777. /* ************************************************************************** */
  6778. WRITE_CHUNK (mng_write_trns)
  6779. {
  6780. mng_trnsp pTRNS;
  6781. mng_uint8p pRawdata;
  6782. mng_uint32 iRawlen;
  6783. mng_retcode iRetcode;
  6784. mng_uint8p pTemp;
  6785. mng_uint32 iX;
  6786. #ifdef MNG_SUPPORT_TRACE
  6787. MNG_TRACE (pData, MNG_FN_WRITE_TRNS, MNG_LC_START);
  6788. #endif
  6789. pTRNS = (mng_trnsp)pChunk; /* address the proper chunk */
  6790. if (pTRNS->bEmpty) /* write empty chunk ? */
  6791. iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname, 0, 0);
  6792. else
  6793. if (pTRNS->bGlobal) /* write global chunk ? */
  6794. iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname,
  6795. pTRNS->iRawlen, (mng_uint8p)pTRNS->aRawdata);
  6796. else
  6797. {
  6798. pRawdata = pData->pWritebuf+8; /* init output buffer */
  6799. iRawlen = 0; /* and default size */
  6800. switch (pTRNS->iType)
  6801. {
  6802. case 0: {
  6803. iRawlen = 2; /* fill the size & output buffer */
  6804. mng_put_uint16 (pRawdata, pTRNS->iGray);
  6805. break;
  6806. }
  6807. case 2: {
  6808. iRawlen = 6; /* fill the size & output buffer */
  6809. mng_put_uint16 (pRawdata, pTRNS->iRed);
  6810. mng_put_uint16 (pRawdata+2, pTRNS->iGreen);
  6811. mng_put_uint16 (pRawdata+4, pTRNS->iBlue);
  6812. break;
  6813. }
  6814. case 3: { /* init output buffer size */
  6815. iRawlen = pTRNS->iCount;
  6816. pTemp = pRawdata; /* fill the output buffer */
  6817. for (iX = 0; iX < pTRNS->iCount; iX++)
  6818. {
  6819. *pTemp = pTRNS->aEntries[iX];
  6820. pTemp++;
  6821. }
  6822. break;
  6823. }
  6824. }
  6825. /* write the chunk */
  6826. iRetcode = write_raw_chunk (pData, pTRNS->sHeader.iChunkname,
  6827. iRawlen, pRawdata);
  6828. }
  6829. #ifdef MNG_SUPPORT_TRACE
  6830. MNG_TRACE (pData, MNG_FN_WRITE_TRNS, MNG_LC_END);
  6831. #endif
  6832. return iRetcode;
  6833. }
  6834. /* ************************************************************************** */
  6835. WRITE_CHUNK (mng_write_gama)
  6836. {
  6837. mng_gamap pGAMA;
  6838. mng_uint8p pRawdata;
  6839. mng_uint32 iRawlen;
  6840. mng_retcode iRetcode;
  6841. #ifdef MNG_SUPPORT_TRACE
  6842. MNG_TRACE (pData, MNG_FN_WRITE_GAMA, MNG_LC_START);
  6843. #endif
  6844. pGAMA = (mng_gamap)pChunk; /* address the proper chunk */
  6845. if (pGAMA->bEmpty) /* write empty ? */
  6846. iRetcode = write_raw_chunk (pData, pGAMA->sHeader.iChunkname, 0, 0);
  6847. else
  6848. {
  6849. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  6850. iRawlen = 4;
  6851. /* fill the buffer */
  6852. mng_put_uint32 (pRawdata, pGAMA->iGamma);
  6853. /* and write it */
  6854. iRetcode = write_raw_chunk (pData, pGAMA->sHeader.iChunkname,
  6855. iRawlen, pRawdata);
  6856. }
  6857. #ifdef MNG_SUPPORT_TRACE
  6858. MNG_TRACE (pData, MNG_FN_WRITE_GAMA, MNG_LC_END);
  6859. #endif
  6860. return iRetcode;
  6861. }
  6862. /* ************************************************************************** */
  6863. #ifndef MNG_SKIPCHUNK_cHRM
  6864. WRITE_CHUNK (mng_write_chrm)
  6865. {
  6866. mng_chrmp pCHRM;
  6867. mng_uint8p pRawdata;
  6868. mng_uint32 iRawlen;
  6869. mng_retcode iRetcode;
  6870. #ifdef MNG_SUPPORT_TRACE
  6871. MNG_TRACE (pData, MNG_FN_WRITE_CHRM, MNG_LC_START);
  6872. #endif
  6873. pCHRM = (mng_chrmp)pChunk; /* address the proper chunk */
  6874. if (pCHRM->bEmpty) /* write empty ? */
  6875. iRetcode = write_raw_chunk (pData, pCHRM->sHeader.iChunkname, 0, 0);
  6876. else
  6877. {
  6878. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  6879. iRawlen = 32;
  6880. /* fill the buffer */
  6881. mng_put_uint32 (pRawdata, pCHRM->iWhitepointx);
  6882. mng_put_uint32 (pRawdata+4, pCHRM->iWhitepointy);
  6883. mng_put_uint32 (pRawdata+8, pCHRM->iRedx);
  6884. mng_put_uint32 (pRawdata+12, pCHRM->iRedy);
  6885. mng_put_uint32 (pRawdata+16, pCHRM->iGreenx);
  6886. mng_put_uint32 (pRawdata+20, pCHRM->iGreeny);
  6887. mng_put_uint32 (pRawdata+24, pCHRM->iBluex);
  6888. mng_put_uint32 (pRawdata+28, pCHRM->iBluey);
  6889. /* and write it */
  6890. iRetcode = write_raw_chunk (pData, pCHRM->sHeader.iChunkname,
  6891. iRawlen, pRawdata);
  6892. }
  6893. #ifdef MNG_SUPPORT_TRACE
  6894. MNG_TRACE (pData, MNG_FN_WRITE_CHRM, MNG_LC_END);
  6895. #endif
  6896. return iRetcode;
  6897. }
  6898. #endif
  6899. /* ************************************************************************** */
  6900. WRITE_CHUNK (mng_write_srgb)
  6901. {
  6902. mng_srgbp pSRGB;
  6903. mng_uint8p pRawdata;
  6904. mng_uint32 iRawlen;
  6905. mng_retcode iRetcode;
  6906. #ifdef MNG_SUPPORT_TRACE
  6907. MNG_TRACE (pData, MNG_FN_WRITE_SRGB, MNG_LC_START);
  6908. #endif
  6909. pSRGB = (mng_srgbp)pChunk; /* address the proper chunk */
  6910. if (pSRGB->bEmpty) /* write empty ? */
  6911. iRetcode = write_raw_chunk (pData, pSRGB->sHeader.iChunkname, 0, 0);
  6912. else
  6913. {
  6914. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  6915. iRawlen = 1;
  6916. /* fill the buffer */
  6917. *pRawdata = pSRGB->iRenderingintent;
  6918. /* and write it */
  6919. iRetcode = write_raw_chunk (pData, pSRGB->sHeader.iChunkname,
  6920. iRawlen, pRawdata);
  6921. }
  6922. #ifdef MNG_SUPPORT_TRACE
  6923. MNG_TRACE (pData, MNG_FN_WRITE_SRGB, MNG_LC_END);
  6924. #endif
  6925. return iRetcode;
  6926. }
  6927. /* ************************************************************************** */
  6928. #ifndef MNG_SKIPCHUNK_iCCP
  6929. WRITE_CHUNK (mng_write_iccp)
  6930. {
  6931. mng_iccpp pICCP;
  6932. mng_uint8p pRawdata;
  6933. mng_uint32 iRawlen;
  6934. mng_retcode iRetcode;
  6935. mng_uint8p pTemp;
  6936. mng_uint8p pBuf = 0;
  6937. mng_uint32 iBuflen;
  6938. mng_uint32 iReallen;
  6939. #ifdef MNG_SUPPORT_TRACE
  6940. MNG_TRACE (pData, MNG_FN_WRITE_ICCP, MNG_LC_START);
  6941. #endif
  6942. pICCP = (mng_iccpp)pChunk; /* address the proper chunk */
  6943. if (pICCP->bEmpty) /* write empty ? */
  6944. iRetcode = write_raw_chunk (pData, pICCP->sHeader.iChunkname, 0, 0);
  6945. else
  6946. { /* compress the profile */
  6947. iRetcode = deflate_buffer (pData, pICCP->pProfile, pICCP->iProfilesize,
  6948. &pBuf, &iBuflen, &iReallen);
  6949. if (!iRetcode) /* still oke ? */
  6950. {
  6951. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  6952. iRawlen = pICCP->iNamesize + 2 + iReallen;
  6953. /* requires large buffer ? */
  6954. if (iRawlen > pData->iWritebufsize)
  6955. MNG_ALLOC (pData, pRawdata, iRawlen);
  6956. pTemp = pRawdata; /* fill the buffer */
  6957. if (pICCP->iNamesize)
  6958. {
  6959. MNG_COPY (pTemp, pICCP->zName, pICCP->iNamesize);
  6960. pTemp += pICCP->iNamesize;
  6961. }
  6962. *pTemp = 0;
  6963. *(pTemp+1) = pICCP->iCompression;
  6964. pTemp += 2;
  6965. if (iReallen)
  6966. MNG_COPY (pTemp, pBuf, iReallen);
  6967. /* and write it */
  6968. iRetcode = write_raw_chunk (pData, pICCP->sHeader.iChunkname,
  6969. iRawlen, pRawdata);
  6970. /* drop the temp buffer ? */
  6971. if (iRawlen > pData->iWritebufsize)
  6972. MNG_FREEX (pData, pRawdata, iRawlen);
  6973. }
  6974. MNG_FREEX (pData, pBuf, iBuflen); /* always drop the extra buffer */
  6975. }
  6976. #ifdef MNG_SUPPORT_TRACE
  6977. MNG_TRACE (pData, MNG_FN_WRITE_ICCP, MNG_LC_END);
  6978. #endif
  6979. return iRetcode;
  6980. }
  6981. #endif
  6982. /* ************************************************************************** */
  6983. #ifndef MNG_SKIPCHUNK_tEXt
  6984. WRITE_CHUNK (mng_write_text)
  6985. {
  6986. mng_textp pTEXT;
  6987. mng_uint8p pRawdata;
  6988. mng_uint32 iRawlen;
  6989. mng_retcode iRetcode;
  6990. mng_uint8p pTemp;
  6991. #ifdef MNG_SUPPORT_TRACE
  6992. MNG_TRACE (pData, MNG_FN_WRITE_TEXT, MNG_LC_START);
  6993. #endif
  6994. pTEXT = (mng_textp)pChunk; /* address the proper chunk */
  6995. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  6996. iRawlen = pTEXT->iKeywordsize + 1 + pTEXT->iTextsize;
  6997. /* requires large buffer ? */
  6998. if (iRawlen > pData->iWritebufsize)
  6999. MNG_ALLOC (pData, pRawdata, iRawlen);
  7000. pTemp = pRawdata; /* fill the buffer */
  7001. if (pTEXT->iKeywordsize)
  7002. {
  7003. MNG_COPY (pTemp, pTEXT->zKeyword, pTEXT->iKeywordsize);
  7004. pTemp += pTEXT->iKeywordsize;
  7005. }
  7006. *pTemp = 0;
  7007. pTemp += 1;
  7008. if (pTEXT->iTextsize)
  7009. MNG_COPY (pTemp, pTEXT->zText, pTEXT->iTextsize);
  7010. /* and write it */
  7011. iRetcode = write_raw_chunk (pData, pTEXT->sHeader.iChunkname,
  7012. iRawlen, pRawdata);
  7013. if (iRawlen > pData->iWritebufsize) /* drop the temp buffer ? */
  7014. MNG_FREEX (pData, pRawdata, iRawlen);
  7015. #ifdef MNG_SUPPORT_TRACE
  7016. MNG_TRACE (pData, MNG_FN_WRITE_TEXT, MNG_LC_END);
  7017. #endif
  7018. return iRetcode;
  7019. }
  7020. #endif
  7021. /* ************************************************************************** */
  7022. #ifndef MNG_SKIPCHUNK_zTXt
  7023. WRITE_CHUNK (mng_write_ztxt)
  7024. {
  7025. mng_ztxtp pZTXT;
  7026. mng_uint8p pRawdata;
  7027. mng_uint32 iRawlen;
  7028. mng_retcode iRetcode;
  7029. mng_uint8p pTemp;
  7030. mng_uint8p pBuf = 0;
  7031. mng_uint32 iBuflen;
  7032. mng_uint32 iReallen;
  7033. #ifdef MNG_SUPPORT_TRACE
  7034. MNG_TRACE (pData, MNG_FN_WRITE_ZTXT, MNG_LC_START);
  7035. #endif
  7036. pZTXT = (mng_ztxtp)pChunk; /* address the proper chunk */
  7037. /* compress the text */
  7038. iRetcode = deflate_buffer (pData, (mng_uint8p)pZTXT->zText, pZTXT->iTextsize,
  7039. &pBuf, &iBuflen, &iReallen);
  7040. if (!iRetcode) /* all ok ? */
  7041. {
  7042. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7043. iRawlen = pZTXT->iKeywordsize + 2 + iReallen;
  7044. /* requires large buffer ? */
  7045. if (iRawlen > pData->iWritebufsize)
  7046. MNG_ALLOC (pData, pRawdata, iRawlen);
  7047. pTemp = pRawdata; /* fill the buffer */
  7048. if (pZTXT->iKeywordsize)
  7049. {
  7050. MNG_COPY (pTemp, pZTXT->zKeyword, pZTXT->iKeywordsize);
  7051. pTemp += pZTXT->iKeywordsize;
  7052. }
  7053. *pTemp = 0; /* terminator zero */
  7054. pTemp++;
  7055. *pTemp = 0; /* compression type */
  7056. pTemp++;
  7057. if (iReallen)
  7058. MNG_COPY (pTemp, pBuf, iReallen);
  7059. /* and write it */
  7060. iRetcode = write_raw_chunk (pData, pZTXT->sHeader.iChunkname,
  7061. iRawlen, pRawdata);
  7062. /* drop the temp buffer ? */
  7063. if (iRawlen > pData->iWritebufsize)
  7064. MNG_FREEX (pData, pRawdata, iRawlen);
  7065. }
  7066. MNG_FREEX (pData, pBuf, iBuflen); /* always drop the compression buffer */
  7067. #ifdef MNG_SUPPORT_TRACE
  7068. MNG_TRACE (pData, MNG_FN_WRITE_ZTXT, MNG_LC_END);
  7069. #endif
  7070. return iRetcode;
  7071. }
  7072. #endif
  7073. /* ************************************************************************** */
  7074. #ifndef MNG_SKIPCHUNK_iTXt
  7075. WRITE_CHUNK (mng_write_itxt)
  7076. {
  7077. mng_itxtp pITXT;
  7078. mng_uint8p pRawdata;
  7079. mng_uint32 iRawlen;
  7080. mng_retcode iRetcode;
  7081. mng_uint8p pTemp;
  7082. mng_uint8p pBuf = 0;
  7083. mng_uint32 iBuflen;
  7084. mng_uint32 iReallen;
  7085. #ifdef MNG_SUPPORT_TRACE
  7086. MNG_TRACE (pData, MNG_FN_WRITE_ITXT, MNG_LC_START);
  7087. #endif
  7088. pITXT = (mng_itxtp)pChunk; /* address the proper chunk */
  7089. if (pITXT->iCompressionflag) /* compress the text */
  7090. iRetcode = deflate_buffer (pData, (mng_uint8p)pITXT->zText, pITXT->iTextsize,
  7091. &pBuf, &iBuflen, &iReallen);
  7092. else
  7093. iRetcode = MNG_NOERROR;
  7094. if (!iRetcode) /* all ok ? */
  7095. {
  7096. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7097. iRawlen = pITXT->iKeywordsize + pITXT->iLanguagesize +
  7098. pITXT->iTranslationsize + 5;
  7099. if (pITXT->iCompressionflag)
  7100. iRawlen = iRawlen + iReallen;
  7101. else
  7102. iRawlen = iRawlen + pITXT->iTextsize;
  7103. /* requires large buffer ? */
  7104. if (iRawlen > pData->iWritebufsize)
  7105. MNG_ALLOC (pData, pRawdata, iRawlen);
  7106. pTemp = pRawdata; /* fill the buffer */
  7107. if (pITXT->iKeywordsize)
  7108. {
  7109. MNG_COPY (pTemp, pITXT->zKeyword, pITXT->iKeywordsize);
  7110. pTemp += pITXT->iKeywordsize;
  7111. }
  7112. *pTemp = 0;
  7113. pTemp++;
  7114. *pTemp = pITXT->iCompressionflag;
  7115. pTemp++;
  7116. *pTemp = pITXT->iCompressionmethod;
  7117. pTemp++;
  7118. if (pITXT->iLanguagesize)
  7119. {
  7120. MNG_COPY (pTemp, pITXT->zLanguage, pITXT->iLanguagesize);
  7121. pTemp += pITXT->iLanguagesize;
  7122. }
  7123. *pTemp = 0;
  7124. pTemp++;
  7125. if (pITXT->iTranslationsize)
  7126. {
  7127. MNG_COPY (pTemp, pITXT->zTranslation, pITXT->iTranslationsize);
  7128. pTemp += pITXT->iTranslationsize;
  7129. }
  7130. *pTemp = 0;
  7131. pTemp++;
  7132. if (pITXT->iCompressionflag)
  7133. {
  7134. if (iReallen)
  7135. MNG_COPY (pTemp, pBuf, iReallen);
  7136. }
  7137. else
  7138. {
  7139. if (pITXT->iTextsize)
  7140. MNG_COPY (pTemp, pITXT->zText, pITXT->iTextsize);
  7141. }
  7142. /* and write it */
  7143. iRetcode = write_raw_chunk (pData, pITXT->sHeader.iChunkname,
  7144. iRawlen, pRawdata);
  7145. /* drop the temp buffer ? */
  7146. if (iRawlen > pData->iWritebufsize)
  7147. MNG_FREEX (pData, pRawdata, iRawlen);
  7148. }
  7149. MNG_FREEX (pData, pBuf, iBuflen); /* always drop the compression buffer */
  7150. if (iRetcode) /* on error bail out */
  7151. return iRetcode;
  7152. #ifdef MNG_SUPPORT_TRACE
  7153. MNG_TRACE (pData, MNG_FN_WRITE_ITXT, MNG_LC_END);
  7154. #endif
  7155. return MNG_NOERROR;
  7156. }
  7157. #endif
  7158. /* ************************************************************************** */
  7159. #ifndef MNG_SKIPCHUNK_bKGD
  7160. WRITE_CHUNK (mng_write_bkgd)
  7161. {
  7162. mng_bkgdp pBKGD;
  7163. mng_uint8p pRawdata;
  7164. mng_uint32 iRawlen;
  7165. mng_retcode iRetcode;
  7166. #ifdef MNG_SUPPORT_TRACE
  7167. MNG_TRACE (pData, MNG_FN_WRITE_BKGD, MNG_LC_START);
  7168. #endif
  7169. pBKGD = (mng_bkgdp)pChunk; /* address the proper chunk */
  7170. if (pBKGD->bEmpty) /* write empty ? */
  7171. iRetcode = write_raw_chunk (pData, pBKGD->sHeader.iChunkname, 0, 0);
  7172. else
  7173. {
  7174. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7175. iRawlen = 0; /* and default size */
  7176. switch (pBKGD->iType)
  7177. {
  7178. case 0: { /* gray */
  7179. iRawlen = 2; /* fill the size & output buffer */
  7180. mng_put_uint16 (pRawdata, pBKGD->iGray);
  7181. break;
  7182. }
  7183. case 2: { /* rgb */
  7184. iRawlen = 6; /* fill the size & output buffer */
  7185. mng_put_uint16 (pRawdata, pBKGD->iRed);
  7186. mng_put_uint16 (pRawdata+2, pBKGD->iGreen);
  7187. mng_put_uint16 (pRawdata+4, pBKGD->iBlue);
  7188. break;
  7189. }
  7190. case 3: { /* indexed */
  7191. iRawlen = 1; /* fill the size & output buffer */
  7192. *pRawdata = pBKGD->iIndex;
  7193. break;
  7194. }
  7195. }
  7196. /* and write it */
  7197. iRetcode = write_raw_chunk (pData, pBKGD->sHeader.iChunkname,
  7198. iRawlen, pRawdata);
  7199. }
  7200. #ifdef MNG_SUPPORT_TRACE
  7201. MNG_TRACE (pData, MNG_FN_WRITE_BKGD, MNG_LC_END);
  7202. #endif
  7203. return iRetcode;
  7204. }
  7205. #endif
  7206. /* ************************************************************************** */
  7207. #ifndef MNG_SKIPCHUNK_pHYs
  7208. WRITE_CHUNK (mng_write_phys)
  7209. {
  7210. mng_physp pPHYS;
  7211. mng_uint8p pRawdata;
  7212. mng_uint32 iRawlen;
  7213. mng_retcode iRetcode;
  7214. #ifdef MNG_SUPPORT_TRACE
  7215. MNG_TRACE (pData, MNG_FN_WRITE_PHYS, MNG_LC_START);
  7216. #endif
  7217. pPHYS = (mng_physp)pChunk; /* address the proper chunk */
  7218. if (pPHYS->bEmpty) /* write empty ? */
  7219. iRetcode = write_raw_chunk (pData, pPHYS->sHeader.iChunkname, 0, 0);
  7220. else
  7221. {
  7222. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7223. iRawlen = 9;
  7224. /* fill the output buffer */
  7225. mng_put_uint32 (pRawdata, pPHYS->iSizex);
  7226. mng_put_uint32 (pRawdata+4, pPHYS->iSizey);
  7227. *(pRawdata+8) = pPHYS->iUnit;
  7228. /* and write it */
  7229. iRetcode = write_raw_chunk (pData, pPHYS->sHeader.iChunkname,
  7230. iRawlen, pRawdata);
  7231. }
  7232. #ifdef MNG_SUPPORT_TRACE
  7233. MNG_TRACE (pData, MNG_FN_WRITE_PHYS, MNG_LC_END);
  7234. #endif
  7235. return iRetcode;
  7236. }
  7237. #endif
  7238. /* ************************************************************************** */
  7239. #ifndef MNG_SKIPCHUNK_sBIT
  7240. WRITE_CHUNK (mng_write_sbit)
  7241. {
  7242. mng_sbitp pSBIT;
  7243. mng_uint8p pRawdata;
  7244. mng_uint32 iRawlen;
  7245. mng_retcode iRetcode;
  7246. #ifdef MNG_SUPPORT_TRACE
  7247. MNG_TRACE (pData, MNG_FN_WRITE_SBIT, MNG_LC_START);
  7248. #endif
  7249. pSBIT = (mng_sbitp)pChunk; /* address the proper chunk */
  7250. if (pSBIT->bEmpty) /* write empty ? */
  7251. iRetcode = write_raw_chunk (pData, pSBIT->sHeader.iChunkname, 0, 0);
  7252. else
  7253. {
  7254. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7255. iRawlen = 0; /* and default size */
  7256. switch (pSBIT->iType)
  7257. {
  7258. case 0: { /* gray */
  7259. iRawlen = 1; /* fill the size & output buffer */
  7260. *pRawdata = pSBIT->aBits[0];
  7261. break;
  7262. }
  7263. case 2: { /* rgb */
  7264. iRawlen = 3; /* fill the size & output buffer */
  7265. *pRawdata = pSBIT->aBits[0];
  7266. *(pRawdata+1) = pSBIT->aBits[1];
  7267. *(pRawdata+2) = pSBIT->aBits[2];
  7268. break;
  7269. }
  7270. case 3: { /* indexed */
  7271. iRawlen = 3; /* fill the size & output buffer */
  7272. *pRawdata = pSBIT->aBits[0];
  7273. *pRawdata = pSBIT->aBits[1];
  7274. *pRawdata = pSBIT->aBits[2];
  7275. break;
  7276. }
  7277. case 4: { /* gray + alpha */
  7278. iRawlen = 2; /* fill the size & output buffer */
  7279. *pRawdata = pSBIT->aBits[0];
  7280. *(pRawdata+1) = pSBIT->aBits[1];
  7281. break;
  7282. }
  7283. case 6: { /* rgb + alpha */
  7284. iRawlen = 4; /* fill the size & output buffer */
  7285. *pRawdata = pSBIT->aBits[0];
  7286. *(pRawdata+1) = pSBIT->aBits[1];
  7287. *(pRawdata+2) = pSBIT->aBits[2];
  7288. *(pRawdata+3) = pSBIT->aBits[3];
  7289. break;
  7290. }
  7291. case 10: { /* jpeg gray */
  7292. iRawlen = 1; /* fill the size & output buffer */
  7293. *pRawdata = pSBIT->aBits[0];
  7294. break;
  7295. }
  7296. case 12: { /* jpeg rgb */
  7297. iRawlen = 3; /* fill the size & output buffer */
  7298. *pRawdata = pSBIT->aBits[0];
  7299. *(pRawdata+1) = pSBIT->aBits[1];
  7300. *(pRawdata+2) = pSBIT->aBits[2];
  7301. break;
  7302. }
  7303. case 14: { /* jpeg gray + alpha */
  7304. iRawlen = 2; /* fill the size & output buffer */
  7305. *pRawdata = pSBIT->aBits[0];
  7306. *(pRawdata+1) = pSBIT->aBits[1];
  7307. break;
  7308. }
  7309. case 16: { /* jpeg rgb + alpha */
  7310. iRawlen = 4; /* fill the size & output buffer */
  7311. *pRawdata = pSBIT->aBits[0];
  7312. *(pRawdata+1) = pSBIT->aBits[1];
  7313. *(pRawdata+2) = pSBIT->aBits[2];
  7314. *(pRawdata+3) = pSBIT->aBits[3];
  7315. break;
  7316. }
  7317. }
  7318. /* and write it */
  7319. iRetcode = write_raw_chunk (pData, pSBIT->sHeader.iChunkname,
  7320. iRawlen, pRawdata);
  7321. }
  7322. #ifdef MNG_SUPPORT_TRACE
  7323. MNG_TRACE (pData, MNG_FN_WRITE_SBIT, MNG_LC_END);
  7324. #endif
  7325. return iRetcode;
  7326. }
  7327. #endif
  7328. /* ************************************************************************** */
  7329. #ifndef MNG_SKIPCHUNK_sPLT
  7330. WRITE_CHUNK (mng_write_splt)
  7331. {
  7332. mng_spltp pSPLT;
  7333. mng_uint8p pRawdata;
  7334. mng_uint32 iRawlen;
  7335. mng_retcode iRetcode;
  7336. mng_uint32 iEntrieslen;
  7337. mng_uint8p pTemp;
  7338. #ifdef MNG_SUPPORT_TRACE
  7339. MNG_TRACE (pData, MNG_FN_WRITE_SPLT, MNG_LC_START);
  7340. #endif
  7341. pSPLT = (mng_spltp)pChunk; /* address the proper chunk */
  7342. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7343. iEntrieslen = ((pSPLT->iSampledepth >> 3) * 4 + 2) * pSPLT->iEntrycount;
  7344. iRawlen = pSPLT->iNamesize + 2 + iEntrieslen;
  7345. /* requires large buffer ? */
  7346. if (iRawlen > pData->iWritebufsize)
  7347. MNG_ALLOC (pData, pRawdata, iRawlen);
  7348. pTemp = pRawdata; /* fill the buffer */
  7349. if (pSPLT->iNamesize)
  7350. {
  7351. MNG_COPY (pTemp, pSPLT->zName, pSPLT->iNamesize);
  7352. pTemp += pSPLT->iNamesize;
  7353. }
  7354. *pTemp = 0;
  7355. *(pTemp+1) = pSPLT->iSampledepth;
  7356. pTemp += 2;
  7357. if (pSPLT->iEntrycount)
  7358. MNG_COPY (pTemp, pSPLT->pEntries, iEntrieslen);
  7359. /* and write it */
  7360. iRetcode = write_raw_chunk (pData, pSPLT->sHeader.iChunkname,
  7361. iRawlen, pRawdata);
  7362. if (iRawlen > pData->iWritebufsize) /* drop the temp buffer ? */
  7363. MNG_FREEX (pData, pRawdata, iRawlen);
  7364. #ifdef MNG_SUPPORT_TRACE
  7365. MNG_TRACE (pData, MNG_FN_WRITE_SPLT, MNG_LC_END);
  7366. #endif
  7367. return iRetcode;
  7368. }
  7369. #endif
  7370. /* ************************************************************************** */
  7371. #ifndef MNG_SKIPCHUNK_hIST
  7372. WRITE_CHUNK (mng_write_hist)
  7373. {
  7374. mng_histp pHIST;
  7375. mng_uint8p pRawdata;
  7376. mng_uint32 iRawlen;
  7377. mng_retcode iRetcode;
  7378. mng_uint8p pTemp;
  7379. mng_uint32 iX;
  7380. #ifdef MNG_SUPPORT_TRACE
  7381. MNG_TRACE (pData, MNG_FN_WRITE_HIST, MNG_LC_START);
  7382. #endif
  7383. pHIST = (mng_histp)pChunk; /* address the proper chunk */
  7384. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7385. iRawlen = pHIST->iEntrycount << 1;
  7386. pTemp = pRawdata; /* fill the output buffer */
  7387. for (iX = 0; iX < pHIST->iEntrycount; iX++)
  7388. {
  7389. mng_put_uint16 (pTemp, pHIST->aEntries [iX]);
  7390. pTemp += 2;
  7391. }
  7392. /* and write it */
  7393. iRetcode = write_raw_chunk (pData, pHIST->sHeader.iChunkname,
  7394. iRawlen, pRawdata);
  7395. #ifdef MNG_SUPPORT_TRACE
  7396. MNG_TRACE (pData, MNG_FN_WRITE_HIST, MNG_LC_END);
  7397. #endif
  7398. return iRetcode;
  7399. }
  7400. #endif
  7401. /* ************************************************************************** */
  7402. #ifndef MNG_SKIPCHUNK_tIME
  7403. WRITE_CHUNK (mng_write_time)
  7404. {
  7405. mng_timep pTIME;
  7406. mng_uint8p pRawdata;
  7407. mng_uint32 iRawlen;
  7408. mng_retcode iRetcode;
  7409. #ifdef MNG_SUPPORT_TRACE
  7410. MNG_TRACE (pData, MNG_FN_WRITE_TIME, MNG_LC_START);
  7411. #endif
  7412. pTIME = (mng_timep)pChunk; /* address the proper chunk */
  7413. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7414. iRawlen = 7;
  7415. /* fill the output buffer */
  7416. mng_put_uint16 (pRawdata, pTIME->iYear);
  7417. *(pRawdata+2) = pTIME->iMonth;
  7418. *(pRawdata+3) = pTIME->iDay;
  7419. *(pRawdata+4) = pTIME->iHour;
  7420. *(pRawdata+5) = pTIME->iMinute;
  7421. *(pRawdata+6) = pTIME->iSecond;
  7422. /* and write it */
  7423. iRetcode = write_raw_chunk (pData, pTIME->sHeader.iChunkname,
  7424. iRawlen, pRawdata);
  7425. #ifdef MNG_SUPPORT_TRACE
  7426. MNG_TRACE (pData, MNG_FN_WRITE_TIME, MNG_LC_END);
  7427. #endif
  7428. return iRetcode;
  7429. }
  7430. #endif
  7431. /* ************************************************************************** */
  7432. WRITE_CHUNK (mng_write_mhdr)
  7433. {
  7434. mng_mhdrp pMHDR;
  7435. mng_uint8p pRawdata;
  7436. mng_uint32 iRawlen;
  7437. mng_retcode iRetcode;
  7438. #ifdef MNG_SUPPORT_TRACE
  7439. MNG_TRACE (pData, MNG_FN_WRITE_MHDR, MNG_LC_START);
  7440. #endif
  7441. pMHDR = (mng_mhdrp)pChunk; /* address the proper chunk */
  7442. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7443. iRawlen = 28;
  7444. /* fill the output buffer */
  7445. mng_put_uint32 (pRawdata, pMHDR->iWidth);
  7446. mng_put_uint32 (pRawdata+4, pMHDR->iHeight);
  7447. mng_put_uint32 (pRawdata+8, pMHDR->iTicks);
  7448. mng_put_uint32 (pRawdata+12, pMHDR->iLayercount);
  7449. mng_put_uint32 (pRawdata+16, pMHDR->iFramecount);
  7450. mng_put_uint32 (pRawdata+20, pMHDR->iPlaytime);
  7451. mng_put_uint32 (pRawdata+24, pMHDR->iSimplicity);
  7452. /* and write it */
  7453. iRetcode = write_raw_chunk (pData, pMHDR->sHeader.iChunkname,
  7454. iRawlen, pRawdata);
  7455. #ifdef MNG_SUPPORT_TRACE
  7456. MNG_TRACE (pData, MNG_FN_WRITE_MHDR, MNG_LC_END);
  7457. #endif
  7458. return iRetcode;
  7459. }
  7460. /* ************************************************************************** */
  7461. WRITE_CHUNK (mng_write_mend)
  7462. {
  7463. mng_mendp pMEND;
  7464. mng_retcode iRetcode;
  7465. #ifdef MNG_SUPPORT_TRACE
  7466. MNG_TRACE (pData, MNG_FN_WRITE_MEND, MNG_LC_START);
  7467. #endif
  7468. pMEND = (mng_mendp)pChunk; /* address the proper chunk */
  7469. /* and write it */
  7470. iRetcode = write_raw_chunk (pData, pMEND->sHeader.iChunkname, 0, 0);
  7471. #ifdef MNG_SUPPORT_TRACE
  7472. MNG_TRACE (pData, MNG_FN_WRITE_MEND, MNG_LC_END);
  7473. #endif
  7474. return iRetcode;
  7475. }
  7476. /* ************************************************************************** */
  7477. WRITE_CHUNK (mng_write_loop)
  7478. {
  7479. mng_loopp pLOOP;
  7480. mng_uint8p pRawdata;
  7481. mng_uint32 iRawlen;
  7482. mng_retcode iRetcode;
  7483. #ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
  7484. mng_uint8p pTemp1;
  7485. mng_uint32p pTemp2;
  7486. mng_uint32 iX;
  7487. #endif
  7488. #ifdef MNG_SUPPORT_TRACE
  7489. MNG_TRACE (pData, MNG_FN_WRITE_LOOP, MNG_LC_START);
  7490. #endif
  7491. pLOOP = (mng_loopp)pChunk; /* address the proper chunk */
  7492. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7493. iRawlen = 5;
  7494. /* fill the output buffer */
  7495. *pRawdata = pLOOP->iLevel;
  7496. mng_put_uint32 (pRawdata+1, pLOOP->iRepeat);
  7497. if (pLOOP->iTermination)
  7498. {
  7499. iRawlen++;
  7500. *(pRawdata+5) = pLOOP->iTermination;
  7501. if ((pLOOP->iCount) ||
  7502. (pLOOP->iItermin != 1) || (pLOOP->iItermax != 0x7FFFFFFFL))
  7503. {
  7504. iRawlen += 8;
  7505. mng_put_uint32 (pRawdata+6, pLOOP->iItermin);
  7506. mng_put_uint32 (pRawdata+10, pLOOP->iItermax);
  7507. #ifndef MNG_NO_LOOP_SIGNALS_SUPPORTED
  7508. if (pLOOP->iCount)
  7509. {
  7510. iRawlen += pLOOP->iCount * 4;
  7511. pTemp1 = pRawdata+14;
  7512. pTemp2 = pLOOP->pSignals;
  7513. for (iX = 0; iX < pLOOP->iCount; iX++)
  7514. {
  7515. mng_put_uint32 (pTemp1, *pTemp2);
  7516. pTemp1 += 4;
  7517. pTemp2++;
  7518. }
  7519. }
  7520. #endif
  7521. }
  7522. }
  7523. /* and write it */
  7524. iRetcode = write_raw_chunk (pData, pLOOP->sHeader.iChunkname,
  7525. iRawlen, pRawdata);
  7526. #ifdef MNG_SUPPORT_TRACE
  7527. MNG_TRACE (pData, MNG_FN_WRITE_LOOP, MNG_LC_END);
  7528. #endif
  7529. return iRetcode;
  7530. }
  7531. /* ************************************************************************** */
  7532. WRITE_CHUNK (mng_write_endl)
  7533. {
  7534. mng_endlp pENDL;
  7535. mng_uint8p pRawdata;
  7536. mng_uint32 iRawlen;
  7537. mng_retcode iRetcode;
  7538. #ifdef MNG_SUPPORT_TRACE
  7539. MNG_TRACE (pData, MNG_FN_WRITE_ENDL, MNG_LC_START);
  7540. #endif
  7541. pENDL = (mng_endlp)pChunk; /* address the proper chunk */
  7542. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7543. iRawlen = 1;
  7544. *pRawdata = pENDL->iLevel; /* fill the output buffer */
  7545. /* and write it */
  7546. iRetcode = write_raw_chunk (pData, pENDL->sHeader.iChunkname,
  7547. iRawlen, pRawdata);
  7548. #ifdef MNG_SUPPORT_TRACE
  7549. MNG_TRACE (pData, MNG_FN_WRITE_ENDL, MNG_LC_END);
  7550. #endif
  7551. return iRetcode;
  7552. }
  7553. /* ************************************************************************** */
  7554. WRITE_CHUNK (mng_write_defi)
  7555. {
  7556. mng_defip pDEFI;
  7557. mng_uint8p pRawdata;
  7558. mng_uint32 iRawlen;
  7559. mng_retcode iRetcode;
  7560. #ifdef MNG_SUPPORT_TRACE
  7561. MNG_TRACE (pData, MNG_FN_WRITE_DEFI, MNG_LC_START);
  7562. #endif
  7563. pDEFI = (mng_defip)pChunk; /* address the proper chunk */
  7564. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7565. iRawlen = 2;
  7566. /* fill the output buffer */
  7567. mng_put_uint16 (pRawdata, pDEFI->iObjectid);
  7568. if ((pDEFI->iDonotshow) || (pDEFI->iConcrete) || (pDEFI->bHasloca) || (pDEFI->bHasclip))
  7569. {
  7570. iRawlen++;
  7571. *(pRawdata+2) = pDEFI->iDonotshow;
  7572. if ((pDEFI->iConcrete) || (pDEFI->bHasloca) || (pDEFI->bHasclip))
  7573. {
  7574. iRawlen++;
  7575. *(pRawdata+3) = pDEFI->iConcrete;
  7576. if ((pDEFI->bHasloca) || (pDEFI->bHasclip))
  7577. {
  7578. iRawlen += 8;
  7579. mng_put_uint32 (pRawdata+4, pDEFI->iXlocation);
  7580. mng_put_uint32 (pRawdata+8, pDEFI->iYlocation);
  7581. if (pDEFI->bHasclip)
  7582. {
  7583. iRawlen += 16;
  7584. mng_put_uint32 (pRawdata+12, pDEFI->iLeftcb);
  7585. mng_put_uint32 (pRawdata+16, pDEFI->iRightcb);
  7586. mng_put_uint32 (pRawdata+20, pDEFI->iTopcb);
  7587. mng_put_uint32 (pRawdata+24, pDEFI->iBottomcb);
  7588. }
  7589. }
  7590. }
  7591. }
  7592. /* and write it */
  7593. iRetcode = write_raw_chunk (pData, pDEFI->sHeader.iChunkname,
  7594. iRawlen, pRawdata);
  7595. #ifdef MNG_SUPPORT_TRACE
  7596. MNG_TRACE (pData, MNG_FN_WRITE_DEFI, MNG_LC_END);
  7597. #endif
  7598. return iRetcode;
  7599. }
  7600. /* ************************************************************************** */
  7601. WRITE_CHUNK (mng_write_basi)
  7602. {
  7603. mng_basip pBASI;
  7604. mng_uint8p pRawdata;
  7605. mng_uint32 iRawlen;
  7606. mng_retcode iRetcode;
  7607. mng_bool bOpaque;
  7608. #ifdef MNG_SUPPORT_TRACE
  7609. MNG_TRACE (pData, MNG_FN_WRITE_BASI, MNG_LC_START);
  7610. #endif
  7611. pBASI = (mng_basip)pChunk; /* address the proper chunk */
  7612. #ifndef MNG_NO_16BIT_SUPPORT
  7613. if (pBASI->iBitdepth <= 8) /* determine opacity alpha-field */
  7614. #endif
  7615. bOpaque = (mng_bool)(pBASI->iAlpha == 0xFF);
  7616. #ifndef MNG_NO_16BIT_SUPPORT
  7617. else
  7618. bOpaque = (mng_bool)(pBASI->iAlpha == 0xFFFF);
  7619. #endif
  7620. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7621. iRawlen = 13;
  7622. /* fill the output buffer */
  7623. mng_put_uint32 (pRawdata, pBASI->iWidth);
  7624. mng_put_uint32 (pRawdata+4, pBASI->iHeight);
  7625. *(pRawdata+8) = pBASI->iBitdepth;
  7626. *(pRawdata+9) = pBASI->iColortype;
  7627. *(pRawdata+10) = pBASI->iCompression;
  7628. *(pRawdata+11) = pBASI->iFilter;
  7629. *(pRawdata+12) = pBASI->iInterlace;
  7630. if ((pBASI->iRed) || (pBASI->iGreen) || (pBASI->iBlue) ||
  7631. (!bOpaque) || (pBASI->iViewable))
  7632. {
  7633. iRawlen += 6;
  7634. mng_put_uint16 (pRawdata+13, pBASI->iRed);
  7635. mng_put_uint16 (pRawdata+15, pBASI->iGreen);
  7636. mng_put_uint16 (pRawdata+17, pBASI->iBlue);
  7637. if ((!bOpaque) || (pBASI->iViewable))
  7638. {
  7639. iRawlen += 2;
  7640. mng_put_uint16 (pRawdata+19, pBASI->iAlpha);
  7641. if (pBASI->iViewable)
  7642. {
  7643. iRawlen++;
  7644. *(pRawdata+21) = pBASI->iViewable;
  7645. }
  7646. }
  7647. }
  7648. /* and write it */
  7649. iRetcode = write_raw_chunk (pData, pBASI->sHeader.iChunkname,
  7650. iRawlen, pRawdata);
  7651. #ifdef MNG_SUPPORT_TRACE
  7652. MNG_TRACE (pData, MNG_FN_WRITE_BASI, MNG_LC_END);
  7653. #endif
  7654. return iRetcode;
  7655. }
  7656. /* ************************************************************************** */
  7657. WRITE_CHUNK (mng_write_clon)
  7658. {
  7659. mng_clonp pCLON;
  7660. mng_uint8p pRawdata;
  7661. mng_uint32 iRawlen;
  7662. mng_retcode iRetcode;
  7663. #ifdef MNG_SUPPORT_TRACE
  7664. MNG_TRACE (pData, MNG_FN_WRITE_CLON, MNG_LC_START);
  7665. #endif
  7666. pCLON = (mng_clonp)pChunk; /* address the proper chunk */
  7667. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7668. iRawlen = 4;
  7669. /* fill the output buffer */
  7670. mng_put_uint16 (pRawdata, pCLON->iSourceid);
  7671. mng_put_uint16 (pRawdata+2, pCLON->iCloneid);
  7672. if ((pCLON->iClonetype) || (pCLON->iDonotshow) || (pCLON->iConcrete) || (pCLON->bHasloca))
  7673. {
  7674. iRawlen++;
  7675. *(pRawdata+4) = pCLON->iClonetype;
  7676. if ((pCLON->iDonotshow) || (pCLON->iConcrete) || (pCLON->bHasloca))
  7677. {
  7678. iRawlen++;
  7679. *(pRawdata+5) = pCLON->iDonotshow;
  7680. if ((pCLON->iConcrete) || (pCLON->bHasloca))
  7681. {
  7682. iRawlen++;
  7683. *(pRawdata+6) = pCLON->iConcrete;
  7684. if (pCLON->bHasloca)
  7685. {
  7686. iRawlen += 9;
  7687. *(pRawdata+7) = pCLON->iLocationtype;
  7688. mng_put_int32 (pRawdata+8, pCLON->iLocationx);
  7689. mng_put_int32 (pRawdata+12, pCLON->iLocationy);
  7690. }
  7691. }
  7692. }
  7693. }
  7694. /* and write it */
  7695. iRetcode = write_raw_chunk (pData, pCLON->sHeader.iChunkname,
  7696. iRawlen, pRawdata);
  7697. #ifdef MNG_SUPPORT_TRACE
  7698. MNG_TRACE (pData, MNG_FN_WRITE_CLON, MNG_LC_END);
  7699. #endif
  7700. return iRetcode;
  7701. }
  7702. /* ************************************************************************** */
  7703. #ifndef MNG_SKIPCHUNK_PAST
  7704. WRITE_CHUNK (mng_write_past)
  7705. {
  7706. mng_pastp pPAST;
  7707. mng_uint8p pRawdata;
  7708. mng_uint32 iRawlen;
  7709. mng_retcode iRetcode;
  7710. mng_past_sourcep pSource;
  7711. mng_uint32 iX;
  7712. mng_uint8p pTemp;
  7713. #ifdef MNG_SUPPORT_TRACE
  7714. MNG_TRACE (pData, MNG_FN_WRITE_PAST, MNG_LC_START);
  7715. #endif
  7716. pPAST = (mng_pastp)pChunk; /* address the proper chunk */
  7717. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7718. iRawlen = 11 + (30 * pPAST->iCount);
  7719. /* requires large buffer ? */
  7720. if (iRawlen > pData->iWritebufsize)
  7721. MNG_ALLOC (pData, pRawdata, iRawlen);
  7722. /* fill the output buffer */
  7723. mng_put_uint16 (pRawdata, pPAST->iDestid);
  7724. *(pRawdata+2) = pPAST->iTargettype;
  7725. mng_put_int32 (pRawdata+3, pPAST->iTargetx);
  7726. mng_put_int32 (pRawdata+7, pPAST->iTargety);
  7727. pTemp = pRawdata+11;
  7728. pSource = pPAST->pSources;
  7729. for (iX = 0; iX < pPAST->iCount; iX++)
  7730. {
  7731. mng_put_uint16 (pTemp, pSource->iSourceid);
  7732. *(pTemp+2) = pSource->iComposition;
  7733. *(pTemp+3) = pSource->iOrientation;
  7734. *(pTemp+4) = pSource->iOffsettype;
  7735. mng_put_int32 (pTemp+5, pSource->iOffsetx);
  7736. mng_put_int32 (pTemp+9, pSource->iOffsety);
  7737. *(pTemp+13) = pSource->iBoundarytype;
  7738. mng_put_int32 (pTemp+14, pSource->iBoundaryl);
  7739. mng_put_int32 (pTemp+18, pSource->iBoundaryr);
  7740. mng_put_int32 (pTemp+22, pSource->iBoundaryt);
  7741. mng_put_int32 (pTemp+26, pSource->iBoundaryb);
  7742. pSource++;
  7743. pTemp += 30;
  7744. }
  7745. /* and write it */
  7746. iRetcode = write_raw_chunk (pData, pPAST->sHeader.iChunkname,
  7747. iRawlen, pRawdata);
  7748. /* free temporary buffer ? */
  7749. if (iRawlen > pData->iWritebufsize)
  7750. MNG_FREEX (pData, pRawdata, iRawlen);
  7751. #ifdef MNG_SUPPORT_TRACE
  7752. MNG_TRACE (pData, MNG_FN_WRITE_PAST, MNG_LC_END);
  7753. #endif
  7754. return iRetcode;
  7755. }
  7756. #endif
  7757. /* ************************************************************************** */
  7758. WRITE_CHUNK (mng_write_disc)
  7759. {
  7760. mng_discp pDISC;
  7761. mng_uint8p pRawdata;
  7762. mng_uint32 iRawlen;
  7763. mng_retcode iRetcode;
  7764. mng_uint32 iX;
  7765. mng_uint8p pTemp1;
  7766. mng_uint16p pTemp2;
  7767. #ifdef MNG_SUPPORT_TRACE
  7768. MNG_TRACE (pData, MNG_FN_WRITE_DISC, MNG_LC_START);
  7769. #endif
  7770. pDISC = (mng_discp)pChunk; /* address the proper chunk */
  7771. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7772. iRawlen = pDISC->iCount << 1;
  7773. pTemp1 = pRawdata; /* fill the output buffer */
  7774. pTemp2 = pDISC->pObjectids;
  7775. for (iX = 0; iX < pDISC->iCount; iX++)
  7776. {
  7777. mng_put_uint16 (pTemp1, *pTemp2);
  7778. pTemp2++;
  7779. pTemp1 += 2;
  7780. }
  7781. /* and write it */
  7782. iRetcode = write_raw_chunk (pData, pDISC->sHeader.iChunkname,
  7783. iRawlen, pRawdata);
  7784. #ifdef MNG_SUPPORT_TRACE
  7785. MNG_TRACE (pData, MNG_FN_WRITE_DISC, MNG_LC_END);
  7786. #endif
  7787. return iRetcode;
  7788. }
  7789. /* ************************************************************************** */
  7790. WRITE_CHUNK (mng_write_back)
  7791. {
  7792. mng_backp pBACK;
  7793. mng_uint8p pRawdata;
  7794. mng_uint32 iRawlen;
  7795. mng_retcode iRetcode;
  7796. #ifdef MNG_SUPPORT_TRACE
  7797. MNG_TRACE (pData, MNG_FN_WRITE_BACK, MNG_LC_START);
  7798. #endif
  7799. pBACK = (mng_backp)pChunk; /* address the proper chunk */
  7800. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7801. iRawlen = 6;
  7802. /* fill the output buffer */
  7803. mng_put_uint16 (pRawdata, pBACK->iRed);
  7804. mng_put_uint16 (pRawdata+2, pBACK->iGreen);
  7805. mng_put_uint16 (pRawdata+4, pBACK->iBlue);
  7806. if ((pBACK->iMandatory) || (pBACK->iImageid) || (pBACK->iTile))
  7807. {
  7808. iRawlen++;
  7809. *(pRawdata+6) = pBACK->iMandatory;
  7810. if ((pBACK->iImageid) || (pBACK->iTile))
  7811. {
  7812. iRawlen += 2;
  7813. mng_put_uint16 (pRawdata+7, pBACK->iImageid);
  7814. if (pBACK->iTile)
  7815. {
  7816. iRawlen++;
  7817. *(pRawdata+9) = pBACK->iTile;
  7818. }
  7819. }
  7820. }
  7821. /* and write it */
  7822. iRetcode = write_raw_chunk (pData, pBACK->sHeader.iChunkname,
  7823. iRawlen, pRawdata);
  7824. #ifdef MNG_SUPPORT_TRACE
  7825. MNG_TRACE (pData, MNG_FN_WRITE_BACK, MNG_LC_END);
  7826. #endif
  7827. return iRetcode;
  7828. }
  7829. /* ************************************************************************** */
  7830. WRITE_CHUNK (mng_write_fram)
  7831. {
  7832. mng_framp pFRAM;
  7833. mng_uint8p pRawdata;
  7834. mng_uint32 iRawlen;
  7835. mng_retcode iRetcode;
  7836. mng_uint8p pTemp;
  7837. mng_uint32p pTemp2;
  7838. mng_uint32 iX;
  7839. #ifdef MNG_SUPPORT_TRACE
  7840. MNG_TRACE (pData, MNG_FN_WRITE_FRAM, MNG_LC_START);
  7841. #endif
  7842. pFRAM = (mng_framp)pChunk; /* address the proper chunk */
  7843. if (pFRAM->bEmpty) /* empty ? */
  7844. iRetcode = write_raw_chunk (pData, pFRAM->sHeader.iChunkname, 0, 0);
  7845. else
  7846. {
  7847. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7848. iRawlen = 1;
  7849. /* fill the output buffer */
  7850. *pRawdata = pFRAM->iMode;
  7851. if ((pFRAM->iNamesize ) ||
  7852. (pFRAM->iChangedelay ) || (pFRAM->iChangetimeout) ||
  7853. (pFRAM->iChangeclipping) || (pFRAM->iChangesyncid ) )
  7854. {
  7855. if (pFRAM->iNamesize)
  7856. MNG_COPY (pRawdata+1, pFRAM->zName, pFRAM->iNamesize);
  7857. iRawlen += pFRAM->iNamesize;
  7858. pTemp = pRawdata + pFRAM->iNamesize + 1;
  7859. if ((pFRAM->iChangedelay ) || (pFRAM->iChangetimeout) ||
  7860. (pFRAM->iChangeclipping) || (pFRAM->iChangesyncid ) )
  7861. {
  7862. *pTemp = 0;
  7863. *(pTemp+1) = pFRAM->iChangedelay;
  7864. *(pTemp+2) = pFRAM->iChangetimeout;
  7865. *(pTemp+3) = pFRAM->iChangeclipping;
  7866. *(pTemp+4) = pFRAM->iChangesyncid;
  7867. iRawlen += 5;
  7868. pTemp += 5;
  7869. if (pFRAM->iChangedelay)
  7870. {
  7871. mng_put_uint32 (pTemp, pFRAM->iDelay);
  7872. iRawlen += 4;
  7873. pTemp += 4;
  7874. }
  7875. if (pFRAM->iChangetimeout)
  7876. {
  7877. mng_put_uint32 (pTemp, pFRAM->iTimeout);
  7878. iRawlen += 4;
  7879. pTemp += 4;
  7880. }
  7881. if (pFRAM->iChangeclipping)
  7882. {
  7883. *pTemp = pFRAM->iBoundarytype;
  7884. mng_put_uint32 (pTemp+1, pFRAM->iBoundaryl);
  7885. mng_put_uint32 (pTemp+5, pFRAM->iBoundaryr);
  7886. mng_put_uint32 (pTemp+9, pFRAM->iBoundaryt);
  7887. mng_put_uint32 (pTemp+13, pFRAM->iBoundaryb);
  7888. iRawlen += 17;
  7889. pTemp += 17;
  7890. }
  7891. if (pFRAM->iChangesyncid)
  7892. {
  7893. iRawlen += pFRAM->iCount * 4;
  7894. pTemp2 = pFRAM->pSyncids;
  7895. for (iX = 0; iX < pFRAM->iCount; iX++)
  7896. {
  7897. mng_put_uint32 (pTemp, *pTemp2);
  7898. pTemp2++;
  7899. pTemp += 4;
  7900. }
  7901. }
  7902. }
  7903. }
  7904. /* and write it */
  7905. iRetcode = write_raw_chunk (pData, pFRAM->sHeader.iChunkname,
  7906. iRawlen, pRawdata);
  7907. }
  7908. #ifdef MNG_SUPPORT_TRACE
  7909. MNG_TRACE (pData, MNG_FN_WRITE_FRAM, MNG_LC_END);
  7910. #endif
  7911. return iRetcode;
  7912. }
  7913. /* ************************************************************************** */
  7914. WRITE_CHUNK (mng_write_move)
  7915. {
  7916. mng_movep pMOVE;
  7917. mng_uint8p pRawdata;
  7918. mng_uint32 iRawlen;
  7919. mng_retcode iRetcode;
  7920. #ifdef MNG_SUPPORT_TRACE
  7921. MNG_TRACE (pData, MNG_FN_WRITE_MOVE, MNG_LC_START);
  7922. #endif
  7923. pMOVE = (mng_movep)pChunk; /* address the proper chunk */
  7924. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7925. iRawlen = 13;
  7926. /* fill the output buffer */
  7927. mng_put_uint16 (pRawdata, pMOVE->iFirstid);
  7928. mng_put_uint16 (pRawdata+2, pMOVE->iLastid);
  7929. *(pRawdata+4) = pMOVE->iMovetype;
  7930. mng_put_int32 (pRawdata+5, pMOVE->iMovex);
  7931. mng_put_int32 (pRawdata+9, pMOVE->iMovey);
  7932. /* and write it */
  7933. iRetcode = write_raw_chunk (pData, pMOVE->sHeader.iChunkname,
  7934. iRawlen, pRawdata);
  7935. #ifdef MNG_SUPPORT_TRACE
  7936. MNG_TRACE (pData, MNG_FN_WRITE_MOVE, MNG_LC_END);
  7937. #endif
  7938. return iRetcode;
  7939. }
  7940. /* ************************************************************************** */
  7941. WRITE_CHUNK (mng_write_clip)
  7942. {
  7943. mng_clipp pCLIP;
  7944. mng_uint8p pRawdata;
  7945. mng_uint32 iRawlen;
  7946. mng_retcode iRetcode;
  7947. #ifdef MNG_SUPPORT_TRACE
  7948. MNG_TRACE (pData, MNG_FN_WRITE_CLIP, MNG_LC_START);
  7949. #endif
  7950. pCLIP = (mng_clipp)pChunk; /* address the proper chunk */
  7951. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7952. iRawlen = 21;
  7953. /* fill the output buffer */
  7954. mng_put_uint16 (pRawdata, pCLIP->iFirstid);
  7955. mng_put_uint16 (pRawdata+2, pCLIP->iLastid);
  7956. *(pRawdata+4) = pCLIP->iCliptype;
  7957. mng_put_int32 (pRawdata+5, pCLIP->iClipl);
  7958. mng_put_int32 (pRawdata+9, pCLIP->iClipr);
  7959. mng_put_int32 (pRawdata+13, pCLIP->iClipt);
  7960. mng_put_int32 (pRawdata+17, pCLIP->iClipb);
  7961. /* and write it */
  7962. iRetcode = write_raw_chunk (pData, pCLIP->sHeader.iChunkname,
  7963. iRawlen, pRawdata);
  7964. #ifdef MNG_SUPPORT_TRACE
  7965. MNG_TRACE (pData, MNG_FN_WRITE_CLIP, MNG_LC_END);
  7966. #endif
  7967. return iRetcode;
  7968. }
  7969. /* ************************************************************************** */
  7970. WRITE_CHUNK (mng_write_show)
  7971. {
  7972. mng_showp pSHOW;
  7973. mng_uint8p pRawdata;
  7974. mng_uint32 iRawlen;
  7975. mng_retcode iRetcode;
  7976. #ifdef MNG_SUPPORT_TRACE
  7977. MNG_TRACE (pData, MNG_FN_WRITE_SHOW, MNG_LC_START);
  7978. #endif
  7979. pSHOW = (mng_showp)pChunk; /* address the proper chunk */
  7980. if (pSHOW->bEmpty) /* empty ? */
  7981. iRetcode = write_raw_chunk (pData, pSHOW->sHeader.iChunkname, 0, 0);
  7982. else
  7983. {
  7984. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  7985. iRawlen = 2;
  7986. /* fill the output buffer */
  7987. mng_put_uint16 (pRawdata, pSHOW->iFirstid);
  7988. if ((pSHOW->iLastid != pSHOW->iFirstid) || (pSHOW->iMode))
  7989. {
  7990. iRawlen += 2;
  7991. mng_put_uint16 (pRawdata+2, pSHOW->iLastid);
  7992. if (pSHOW->iMode)
  7993. {
  7994. iRawlen++;
  7995. *(pRawdata+4) = pSHOW->iMode;
  7996. }
  7997. }
  7998. /* and write it */
  7999. iRetcode = write_raw_chunk (pData, pSHOW->sHeader.iChunkname,
  8000. iRawlen, pRawdata);
  8001. }
  8002. #ifdef MNG_SUPPORT_TRACE
  8003. MNG_TRACE (pData, MNG_FN_WRITE_SHOW, MNG_LC_END);
  8004. #endif
  8005. return iRetcode;
  8006. }
  8007. /* ************************************************************************** */
  8008. WRITE_CHUNK (mng_write_term)
  8009. {
  8010. mng_termp pTERM;
  8011. mng_uint8p pRawdata;
  8012. mng_uint32 iRawlen;
  8013. mng_retcode iRetcode;
  8014. #ifdef MNG_SUPPORT_TRACE
  8015. MNG_TRACE (pData, MNG_FN_WRITE_TERM, MNG_LC_START);
  8016. #endif
  8017. pTERM = (mng_termp)pChunk; /* address the proper chunk */
  8018. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8019. iRawlen = 1;
  8020. *pRawdata = pTERM->iTermaction; /* fill the output buffer */
  8021. if (pTERM->iTermaction == 3)
  8022. {
  8023. iRawlen = 10;
  8024. *(pRawdata+1) = pTERM->iIteraction;
  8025. mng_put_uint32 (pRawdata+2, pTERM->iDelay);
  8026. mng_put_uint32 (pRawdata+6, pTERM->iItermax);
  8027. }
  8028. /* and write it */
  8029. iRetcode = write_raw_chunk (pData, pTERM->sHeader.iChunkname,
  8030. iRawlen, pRawdata);
  8031. #ifdef MNG_SUPPORT_TRACE
  8032. MNG_TRACE (pData, MNG_FN_WRITE_TERM, MNG_LC_END);
  8033. #endif
  8034. return iRetcode;
  8035. }
  8036. /* ************************************************************************** */
  8037. #ifndef MNG_SKIPCHUNK_SAVE
  8038. WRITE_CHUNK (mng_write_save)
  8039. {
  8040. mng_savep pSAVE;
  8041. mng_uint8p pRawdata;
  8042. mng_uint32 iRawlen;
  8043. mng_retcode iRetcode;
  8044. mng_save_entryp pEntry;
  8045. mng_uint32 iEntrysize;
  8046. mng_uint8p pTemp;
  8047. mng_uint32 iX;
  8048. #ifdef MNG_SUPPORT_TRACE
  8049. MNG_TRACE (pData, MNG_FN_WRITE_SAVE, MNG_LC_START);
  8050. #endif
  8051. pSAVE = (mng_savep)pChunk; /* address the proper chunk */
  8052. if (pSAVE->bEmpty) /* empty ? */
  8053. iRetcode = write_raw_chunk (pData, pSAVE->sHeader.iChunkname, 0, 0);
  8054. else
  8055. {
  8056. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8057. iRawlen = 1;
  8058. *pRawdata = pSAVE->iOffsettype; /* fill the output buffer */
  8059. if (pSAVE->iOffsettype == 16)
  8060. iEntrysize = 25;
  8061. else
  8062. iEntrysize = 17;
  8063. pTemp = pRawdata+1;
  8064. pEntry = pSAVE->pEntries;
  8065. for (iX = 0; iX < pSAVE->iCount; iX++)
  8066. {
  8067. if (iX) /* put separator null-byte, except the first */
  8068. {
  8069. *pTemp = 0;
  8070. pTemp++;
  8071. iRawlen++;
  8072. }
  8073. iRawlen += iEntrysize + pEntry->iNamesize;
  8074. *pTemp = pEntry->iEntrytype;
  8075. if (pSAVE->iOffsettype == 16)
  8076. {
  8077. mng_put_uint32 (pTemp+1, pEntry->iOffset[0]);
  8078. mng_put_uint32 (pTemp+5, pEntry->iOffset[1]);
  8079. mng_put_uint32 (pTemp+9, pEntry->iStarttime[0]);
  8080. mng_put_uint32 (pTemp+13, pEntry->iStarttime[1]);
  8081. mng_put_uint32 (pTemp+17, pEntry->iLayernr);
  8082. mng_put_uint32 (pTemp+21, pEntry->iFramenr);
  8083. pTemp += 25;
  8084. }
  8085. else
  8086. {
  8087. mng_put_uint32 (pTemp+1, pEntry->iOffset[1]);
  8088. mng_put_uint32 (pTemp+5, pEntry->iStarttime[1]);
  8089. mng_put_uint32 (pTemp+9, pEntry->iLayernr);
  8090. mng_put_uint32 (pTemp+13, pEntry->iFramenr);
  8091. pTemp += 17;
  8092. }
  8093. if (pEntry->iNamesize)
  8094. {
  8095. MNG_COPY (pTemp, pEntry->zName, pEntry->iNamesize);
  8096. pTemp += pEntry->iNamesize;
  8097. }
  8098. pEntry++;
  8099. }
  8100. /* and write it */
  8101. iRetcode = write_raw_chunk (pData, pSAVE->sHeader.iChunkname,
  8102. iRawlen, pRawdata);
  8103. }
  8104. #ifdef MNG_SUPPORT_TRACE
  8105. MNG_TRACE (pData, MNG_FN_WRITE_SAVE, MNG_LC_END);
  8106. #endif
  8107. return iRetcode;
  8108. }
  8109. #endif
  8110. /* ************************************************************************** */
  8111. #ifndef MNG_SKIPCHUNK_SEEK
  8112. WRITE_CHUNK (mng_write_seek)
  8113. {
  8114. mng_seekp pSEEK;
  8115. mng_uint8p pRawdata;
  8116. mng_uint32 iRawlen;
  8117. mng_retcode iRetcode;
  8118. #ifdef MNG_SUPPORT_TRACE
  8119. MNG_TRACE (pData, MNG_FN_WRITE_SEEK, MNG_LC_START);
  8120. #endif
  8121. pSEEK = (mng_seekp)pChunk; /* address the proper chunk */
  8122. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8123. iRawlen = pSEEK->iNamesize;
  8124. if (iRawlen) /* fill the output buffer */
  8125. MNG_COPY (pRawdata, pSEEK->zName, iRawlen);
  8126. /* and write it */
  8127. iRetcode = write_raw_chunk (pData, pSEEK->sHeader.iChunkname,
  8128. iRawlen, pRawdata);
  8129. #ifdef MNG_SUPPORT_TRACE
  8130. MNG_TRACE (pData, MNG_FN_WRITE_SEEK, MNG_LC_END);
  8131. #endif
  8132. return iRetcode;
  8133. }
  8134. #endif
  8135. /* ************************************************************************** */
  8136. #ifndef MNG_SKIPCHUNK_eXPI
  8137. WRITE_CHUNK (mng_write_expi)
  8138. {
  8139. mng_expip pEXPI;
  8140. mng_uint8p pRawdata;
  8141. mng_uint32 iRawlen;
  8142. mng_retcode iRetcode;
  8143. #ifdef MNG_SUPPORT_TRACE
  8144. MNG_TRACE (pData, MNG_FN_WRITE_EXPI, MNG_LC_START);
  8145. #endif
  8146. pEXPI = (mng_expip)pChunk; /* address the proper chunk */
  8147. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8148. iRawlen = 2 + pEXPI->iNamesize;
  8149. /* fill the output buffer */
  8150. mng_put_uint16 (pRawdata, pEXPI->iSnapshotid);
  8151. if (pEXPI->iNamesize)
  8152. MNG_COPY (pRawdata+2, pEXPI->zName, pEXPI->iNamesize);
  8153. /* and write it */
  8154. iRetcode = write_raw_chunk (pData, pEXPI->sHeader.iChunkname,
  8155. iRawlen, pRawdata);
  8156. #ifdef MNG_SUPPORT_TRACE
  8157. MNG_TRACE (pData, MNG_FN_WRITE_EXPI, MNG_LC_END);
  8158. #endif
  8159. return iRetcode;
  8160. }
  8161. #endif
  8162. /* ************************************************************************** */
  8163. #ifndef MNG_SKIPCHUNK_fPRI
  8164. WRITE_CHUNK (mng_write_fpri)
  8165. {
  8166. mng_fprip pFPRI;
  8167. mng_uint8p pRawdata;
  8168. mng_uint32 iRawlen;
  8169. mng_retcode iRetcode;
  8170. #ifdef MNG_SUPPORT_TRACE
  8171. MNG_TRACE (pData, MNG_FN_WRITE_FPRI, MNG_LC_START);
  8172. #endif
  8173. pFPRI = (mng_fprip)pChunk; /* address the proper chunk */
  8174. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8175. iRawlen = 2;
  8176. *pRawdata = pFPRI->iDeltatype; /* fill the output buffer */
  8177. *(pRawdata+1) = pFPRI->iPriority;
  8178. /* and write it */
  8179. iRetcode = write_raw_chunk (pData, pFPRI->sHeader.iChunkname,
  8180. iRawlen, pRawdata);
  8181. #ifdef MNG_SUPPORT_TRACE
  8182. MNG_TRACE (pData, MNG_FN_WRITE_FPRI, MNG_LC_END);
  8183. #endif
  8184. return iRetcode;
  8185. }
  8186. #endif
  8187. /* ************************************************************************** */
  8188. #ifndef MNG_SKIPCHUNK_nEED
  8189. WRITE_CHUNK (mng_write_need)
  8190. {
  8191. mng_needp pNEED;
  8192. mng_uint8p pRawdata;
  8193. mng_uint32 iRawlen;
  8194. mng_retcode iRetcode;
  8195. #ifdef MNG_SUPPORT_TRACE
  8196. MNG_TRACE (pData, MNG_FN_WRITE_NEED, MNG_LC_START);
  8197. #endif
  8198. pNEED = (mng_needp)pChunk; /* address the proper chunk */
  8199. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8200. iRawlen = pNEED->iKeywordssize;
  8201. /* fill the output buffer */
  8202. if (pNEED->iKeywordssize)
  8203. MNG_COPY (pRawdata, pNEED->zKeywords, pNEED->iKeywordssize);
  8204. /* and write it */
  8205. iRetcode = write_raw_chunk (pData, pNEED->sHeader.iChunkname,
  8206. iRawlen, pRawdata);
  8207. #ifdef MNG_SUPPORT_TRACE
  8208. MNG_TRACE (pData, MNG_FN_WRITE_NEED, MNG_LC_END);
  8209. #endif
  8210. return iRetcode;
  8211. }
  8212. #endif
  8213. /* ************************************************************************** */
  8214. #ifndef MNG_SKIPCHUNK_pHYg
  8215. WRITE_CHUNK (mng_write_phyg)
  8216. {
  8217. mng_phygp pPHYG;
  8218. mng_uint8p pRawdata;
  8219. mng_uint32 iRawlen;
  8220. mng_retcode iRetcode;
  8221. #ifdef MNG_SUPPORT_TRACE
  8222. MNG_TRACE (pData, MNG_FN_WRITE_PHYG, MNG_LC_START);
  8223. #endif
  8224. pPHYG = (mng_phygp)pChunk; /* address the proper chunk */
  8225. if (pPHYG->bEmpty) /* write empty ? */
  8226. iRetcode = write_raw_chunk (pData, pPHYG->sHeader.iChunkname, 0, 0);
  8227. else
  8228. {
  8229. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8230. iRawlen = 9;
  8231. /* fill the output buffer */
  8232. mng_put_uint32 (pRawdata, pPHYG->iSizex);
  8233. mng_put_uint32 (pRawdata+4, pPHYG->iSizey);
  8234. *(pRawdata+8) = pPHYG->iUnit;
  8235. /* and write it */
  8236. iRetcode = write_raw_chunk (pData, pPHYG->sHeader.iChunkname,
  8237. iRawlen, pRawdata);
  8238. }
  8239. #ifdef MNG_SUPPORT_TRACE
  8240. MNG_TRACE (pData, MNG_FN_WRITE_PHYG, MNG_LC_END);
  8241. #endif
  8242. return iRetcode;
  8243. }
  8244. #endif
  8245. /* ************************************************************************** */
  8246. /* B004 */
  8247. #ifdef MNG_INCLUDE_JNG
  8248. /* B004 */
  8249. WRITE_CHUNK (mng_write_jhdr)
  8250. {
  8251. mng_jhdrp pJHDR;
  8252. mng_uint8p pRawdata;
  8253. mng_uint32 iRawlen;
  8254. mng_retcode iRetcode;
  8255. #ifdef MNG_SUPPORT_TRACE
  8256. MNG_TRACE (pData, MNG_FN_WRITE_JHDR, MNG_LC_START);
  8257. #endif
  8258. pJHDR = (mng_jhdrp)pChunk; /* address the proper chunk */
  8259. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8260. iRawlen = 16;
  8261. /* fill the output buffer */
  8262. mng_put_uint32 (pRawdata, pJHDR->iWidth);
  8263. mng_put_uint32 (pRawdata+4, pJHDR->iHeight);
  8264. *(pRawdata+8) = pJHDR->iColortype;
  8265. *(pRawdata+9) = pJHDR->iImagesampledepth;
  8266. *(pRawdata+10) = pJHDR->iImagecompression;
  8267. *(pRawdata+11) = pJHDR->iImageinterlace;
  8268. *(pRawdata+12) = pJHDR->iAlphasampledepth;
  8269. *(pRawdata+13) = pJHDR->iAlphacompression;
  8270. *(pRawdata+14) = pJHDR->iAlphafilter;
  8271. *(pRawdata+15) = pJHDR->iAlphainterlace;
  8272. /* and write it */
  8273. iRetcode = write_raw_chunk (pData, pJHDR->sHeader.iChunkname, iRawlen, pRawdata);
  8274. #ifdef MNG_SUPPORT_TRACE
  8275. MNG_TRACE (pData, MNG_FN_WRITE_JHDR, MNG_LC_END);
  8276. #endif
  8277. return iRetcode;
  8278. }
  8279. #else
  8280. #define write_jhdr 0
  8281. /* B004 */
  8282. #endif /* MNG_INCLUDE_JNG */
  8283. /* B004 */
  8284. /* ************************************************************************** */
  8285. #ifdef MNG_INCLUDE_JNG
  8286. WRITE_CHUNK (mng_write_jdaa)
  8287. {
  8288. mng_jdatp pJDAA;
  8289. mng_retcode iRetcode;
  8290. #ifdef MNG_SUPPORT_TRACE
  8291. MNG_TRACE (pData, MNG_FN_WRITE_JDAA, MNG_LC_START);
  8292. #endif
  8293. pJDAA = (mng_jdaap)pChunk; /* address the proper chunk */
  8294. if (pJDAA->bEmpty) /* and write it */
  8295. iRetcode = write_raw_chunk (pData, pJDAA->sHeader.iChunkname, 0, 0);
  8296. else
  8297. iRetcode = write_raw_chunk (pData, pJDAA->sHeader.iChunkname,
  8298. pJDAA->iDatasize, pJDAA->pData);
  8299. #ifdef MNG_SUPPORT_TRACE
  8300. MNG_TRACE (pData, MNG_FN_WRITE_JDAA, MNG_LC_END);
  8301. #endif
  8302. return iRetcode;
  8303. }
  8304. #else
  8305. #define write_jdaa 0
  8306. #endif /* MNG_INCLUDE_JNG */
  8307. /* ************************************************************************** */
  8308. /* B004 */
  8309. #ifdef MNG_INCLUDE_JNG
  8310. /* B004 */
  8311. WRITE_CHUNK (mng_write_jdat)
  8312. {
  8313. mng_jdatp pJDAT;
  8314. mng_retcode iRetcode;
  8315. #ifdef MNG_SUPPORT_TRACE
  8316. MNG_TRACE (pData, MNG_FN_WRITE_JDAT, MNG_LC_START);
  8317. #endif
  8318. pJDAT = (mng_jdatp)pChunk; /* address the proper chunk */
  8319. if (pJDAT->bEmpty) /* and write it */
  8320. iRetcode = write_raw_chunk (pData, pJDAT->sHeader.iChunkname, 0, 0);
  8321. else
  8322. iRetcode = write_raw_chunk (pData, pJDAT->sHeader.iChunkname,
  8323. pJDAT->iDatasize, pJDAT->pData);
  8324. #ifdef MNG_SUPPORT_TRACE
  8325. MNG_TRACE (pData, MNG_FN_WRITE_JDAT, MNG_LC_END);
  8326. #endif
  8327. return iRetcode;
  8328. }
  8329. #else
  8330. #define write_jdat 0
  8331. /* B004 */
  8332. #endif /* MNG_INCLUDE_JNG */
  8333. /* B004 */
  8334. /* ************************************************************************** */
  8335. /* B004 */
  8336. #ifdef MNG_INCLUDE_JNG
  8337. /* B004 */
  8338. WRITE_CHUNK (mng_write_jsep)
  8339. {
  8340. mng_jsepp pJSEP;
  8341. mng_retcode iRetcode;
  8342. #ifdef MNG_SUPPORT_TRACE
  8343. MNG_TRACE (pData, MNG_FN_WRITE_JSEP, MNG_LC_START);
  8344. #endif
  8345. pJSEP = (mng_jsepp)pChunk; /* address the proper chunk */
  8346. /* and write it */
  8347. iRetcode = write_raw_chunk (pData, pJSEP->sHeader.iChunkname, 0, 0);
  8348. #ifdef MNG_SUPPORT_TRACE
  8349. MNG_TRACE (pData, MNG_FN_WRITE_JSEP, MNG_LC_END);
  8350. #endif
  8351. return iRetcode;
  8352. }
  8353. #else
  8354. #define write_jsep 0
  8355. /* B004 */
  8356. #endif /* MNG_INCLUDE_JNG */
  8357. /* B004 */
  8358. /* ************************************************************************** */
  8359. #ifndef MNG_NO_DELTA_PNG
  8360. WRITE_CHUNK (mng_write_dhdr)
  8361. {
  8362. mng_dhdrp pDHDR;
  8363. mng_uint8p pRawdata;
  8364. mng_uint32 iRawlen;
  8365. mng_retcode iRetcode;
  8366. #ifdef MNG_SUPPORT_TRACE
  8367. MNG_TRACE (pData, MNG_FN_WRITE_DHDR, MNG_LC_START);
  8368. #endif
  8369. pDHDR = (mng_dhdrp)pChunk; /* address the proper chunk */
  8370. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8371. iRawlen = 4;
  8372. /* fill the output buffer */
  8373. mng_put_uint16 (pRawdata, pDHDR->iObjectid);
  8374. *(pRawdata+2) = pDHDR->iImagetype;
  8375. *(pRawdata+3) = pDHDR->iDeltatype;
  8376. if (pDHDR->iDeltatype != 7)
  8377. {
  8378. iRawlen += 8;
  8379. mng_put_uint32 (pRawdata+4, pDHDR->iBlockwidth);
  8380. mng_put_uint32 (pRawdata+8, pDHDR->iBlockheight);
  8381. if (pDHDR->iDeltatype != 0)
  8382. {
  8383. iRawlen += 8;
  8384. mng_put_uint32 (pRawdata+12, pDHDR->iBlockx);
  8385. mng_put_uint32 (pRawdata+16, pDHDR->iBlocky);
  8386. }
  8387. }
  8388. /* and write it */
  8389. iRetcode = write_raw_chunk (pData, pDHDR->sHeader.iChunkname,
  8390. iRawlen, pRawdata);
  8391. #ifdef MNG_SUPPORT_TRACE
  8392. MNG_TRACE (pData, MNG_FN_WRITE_DHDR, MNG_LC_END);
  8393. #endif
  8394. return iRetcode;
  8395. }
  8396. #endif
  8397. /* ************************************************************************** */
  8398. #ifndef MNG_NO_DELTA_PNG
  8399. WRITE_CHUNK (mng_write_prom)
  8400. {
  8401. mng_promp pPROM;
  8402. mng_uint8p pRawdata;
  8403. mng_uint32 iRawlen;
  8404. mng_retcode iRetcode;
  8405. #ifdef MNG_SUPPORT_TRACE
  8406. MNG_TRACE (pData, MNG_FN_WRITE_PROM, MNG_LC_START);
  8407. #endif
  8408. pPROM = (mng_promp)pChunk; /* address the proper chunk */
  8409. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8410. iRawlen = 3;
  8411. *pRawdata = pPROM->iColortype; /* fill the output buffer */
  8412. *(pRawdata+1) = pPROM->iSampledepth;
  8413. *(pRawdata+2) = pPROM->iFilltype;
  8414. /* and write it */
  8415. iRetcode = write_raw_chunk (pData, pPROM->sHeader.iChunkname,
  8416. iRawlen, pRawdata);
  8417. #ifdef MNG_SUPPORT_TRACE
  8418. MNG_TRACE (pData, MNG_FN_WRITE_PROM, MNG_LC_END);
  8419. #endif
  8420. return iRetcode;
  8421. }
  8422. #endif
  8423. /* ************************************************************************** */
  8424. #ifndef MNG_NO_DELTA_PNG
  8425. WRITE_CHUNK (mng_write_ipng)
  8426. {
  8427. mng_ipngp pIPNG;
  8428. mng_retcode iRetcode;
  8429. #ifdef MNG_SUPPORT_TRACE
  8430. MNG_TRACE (pData, MNG_FN_WRITE_IPNG, MNG_LC_START);
  8431. #endif
  8432. pIPNG = (mng_ipngp)pChunk; /* address the proper chunk */
  8433. /* and write it */
  8434. iRetcode = write_raw_chunk (pData, pIPNG->sHeader.iChunkname, 0, 0);
  8435. #ifdef MNG_SUPPORT_TRACE
  8436. MNG_TRACE (pData, MNG_FN_WRITE_IPNG, MNG_LC_END);
  8437. #endif
  8438. return iRetcode;
  8439. }
  8440. #endif
  8441. /* ************************************************************************** */
  8442. #ifndef MNG_NO_DELTA_PNG
  8443. WRITE_CHUNK (mng_write_pplt)
  8444. {
  8445. mng_ppltp pPPLT;
  8446. mng_uint8p pRawdata;
  8447. mng_uint32 iRawlen;
  8448. mng_retcode iRetcode;
  8449. mng_pplt_entryp pEntry;
  8450. mng_uint8p pTemp;
  8451. mng_uint32 iX;
  8452. mng_bool bHasgroup;
  8453. mng_uint8p pLastid = 0;
  8454. #ifdef MNG_SUPPORT_TRACE
  8455. MNG_TRACE (pData, MNG_FN_WRITE_PPLT, MNG_LC_START);
  8456. #endif
  8457. pPPLT = (mng_ppltp)pChunk; /* address the proper chunk */
  8458. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8459. iRawlen = 1;
  8460. *pRawdata = pPPLT->iDeltatype; /* fill the output buffer */
  8461. pTemp = pRawdata+1;
  8462. bHasgroup = MNG_FALSE;
  8463. for (iX = 0; iX < pPPLT->iCount; iX++)
  8464. {
  8465. pEntry = &pPPLT->aEntries[iX];
  8466. if (pEntry->bUsed) /* valid entry ? */
  8467. {
  8468. if (!bHasgroup) /* start a new group ? */
  8469. {
  8470. bHasgroup = MNG_TRUE;
  8471. pLastid = pTemp+1;
  8472. *pTemp = (mng_uint8)iX;
  8473. *(pTemp+1) = 0;
  8474. pTemp += 2;
  8475. iRawlen += 2;
  8476. }
  8477. switch (pPPLT->iDeltatype) /* add group-entry depending on type */
  8478. {
  8479. case 0: ;
  8480. case 1: {
  8481. *pTemp = pEntry->iRed;
  8482. *(pTemp+1) = pEntry->iGreen;
  8483. *(pTemp+2) = pEntry->iBlue;
  8484. pTemp += 3;
  8485. iRawlen += 3;
  8486. break;
  8487. }
  8488. case 2: ;
  8489. case 3: {
  8490. *pTemp = pEntry->iAlpha;
  8491. pTemp++;
  8492. iRawlen++;
  8493. break;
  8494. }
  8495. case 4: ;
  8496. case 5: {
  8497. *pTemp = pEntry->iRed;
  8498. *(pTemp+1) = pEntry->iGreen;
  8499. *(pTemp+2) = pEntry->iBlue;
  8500. *(pTemp+3) = pEntry->iAlpha;
  8501. pTemp += 4;
  8502. iRawlen += 4;
  8503. break;
  8504. }
  8505. }
  8506. }
  8507. else
  8508. {
  8509. if (bHasgroup) /* finish off a group ? */
  8510. *pLastid = (mng_uint8)(iX-1);
  8511. bHasgroup = MNG_FALSE;
  8512. }
  8513. }
  8514. if (bHasgroup) /* last group unfinished ? */
  8515. *pLastid = (mng_uint8)(pPPLT->iCount-1);
  8516. /* write the output buffer */
  8517. iRetcode = write_raw_chunk (pData, pPPLT->sHeader.iChunkname,
  8518. iRawlen, pRawdata);
  8519. #ifdef MNG_SUPPORT_TRACE
  8520. MNG_TRACE (pData, MNG_FN_WRITE_PPLT, MNG_LC_END);
  8521. #endif
  8522. return iRetcode;
  8523. }
  8524. #endif
  8525. /* ************************************************************************** */
  8526. #ifndef MNG_NO_DELTA_PNG
  8527. #ifdef MNG_INCLUDE_JNG
  8528. WRITE_CHUNK (mng_write_ijng)
  8529. {
  8530. mng_ijngp pIJNG;
  8531. mng_retcode iRetcode;
  8532. #ifdef MNG_SUPPORT_TRACE
  8533. MNG_TRACE (pData, MNG_FN_WRITE_IJNG, MNG_LC_START);
  8534. #endif
  8535. pIJNG = (mng_ijngp)pChunk; /* address the proper chunk */
  8536. /* and write it */
  8537. iRetcode = write_raw_chunk (pData, pIJNG->sHeader.iChunkname, 0, 0);
  8538. #ifdef MNG_SUPPORT_TRACE
  8539. MNG_TRACE (pData, MNG_FN_WRITE_IJNG, MNG_LC_END);
  8540. #endif
  8541. return iRetcode;
  8542. }
  8543. #endif
  8544. #endif
  8545. /* ************************************************************************** */
  8546. #ifndef MNG_NO_DELTA_PNG
  8547. WRITE_CHUNK (mng_write_drop)
  8548. {
  8549. mng_dropp pDROP;
  8550. mng_uint8p pRawdata;
  8551. mng_uint32 iRawlen;
  8552. mng_retcode iRetcode;
  8553. mng_uint32 iX;
  8554. mng_uint8p pTemp1;
  8555. mng_chunkidp pTemp2;
  8556. #ifdef MNG_SUPPORT_TRACE
  8557. MNG_TRACE (pData, MNG_FN_WRITE_DROP, MNG_LC_START);
  8558. #endif
  8559. pDROP = (mng_dropp)pChunk; /* address the proper chunk */
  8560. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8561. iRawlen = pDROP->iCount << 2;
  8562. pTemp1 = pRawdata; /* fill the output buffer */
  8563. pTemp2 = pDROP->pChunknames;
  8564. for (iX = 0; iX < pDROP->iCount; iX++)
  8565. {
  8566. mng_put_uint32 (pTemp1, (mng_uint32)*pTemp2);
  8567. pTemp2++;
  8568. pTemp1 += 4;
  8569. }
  8570. /* and write it */
  8571. iRetcode = write_raw_chunk (pData, pDROP->sHeader.iChunkname,
  8572. iRawlen, pRawdata);
  8573. #ifdef MNG_SUPPORT_TRACE
  8574. MNG_TRACE (pData, MNG_FN_WRITE_DROP, MNG_LC_END);
  8575. #endif
  8576. return iRetcode;
  8577. }
  8578. #endif
  8579. /* ************************************************************************** */
  8580. #ifndef MNG_NO_DELTA_PNG
  8581. #ifndef MNG_SKIPCHUNK_DBYK
  8582. WRITE_CHUNK (mng_write_dbyk)
  8583. {
  8584. mng_dbykp pDBYK;
  8585. mng_uint8p pRawdata;
  8586. mng_uint32 iRawlen;
  8587. mng_retcode iRetcode;
  8588. #ifdef MNG_SUPPORT_TRACE
  8589. MNG_TRACE (pData, MNG_FN_WRITE_DBYK, MNG_LC_START);
  8590. #endif
  8591. pDBYK = (mng_dbykp)pChunk; /* address the proper chunk */
  8592. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8593. iRawlen = 5 + pDBYK->iKeywordssize;
  8594. /* fill the output buffer */
  8595. mng_put_uint32 (pRawdata, pDBYK->iChunkname);
  8596. *(pRawdata+4) = pDBYK->iPolarity;
  8597. if (pDBYK->iKeywordssize)
  8598. MNG_COPY (pRawdata+5, pDBYK->zKeywords, pDBYK->iKeywordssize);
  8599. /* and write it */
  8600. iRetcode = write_raw_chunk (pData, pDBYK->sHeader.iChunkname,
  8601. iRawlen, pRawdata);
  8602. #ifdef MNG_SUPPORT_TRACE
  8603. MNG_TRACE (pData, MNG_FN_WRITE_DBYK, MNG_LC_END);
  8604. #endif
  8605. return iRetcode;
  8606. }
  8607. #endif
  8608. #endif
  8609. /* ************************************************************************** */
  8610. #ifndef MNG_NO_DELTA_PNG
  8611. #ifndef MNG_SKIPCHUNK_ORDR
  8612. WRITE_CHUNK (mng_write_ordr)
  8613. {
  8614. mng_ordrp pORDR;
  8615. mng_uint8p pRawdata;
  8616. mng_uint32 iRawlen;
  8617. mng_retcode iRetcode;
  8618. mng_uint8p pTemp;
  8619. mng_ordr_entryp pEntry;
  8620. mng_uint32 iX;
  8621. #ifdef MNG_SUPPORT_TRACE
  8622. MNG_TRACE (pData, MNG_FN_WRITE_ORDR, MNG_LC_START);
  8623. #endif
  8624. pORDR = (mng_ordrp)pChunk; /* address the proper chunk */
  8625. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8626. iRawlen = pORDR->iCount * 5;
  8627. pTemp = pRawdata; /* fill the output buffer */
  8628. pEntry = pORDR->pEntries;
  8629. for (iX = 0; iX < pORDR->iCount; iX++)
  8630. {
  8631. mng_put_uint32 (pTemp, pEntry->iChunkname);
  8632. *(pTemp+4) = pEntry->iOrdertype;
  8633. pTemp += 5;
  8634. pEntry++;
  8635. }
  8636. /* and write it */
  8637. iRetcode = write_raw_chunk (pData, pORDR->sHeader.iChunkname,
  8638. iRawlen, pRawdata);
  8639. #ifdef MNG_SUPPORT_TRACE
  8640. MNG_TRACE (pData, MNG_FN_WRITE_ORDR, MNG_LC_END);
  8641. #endif
  8642. return iRetcode;
  8643. }
  8644. #endif
  8645. #endif
  8646. /* ************************************************************************** */
  8647. WRITE_CHUNK (mng_write_magn)
  8648. {
  8649. mng_magnp pMAGN;
  8650. mng_uint8p pRawdata;
  8651. mng_uint32 iRawlen;
  8652. mng_retcode iRetcode;
  8653. #ifdef MNG_SUPPORT_TRACE
  8654. MNG_TRACE (pData, MNG_FN_WRITE_MAGN, MNG_LC_START);
  8655. #endif
  8656. pMAGN = (mng_magnp)pChunk; /* address the proper chunk */
  8657. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8658. iRawlen = 18;
  8659. /* fill the output buffer */
  8660. mng_put_uint16 (pRawdata, pMAGN->iFirstid);
  8661. mng_put_uint16 (pRawdata+2, pMAGN->iLastid);
  8662. *(pRawdata+4) = pMAGN->iMethodX;
  8663. mng_put_uint16 (pRawdata+5, pMAGN->iMX);
  8664. mng_put_uint16 (pRawdata+7, pMAGN->iMY);
  8665. mng_put_uint16 (pRawdata+9, pMAGN->iML);
  8666. mng_put_uint16 (pRawdata+11, pMAGN->iMR);
  8667. mng_put_uint16 (pRawdata+13, pMAGN->iMT);
  8668. mng_put_uint16 (pRawdata+15, pMAGN->iMB);
  8669. *(pRawdata+17) = pMAGN->iMethodY;
  8670. /* optimize length */
  8671. if (pMAGN->iMethodY == pMAGN->iMethodX)
  8672. {
  8673. iRawlen--;
  8674. if (pMAGN->iMB == pMAGN->iMY)
  8675. {
  8676. iRawlen -= 2;
  8677. if (pMAGN->iMT == pMAGN->iMY)
  8678. {
  8679. iRawlen -= 2;
  8680. if (pMAGN->iMR == pMAGN->iMX)
  8681. {
  8682. iRawlen -= 2;
  8683. if (pMAGN->iML == pMAGN->iMX)
  8684. {
  8685. iRawlen -= 2;
  8686. if (pMAGN->iMY == pMAGN->iMX)
  8687. {
  8688. iRawlen -= 2;
  8689. if (pMAGN->iMX == 1)
  8690. {
  8691. iRawlen -= 2;
  8692. if (pMAGN->iMethodX == 0)
  8693. {
  8694. iRawlen--;
  8695. if (pMAGN->iLastid == pMAGN->iFirstid)
  8696. {
  8697. iRawlen -= 2;
  8698. if (pMAGN->iFirstid == 0)
  8699. iRawlen = 0;
  8700. }
  8701. }
  8702. }
  8703. }
  8704. }
  8705. }
  8706. }
  8707. }
  8708. }
  8709. /* and write it */
  8710. iRetcode = write_raw_chunk (pData, pMAGN->sHeader.iChunkname,
  8711. iRawlen, pRawdata);
  8712. #ifdef MNG_SUPPORT_TRACE
  8713. MNG_TRACE (pData, MNG_FN_WRITE_MAGN, MNG_LC_END);
  8714. #endif
  8715. return iRetcode;
  8716. }
  8717. /* ************************************************************************** */
  8718. #ifdef MNG_INCLUDE_MPNG_PROPOSAL
  8719. WRITE_CHUNK (mng_write_mpng)
  8720. {
  8721. mng_mpngp pMPNG;
  8722. mng_uint8p pRawdata;
  8723. mng_uint32 iRawlen;
  8724. mng_retcode iRetcode;
  8725. mng_uint8p pBuf = 0;
  8726. mng_uint32 iBuflen;
  8727. mng_uint32 iReallen;
  8728. #ifdef MNG_SUPPORT_TRACE
  8729. MNG_TRACE (pData, MNG_FN_WRITE_MPNG, MNG_LC_START);
  8730. #endif
  8731. pMPNG = (mng_mpngp)pChunk; /* address the proper chunk */
  8732. /* compress the frame structures */
  8733. iRetcode = deflate_buffer (pData, (mng_uint8p)pMPNG->pFrames, pMPNG->iFramessize,
  8734. &pBuf, &iBuflen, &iReallen);
  8735. if (!iRetcode) /* all ok ? */
  8736. {
  8737. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8738. iRawlen = 15 + iReallen;
  8739. /* requires large buffer ? */
  8740. if (iRawlen > pData->iWritebufsize)
  8741. MNG_ALLOC (pData, pRawdata, iRawlen);
  8742. /* fill the buffer */
  8743. mng_put_uint32 (pRawdata, pMPNG->iFramewidth);
  8744. mng_put_uint32 (pRawdata+4, pMPNG->iFrameheight);
  8745. mng_put_uint16 (pRawdata+8, pMPNG->iNumplays);
  8746. mng_put_uint16 (pRawdata+10, pMPNG->iTickspersec);
  8747. *(pRawdata+12) = pMPNG->iCompressionmethod;
  8748. if (iReallen)
  8749. MNG_COPY (pRawdata+13, pBuf, iReallen);
  8750. /* and write it */
  8751. iRetcode = write_raw_chunk (pData, pMPNG->sHeader.iChunkname,
  8752. iRawlen, pRawdata);
  8753. /* drop the temp buffer ? */
  8754. if (iRawlen > pData->iWritebufsize)
  8755. MNG_FREEX (pData, pRawdata, iRawlen);
  8756. }
  8757. MNG_FREEX (pData, pBuf, iBuflen); /* always drop the compression buffer */
  8758. #ifdef MNG_SUPPORT_TRACE
  8759. MNG_TRACE (pData, MNG_FN_WRITE_MPNG, MNG_LC_END);
  8760. #endif
  8761. return iRetcode;
  8762. }
  8763. #endif
  8764. /* ************************************************************************** */
  8765. #ifdef MNG_INCLUDE_ANG_PROPOSAL
  8766. WRITE_CHUNK (mng_write_ahdr)
  8767. {
  8768. mng_ahdrp pAHDR;
  8769. mng_uint8p pRawdata;
  8770. mng_uint32 iRawlen;
  8771. mng_retcode iRetcode;
  8772. #ifdef MNG_SUPPORT_TRACE
  8773. MNG_TRACE (pData, MNG_FN_WRITE_AHDR, MNG_LC_START);
  8774. #endif
  8775. pAHDR = (mng_ahdrp)pChunk; /* address the proper chunk */
  8776. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8777. iRawlen = 22;
  8778. /* fill the buffer */
  8779. mng_put_uint32 (pRawdata, pAHDR->iNumframes);
  8780. mng_put_uint32 (pRawdata+4, pAHDR->iTickspersec);
  8781. mng_put_uint32 (pRawdata+8, pAHDR->iNumplays);
  8782. mng_put_uint32 (pRawdata+12, pAHDR->iTilewidth);
  8783. mng_put_uint32 (pRawdata+16, pAHDR->iTileheight);
  8784. *(pRawdata+20) = pAHDR->iInterlace;
  8785. *(pRawdata+21) = pAHDR->iStillused;
  8786. /* and write it */
  8787. iRetcode = write_raw_chunk (pData, pAHDR->sHeader.iChunkname,
  8788. iRawlen, pRawdata);
  8789. #ifdef MNG_SUPPORT_TRACE
  8790. MNG_TRACE (pData, MNG_FN_WRITE_AHDR, MNG_LC_END);
  8791. #endif
  8792. return iRetcode;
  8793. }
  8794. #endif
  8795. /* ************************************************************************** */
  8796. #ifdef MNG_INCLUDE_ANG_PROPOSAL
  8797. WRITE_CHUNK (mng_write_adat)
  8798. {
  8799. /* TODO: something */
  8800. return MNG_NOERROR;
  8801. }
  8802. #endif
  8803. /* ************************************************************************** */
  8804. #ifndef MNG_SKIPCHUNK_evNT
  8805. WRITE_CHUNK (mng_write_evnt)
  8806. {
  8807. mng_evntp pEVNT;
  8808. mng_uint8p pRawdata;
  8809. mng_uint32 iRawlen;
  8810. mng_retcode iRetcode;
  8811. mng_evnt_entryp pEntry;
  8812. mng_uint8p pTemp;
  8813. mng_uint32 iX;
  8814. mng_uint32 iNamesize;
  8815. #ifdef MNG_SUPPORT_TRACE
  8816. MNG_TRACE (pData, MNG_FN_WRITE_EVNT, MNG_LC_START);
  8817. #endif
  8818. pEVNT = (mng_evntp)pChunk; /* address the proper chunk */
  8819. if (!pEVNT->iCount) /* empty ? */
  8820. iRetcode = write_raw_chunk (pData, pEVNT->sHeader.iChunkname, 0, 0);
  8821. else
  8822. {
  8823. pRawdata = pData->pWritebuf+8; /* init output buffer & size */
  8824. iRawlen = 0;
  8825. pTemp = pRawdata;
  8826. pEntry = pEVNT->pEntries;
  8827. for (iX = 0; iX < pEVNT->iCount; iX++)
  8828. {
  8829. if (iX) /* put separator null-byte, except the first */
  8830. {
  8831. *pTemp = 0;
  8832. pTemp++;
  8833. iRawlen++;
  8834. }
  8835. *pTemp = pEntry->iEventtype;
  8836. *(pTemp+1) = pEntry->iMasktype;
  8837. pTemp += 2;
  8838. iRawlen += 2;
  8839. switch (pEntry->iMasktype)
  8840. {
  8841. case 1 :
  8842. {
  8843. mng_put_int32 (pTemp, pEntry->iLeft);
  8844. mng_put_int32 (pTemp+4, pEntry->iRight);
  8845. mng_put_int32 (pTemp+8, pEntry->iTop);
  8846. mng_put_int32 (pTemp+12, pEntry->iBottom);
  8847. pTemp += 16;
  8848. iRawlen += 16;
  8849. break;
  8850. }
  8851. case 2 :
  8852. {
  8853. mng_put_uint16 (pTemp, pEntry->iObjectid);
  8854. pTemp += 2;
  8855. iRawlen += 2;
  8856. break;
  8857. }
  8858. case 3 :
  8859. {
  8860. mng_put_uint16 (pTemp, pEntry->iObjectid);
  8861. *(pTemp+2) = pEntry->iIndex;
  8862. pTemp += 3;
  8863. iRawlen += 3;
  8864. break;
  8865. }
  8866. case 4 :
  8867. {
  8868. mng_put_int32 (pTemp, pEntry->iLeft);
  8869. mng_put_int32 (pTemp+4, pEntry->iRight);
  8870. mng_put_int32 (pTemp+8, pEntry->iTop);
  8871. mng_put_int32 (pTemp+12, pEntry->iBottom);
  8872. mng_put_uint16 (pTemp+16, pEntry->iObjectid);
  8873. pTemp += 18;
  8874. iRawlen += 18;
  8875. break;
  8876. }
  8877. case 5 :
  8878. {
  8879. mng_put_int32 (pTemp, pEntry->iLeft);
  8880. mng_put_int32 (pTemp+4, pEntry->iRight);
  8881. mng_put_int32 (pTemp+8, pEntry->iTop);
  8882. mng_put_int32 (pTemp+12, pEntry->iBottom);
  8883. mng_put_uint16 (pTemp+16, pEntry->iObjectid);
  8884. *(pTemp+18) = pEntry->iIndex;
  8885. pTemp += 19;
  8886. iRawlen += 19;
  8887. break;
  8888. }
  8889. }
  8890. iNamesize = pEntry->iSegmentnamesize;
  8891. if (iNamesize)
  8892. {
  8893. MNG_COPY (pTemp, pEntry->zSegmentname, iNamesize);
  8894. pTemp += iNamesize;
  8895. iRawlen += iNamesize;
  8896. }
  8897. pEntry++;
  8898. }
  8899. /* and write it */
  8900. iRetcode = write_raw_chunk (pData, pEVNT->sHeader.iChunkname,
  8901. iRawlen, pRawdata);
  8902. }
  8903. #ifdef MNG_SUPPORT_TRACE
  8904. MNG_TRACE (pData, MNG_FN_WRITE_EVNT, MNG_LC_END);
  8905. #endif
  8906. return iRetcode;
  8907. }
  8908. #endif
  8909. /* ************************************************************************** */
  8910. WRITE_CHUNK (mng_write_unknown)
  8911. {
  8912. mng_unknown_chunkp pUnknown;
  8913. mng_retcode iRetcode;
  8914. #ifdef MNG_SUPPORT_TRACE
  8915. MNG_TRACE (pData, MNG_FN_WRITE_UNKNOWN, MNG_LC_START);
  8916. #endif
  8917. /* address the proper chunk */
  8918. pUnknown = (mng_unknown_chunkp)pChunk;
  8919. /* and write it */
  8920. iRetcode = write_raw_chunk (pData, pUnknown->sHeader.iChunkname,
  8921. pUnknown->iDatasize, pUnknown->pData);
  8922. #ifdef MNG_SUPPORT_TRACE
  8923. MNG_TRACE (pData, MNG_FN_WRITE_UNKNOWN, MNG_LC_END);
  8924. #endif
  8925. return iRetcode;
  8926. }
  8927. /* ************************************************************************** */
  8928. #endif /* MNG_INCLUDE_WRITE_PROCS */
  8929. /* ************************************************************************** */
  8930. /* * end of file * */
  8931. /* ************************************************************************** */