spng.c 195 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980
  1. /* SPDX-License-Identifier: (BSD-2-Clause AND libpng-2.0) */
  2. #define SPNG__BUILD
  3. #include "spng.h"
  4. #include <limits.h>
  5. #include <string.h>
  6. #include <stdio.h>
  7. #include <math.h>
  8. #define ZLIB_CONST
  9. #ifdef __FRAMAC__
  10. #define SPNG_DISABLE_OPT
  11. #include "tests/framac_stubs.h"
  12. #else
  13. #ifdef SPNG_USE_MINIZ
  14. #include <miniz.h>
  15. #else
  16. #include <zlib.h>
  17. #endif
  18. #endif
  19. #ifdef SPNG_MULTITHREADING
  20. #include <pthread.h>
  21. #endif
  22. /* Not build options, edit at your own risk! */
  23. #define SPNG_READ_SIZE (8192)
  24. #define SPNG_WRITE_SIZE SPNG_READ_SIZE
  25. #define SPNG_MAX_CHUNK_COUNT (1000)
  26. #define SPNG_TARGET_CLONES(x)
  27. #ifndef SPNG_DISABLE_OPT
  28. #if defined(__i386__) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_X64)
  29. #define SPNG_X86
  30. #if defined(__x86_64__) || defined(_M_X64)
  31. #define SPNG_X86_64
  32. #endif
  33. #elif defined(__aarch64__) || defined(_M_ARM64) /* || defined(__ARM_NEON) */
  34. #define SPNG_ARM /* NOTE: only arm64 builds are tested! */
  35. #else
  36. #pragma message "disabling SIMD optimizations for unknown target"
  37. #define SPNG_DISABLE_OPT
  38. #endif
  39. #if defined(SPNG_X86_64) && defined(SPNG_ENABLE_TARGET_CLONES)
  40. #undef SPNG_TARGET_CLONES
  41. #define SPNG_TARGET_CLONES(x) __attribute__((target_clones(x)))
  42. #else
  43. #define SPNG_TARGET_CLONES(x)
  44. #endif
  45. #ifndef SPNG_DISABLE_OPT
  46. static void defilter_sub3(size_t rowbytes, unsigned char *row);
  47. static void defilter_sub4(size_t rowbytes, unsigned char *row);
  48. static void defilter_avg3(size_t rowbytes, unsigned char *row, const unsigned char *prev);
  49. static void defilter_avg4(size_t rowbytes, unsigned char *row, const unsigned char *prev);
  50. static void defilter_paeth3(size_t rowbytes, unsigned char *row, const unsigned char *prev);
  51. static void defilter_paeth4(size_t rowbytes, unsigned char *row, const unsigned char *prev);
  52. #if defined(SPNG_ARM)
  53. static uint32_t expand_palette_rgba8_neon(unsigned char *row, const unsigned char *scanline, const unsigned char *plte, uint32_t width);
  54. static uint32_t expand_palette_rgb8_neon(unsigned char *row, const unsigned char *scanline, const unsigned char *plte, uint32_t width);
  55. #endif
  56. #endif
  57. #endif
  58. #if defined(_MSC_VER)
  59. #pragma warning(push)
  60. #pragma warning(disable: 4244)
  61. #endif
  62. #if (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || defined(__BIG_ENDIAN__)
  63. #define SPNG_BIG_ENDIAN
  64. #else
  65. #define SPNG_LITTLE_ENDIAN
  66. #endif
  67. enum spng_state
  68. {
  69. SPNG_STATE_INVALID = 0,
  70. SPNG_STATE_INIT = 1, /* No PNG buffer/stream is set */
  71. SPNG_STATE_INPUT, /* Decoder input PNG was set */
  72. SPNG_STATE_OUTPUT = SPNG_STATE_INPUT, /* Encoder output was set */
  73. SPNG_STATE_IHDR, /* IHDR was read/written */
  74. SPNG_STATE_FIRST_IDAT, /* Encoded up to / reached first IDAT */
  75. SPNG_STATE_DECODE_INIT, /* Decoder is ready for progressive reads */
  76. SPNG_STATE_ENCODE_INIT = SPNG_STATE_DECODE_INIT,
  77. SPNG_STATE_EOI, /* Reached the last scanline/row */
  78. SPNG_STATE_LAST_IDAT, /* Reached last IDAT, set at end of decode_image() */
  79. SPNG_STATE_AFTER_IDAT, /* */
  80. SPNG_STATE_IEND, /* Reached IEND */
  81. };
  82. enum spng__internal
  83. {
  84. SPNG__IO_SIGNAL = 1 << 9,
  85. SPNG__CTX_FLAGS_ALL = (SPNG_CTX_IGNORE_ADLER32 | SPNG_CTX_ENCODER)
  86. };
  87. #define SPNG_STR(x) _SPNG_STR(x)
  88. #define _SPNG_STR(x) #x
  89. #define SPNG_VERSION_STRING SPNG_STR(SPNG_VERSION_MAJOR) "." \
  90. SPNG_STR(SPNG_VERSION_MINOR) "." \
  91. SPNG_STR(SPNG_VERSION_PATCH)
  92. #define SPNG_GET_CHUNK_BOILERPLATE(chunk) \
  93. if(ctx == NULL) return 1; \
  94. int ret = read_chunks(ctx, 0); \
  95. if(ret) return ret; \
  96. if(!ctx->stored.chunk) return SPNG_ECHUNKAVAIL; \
  97. if(chunk == NULL) return 1
  98. #define SPNG_SET_CHUNK_BOILERPLATE(chunk) \
  99. if(ctx == NULL || chunk == NULL) return 1; \
  100. if(ctx->data == NULL && !ctx->encode_only) return SPNG_ENOSRC; \
  101. int ret = read_chunks(ctx, 0); \
  102. if(ret) return ret
  103. /* Determine if the spng_option can be overriden/optimized */
  104. #define spng__optimize(option) (ctx->optimize_option & (1 << option))
  105. struct spng_subimage
  106. {
  107. uint32_t width;
  108. uint32_t height;
  109. size_t out_width; /* byte width based on output format */
  110. size_t scanline_width;
  111. };
  112. struct spng_text2
  113. {
  114. int type;
  115. char *keyword;
  116. char *text;
  117. size_t text_length;
  118. uint8_t compression_flag; /* iTXt only */
  119. char *language_tag; /* iTXt only */
  120. char *translated_keyword; /* iTXt only */
  121. size_t cache_usage;
  122. char user_keyword_storage[80];
  123. };
  124. struct decode_flags
  125. {
  126. unsigned apply_trns: 1;
  127. unsigned apply_gamma: 1;
  128. unsigned use_sbit: 1;
  129. unsigned indexed: 1;
  130. unsigned do_scaling: 1;
  131. unsigned interlaced: 1;
  132. unsigned same_layout: 1;
  133. unsigned zerocopy: 1;
  134. unsigned unpack: 1;
  135. };
  136. struct encode_flags
  137. {
  138. unsigned interlace: 1;
  139. unsigned same_layout: 1;
  140. unsigned to_bigendian: 1;
  141. unsigned progressive: 1;
  142. unsigned finalize: 1;
  143. enum spng_filter_choice filter_choice;
  144. };
  145. struct spng_chunk_bitfield
  146. {
  147. unsigned ihdr: 1;
  148. unsigned plte: 1;
  149. unsigned chrm: 1;
  150. unsigned iccp: 1;
  151. unsigned gama: 1;
  152. unsigned sbit: 1;
  153. unsigned srgb: 1;
  154. unsigned text: 1;
  155. unsigned bkgd: 1;
  156. unsigned hist: 1;
  157. unsigned trns: 1;
  158. unsigned phys: 1;
  159. unsigned splt: 1;
  160. unsigned time: 1;
  161. unsigned offs: 1;
  162. unsigned exif: 1;
  163. unsigned unknown: 1;
  164. };
  165. /* Packed sample iterator */
  166. struct spng__iter
  167. {
  168. const uint8_t mask;
  169. unsigned shift_amount;
  170. const unsigned initial_shift, bit_depth;
  171. const unsigned char *samples;
  172. };
  173. union spng__decode_plte
  174. {
  175. struct spng_plte_entry rgba[256];
  176. unsigned char rgb[256 * 3];
  177. unsigned char raw[256 * 4];
  178. uint32_t align_this;
  179. };
  180. struct spng__zlib_options
  181. {
  182. int compression_level;
  183. int window_bits;
  184. int mem_level;
  185. int strategy;
  186. int data_type;
  187. };
  188. typedef void spng__undo(spng_ctx *ctx);
  189. struct spng_ctx
  190. {
  191. size_t data_size;
  192. size_t bytes_read;
  193. size_t stream_buf_size;
  194. unsigned char *stream_buf;
  195. const unsigned char *data;
  196. /* User-defined pointers for streaming */
  197. spng_read_fn *read_fn;
  198. spng_write_fn *write_fn;
  199. void *stream_user_ptr;
  200. /* Used for buffer reads */
  201. const unsigned char *png_base;
  202. size_t bytes_left;
  203. size_t last_read_size;
  204. /* Used for encoding */
  205. int user_owns_out_png;
  206. unsigned char *out_png;
  207. unsigned char *write_ptr;
  208. size_t out_png_size;
  209. size_t bytes_encoded;
  210. /* These are updated by read/write_header()/read_chunk_bytes() */
  211. struct spng_chunk current_chunk;
  212. uint32_t cur_chunk_bytes_left;
  213. uint32_t cur_actual_crc;
  214. struct spng_alloc alloc;
  215. enum spng_ctx_flags flags;
  216. enum spng_format fmt;
  217. enum spng_state state;
  218. unsigned streaming: 1;
  219. unsigned internal_buffer: 1; /* encoding to internal buffer */
  220. unsigned inflate: 1;
  221. unsigned deflate: 1;
  222. unsigned encode_only: 1;
  223. unsigned strict: 1;
  224. unsigned discard: 1;
  225. unsigned skip_crc: 1;
  226. unsigned keep_unknown: 1;
  227. unsigned prev_was_idat: 1;
  228. struct spng__zlib_options image_options;
  229. struct spng__zlib_options text_options;
  230. spng__undo *undo;
  231. /* input file contains this chunk */
  232. struct spng_chunk_bitfield file;
  233. /* chunk was stored with spng_set_*() */
  234. struct spng_chunk_bitfield user;
  235. /* chunk was stored by reading or with spng_set_*() */
  236. struct spng_chunk_bitfield stored;
  237. /* used to reset the above in case of an error */
  238. struct spng_chunk_bitfield prev_stored;
  239. struct spng_chunk first_idat, last_idat;
  240. uint32_t max_width, max_height;
  241. size_t max_chunk_size;
  242. size_t chunk_cache_limit;
  243. size_t chunk_cache_usage;
  244. uint32_t chunk_count_limit;
  245. uint32_t chunk_count_total;
  246. int crc_action_critical;
  247. int crc_action_ancillary;
  248. uint32_t optimize_option;
  249. struct spng_ihdr ihdr;
  250. struct spng_plte plte;
  251. struct spng_chrm_int chrm_int;
  252. struct spng_iccp iccp;
  253. uint32_t gama;
  254. struct spng_sbit sbit;
  255. uint8_t srgb_rendering_intent;
  256. uint32_t n_text;
  257. struct spng_text2 *text_list;
  258. struct spng_bkgd bkgd;
  259. struct spng_hist hist;
  260. struct spng_trns trns;
  261. struct spng_phys phys;
  262. uint32_t n_splt;
  263. struct spng_splt *splt_list;
  264. struct spng_time time;
  265. struct spng_offs offs;
  266. struct spng_exif exif;
  267. uint32_t n_chunks;
  268. struct spng_unknown_chunk *chunk_list;
  269. struct spng_subimage subimage[7];
  270. z_stream zstream;
  271. unsigned char *scanline_buf, *prev_scanline_buf, *row_buf, *filtered_scanline_buf;
  272. unsigned char *scanline, *prev_scanline, *row, *filtered_scanline;
  273. /* based on fmt */
  274. size_t image_size; /* may be zero */
  275. size_t image_width;
  276. unsigned bytes_per_pixel; /* derived from ihdr */
  277. unsigned pixel_size; /* derived from spng_format+ihdr */
  278. int widest_pass;
  279. int last_pass; /* last non-empty pass */
  280. uint16_t *gamma_lut; /* points to either _lut8 or _lut16 */
  281. uint16_t *gamma_lut16;
  282. uint16_t gamma_lut8[256];
  283. unsigned char trns_px[8];
  284. union spng__decode_plte decode_plte;
  285. struct spng_sbit decode_sb;
  286. struct decode_flags decode_flags;
  287. struct spng_row_info row_info;
  288. struct encode_flags encode_flags;
  289. };
  290. static const uint32_t spng_u32max = INT32_MAX;
  291. static const uint32_t adam7_x_start[7] = { 0, 4, 0, 2, 0, 1, 0 };
  292. static const uint32_t adam7_y_start[7] = { 0, 0, 4, 0, 2, 0, 1 };
  293. static const uint32_t adam7_x_delta[7] = { 8, 8, 4, 4, 2, 2, 1 };
  294. static const uint32_t adam7_y_delta[7] = { 8, 8, 8, 4, 4, 2, 2 };
  295. static const uint8_t spng_signature[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
  296. static const uint8_t type_ihdr[4] = { 73, 72, 68, 82 };
  297. static const uint8_t type_plte[4] = { 80, 76, 84, 69 };
  298. static const uint8_t type_idat[4] = { 73, 68, 65, 84 };
  299. static const uint8_t type_iend[4] = { 73, 69, 78, 68 };
  300. static const uint8_t type_trns[4] = { 116, 82, 78, 83 };
  301. static const uint8_t type_chrm[4] = { 99, 72, 82, 77 };
  302. static const uint8_t type_gama[4] = { 103, 65, 77, 65 };
  303. static const uint8_t type_iccp[4] = { 105, 67, 67, 80 };
  304. static const uint8_t type_sbit[4] = { 115, 66, 73, 84 };
  305. static const uint8_t type_srgb[4] = { 115, 82, 71, 66 };
  306. static const uint8_t type_text[4] = { 116, 69, 88, 116 };
  307. static const uint8_t type_ztxt[4] = { 122, 84, 88, 116 };
  308. static const uint8_t type_itxt[4] = { 105, 84, 88, 116 };
  309. static const uint8_t type_bkgd[4] = { 98, 75, 71, 68 };
  310. static const uint8_t type_hist[4] = { 104, 73, 83, 84 };
  311. static const uint8_t type_phys[4] = { 112, 72, 89, 115 };
  312. static const uint8_t type_splt[4] = { 115, 80, 76, 84 };
  313. static const uint8_t type_time[4] = { 116, 73, 77, 69 };
  314. static const uint8_t type_offs[4] = { 111, 70, 70, 115 };
  315. static const uint8_t type_exif[4] = { 101, 88, 73, 102 };
  316. static inline void *spng__malloc(spng_ctx *ctx, size_t size)
  317. {
  318. return ctx->alloc.malloc_fn(size);
  319. }
  320. static inline void *spng__calloc(spng_ctx *ctx, size_t nmemb, size_t size)
  321. {
  322. return ctx->alloc.calloc_fn(nmemb, size);
  323. }
  324. static inline void *spng__realloc(spng_ctx *ctx, void *ptr, size_t size)
  325. {
  326. return ctx->alloc.realloc_fn(ptr, size);
  327. }
  328. static inline void spng__free(spng_ctx *ctx, void *ptr)
  329. {
  330. ctx->alloc.free_fn(ptr);
  331. }
  332. #if defined(SPNG_USE_MINIZ)
  333. static void *spng__zalloc(void *opaque, size_t items, size_t size)
  334. #else
  335. static void *spng__zalloc(void *opaque, uInt items, uInt size)
  336. #endif
  337. {
  338. spng_ctx *ctx = opaque;
  339. if(size > SIZE_MAX / items) return NULL;
  340. size_t len = (size_t)items * size;
  341. return spng__malloc(ctx, len);
  342. }
  343. static void spng__zfree(void *opqaue, void *ptr)
  344. {
  345. spng_ctx *ctx = opqaue;
  346. spng__free(ctx, ptr);
  347. }
  348. static inline uint16_t read_u16(const void *src)
  349. {
  350. const unsigned char *data = src;
  351. return (data[0] & 0xFFU) << 8 | (data[1] & 0xFFU);
  352. }
  353. static inline uint32_t read_u32(const void *src)
  354. {
  355. const unsigned char *data = src;
  356. return (data[0] & 0xFFUL) << 24 | (data[1] & 0xFFUL) << 16 |
  357. (data[2] & 0xFFUL) << 8 | (data[3] & 0xFFUL);
  358. }
  359. static inline int32_t read_s32(const void *src)
  360. {
  361. int32_t ret = (int32_t)read_u32(src);
  362. return ret;
  363. }
  364. static inline void write_u16(void *dest, uint16_t x)
  365. {
  366. unsigned char *data = dest;
  367. data[0] = x >> 8;
  368. data[1] = x & 0xFF;
  369. }
  370. static inline void write_u32(void *dest, uint32_t x)
  371. {
  372. unsigned char *data = dest;
  373. data[0] = (x >> 24);
  374. data[1] = (x >> 16) & 0xFF;
  375. data[2] = (x >> 8) & 0xFF;
  376. data[3] = x & 0xFF;
  377. }
  378. static inline void write_s32(void *dest, int32_t x)
  379. {
  380. uint32_t n = x;
  381. write_u32(dest, n);
  382. }
  383. /* Returns an iterator for 1,2,4,8-bit samples */
  384. static struct spng__iter spng__iter_init(unsigned bit_depth, const unsigned char *samples)
  385. {
  386. struct spng__iter iter =
  387. {
  388. .mask = (uint32_t)(1 << bit_depth) - 1,
  389. .shift_amount = 8 - bit_depth,
  390. .initial_shift = 8 - bit_depth,
  391. .bit_depth = bit_depth,
  392. .samples = samples
  393. };
  394. return iter;
  395. }
  396. /* Returns the current sample unpacked, iterates to the next one */
  397. static inline uint8_t get_sample(struct spng__iter *iter)
  398. {
  399. uint8_t x = (iter->samples[0] >> iter->shift_amount) & iter->mask;
  400. iter->shift_amount -= iter->bit_depth;
  401. if(iter->shift_amount > 7)
  402. {
  403. iter->shift_amount = iter->initial_shift;
  404. iter->samples++;
  405. }
  406. return x;
  407. }
  408. static void u16_row_to_host(void *row, size_t size)
  409. {
  410. uint16_t *px = row;
  411. size_t i, n = size / 2;
  412. for(i=0; i < n; i++)
  413. {
  414. px[i] = read_u16(&px[i]);
  415. }
  416. }
  417. static void u16_row_to_bigendian(void *row, size_t size)
  418. {
  419. uint16_t *px = (uint16_t*)row;
  420. size_t i, n = size / 2;
  421. for(i=0; i < n; i++)
  422. {
  423. write_u16(&px[i], px[i]);
  424. }
  425. }
  426. static void rgb8_row_to_rgba8(const unsigned char *row, unsigned char *out, uint32_t n)
  427. {
  428. uint32_t i;
  429. for(i=0; i < n; i++)
  430. {
  431. memcpy(out + i * 4, row + i * 3, 3);
  432. out[i*4+3] = 255;
  433. }
  434. }
  435. static unsigned num_channels(const struct spng_ihdr *ihdr)
  436. {
  437. switch(ihdr->color_type)
  438. {
  439. case SPNG_COLOR_TYPE_TRUECOLOR: return 3;
  440. case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA: return 2;
  441. case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA: return 4;
  442. case SPNG_COLOR_TYPE_GRAYSCALE:
  443. case SPNG_COLOR_TYPE_INDEXED:
  444. return 1;
  445. default: return 0;
  446. }
  447. }
  448. /* Calculate scanline width in bits, round up to the nearest byte */
  449. static int calculate_scanline_width(const struct spng_ihdr *ihdr, uint32_t width, size_t *scanline_width)
  450. {
  451. if(ihdr == NULL || !width) return SPNG_EINTERNAL;
  452. size_t res = num_channels(ihdr) * ihdr->bit_depth;
  453. if(res > SIZE_MAX / width) return SPNG_EOVERFLOW;
  454. res = res * width;
  455. res += 15; /* Filter byte + 7 for rounding */
  456. if(res < 15) return SPNG_EOVERFLOW;
  457. res /= 8;
  458. if(res > UINT32_MAX) return SPNG_EOVERFLOW;
  459. *scanline_width = res;
  460. return 0;
  461. }
  462. static int calculate_subimages(struct spng_ctx *ctx)
  463. {
  464. if(ctx == NULL) return SPNG_EINTERNAL;
  465. struct spng_ihdr *ihdr = &ctx->ihdr;
  466. struct spng_subimage *sub = ctx->subimage;
  467. if(ihdr->interlace_method == 1)
  468. {
  469. sub[0].width = (ihdr->width + 7) >> 3;
  470. sub[0].height = (ihdr->height + 7) >> 3;
  471. sub[1].width = (ihdr->width + 3) >> 3;
  472. sub[1].height = (ihdr->height + 7) >> 3;
  473. sub[2].width = (ihdr->width + 3) >> 2;
  474. sub[2].height = (ihdr->height + 3) >> 3;
  475. sub[3].width = (ihdr->width + 1) >> 2;
  476. sub[3].height = (ihdr->height + 3) >> 2;
  477. sub[4].width = (ihdr->width + 1) >> 1;
  478. sub[4].height = (ihdr->height + 1) >> 2;
  479. sub[5].width = ihdr->width >> 1;
  480. sub[5].height = (ihdr->height + 1) >> 1;
  481. sub[6].width = ihdr->width;
  482. sub[6].height = ihdr->height >> 1;
  483. }
  484. else
  485. {
  486. sub[0].width = ihdr->width;
  487. sub[0].height = ihdr->height;
  488. }
  489. int i;
  490. for(i=0; i < 7; i++)
  491. {
  492. if(sub[i].width == 0 || sub[i].height == 0) continue;
  493. int ret = calculate_scanline_width(ihdr, sub[i].width, &sub[i].scanline_width);
  494. if(ret) return ret;
  495. if(sub[ctx->widest_pass].scanline_width < sub[i].scanline_width) ctx->widest_pass = i;
  496. ctx->last_pass = i;
  497. }
  498. return 0;
  499. }
  500. static int check_decode_fmt(const struct spng_ihdr *ihdr, const int fmt)
  501. {
  502. switch(fmt)
  503. {
  504. case SPNG_FMT_RGBA8:
  505. case SPNG_FMT_RGBA16:
  506. case SPNG_FMT_RGB8:
  507. case SPNG_FMT_PNG:
  508. case SPNG_FMT_RAW:
  509. return 0;
  510. case SPNG_FMT_G8:
  511. case SPNG_FMT_GA8:
  512. if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE && ihdr->bit_depth <= 8) return 0;
  513. else return SPNG_EFMT;
  514. case SPNG_FMT_GA16:
  515. if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE && ihdr->bit_depth == 16) return 0;
  516. else return SPNG_EFMT;
  517. default: return SPNG_EFMT;
  518. }
  519. }
  520. static int calculate_image_width(const struct spng_ihdr *ihdr, int fmt, size_t *len)
  521. {
  522. if(ihdr == NULL || len == NULL) return SPNG_EINTERNAL;
  523. size_t res = ihdr->width;
  524. unsigned bytes_per_pixel;
  525. switch(fmt)
  526. {
  527. case SPNG_FMT_RGBA8:
  528. case SPNG_FMT_GA16:
  529. bytes_per_pixel = 4;
  530. break;
  531. case SPNG_FMT_RGBA16:
  532. bytes_per_pixel = 8;
  533. break;
  534. case SPNG_FMT_RGB8:
  535. bytes_per_pixel = 3;
  536. break;
  537. case SPNG_FMT_PNG:
  538. case SPNG_FMT_RAW:
  539. {
  540. int ret = calculate_scanline_width(ihdr, ihdr->width, &res);
  541. if(ret) return ret;
  542. res -= 1; /* exclude filter byte */
  543. bytes_per_pixel = 1;
  544. break;
  545. }
  546. case SPNG_FMT_G8:
  547. bytes_per_pixel = 1;
  548. break;
  549. case SPNG_FMT_GA8:
  550. bytes_per_pixel = 2;
  551. break;
  552. default: return SPNG_EINTERNAL;
  553. }
  554. if(res > SIZE_MAX / bytes_per_pixel) return SPNG_EOVERFLOW;
  555. res = res * bytes_per_pixel;
  556. *len = res;
  557. return 0;
  558. }
  559. static int calculate_image_size(const struct spng_ihdr *ihdr, int fmt, size_t *len)
  560. {
  561. if(ihdr == NULL || len == NULL) return SPNG_EINTERNAL;
  562. size_t res = 0;
  563. int ret = calculate_image_width(ihdr, fmt, &res);
  564. if(ret) return ret;
  565. if(res > SIZE_MAX / ihdr->height) return SPNG_EOVERFLOW;
  566. res = res * ihdr->height;
  567. *len = res;
  568. return 0;
  569. }
  570. static int increase_cache_usage(spng_ctx *ctx, size_t bytes, int new_chunk)
  571. {
  572. if(ctx == NULL || !bytes) return SPNG_EINTERNAL;
  573. if(new_chunk)
  574. {
  575. ctx->chunk_count_total++;
  576. if(ctx->chunk_count_total < 1) return SPNG_EOVERFLOW;
  577. if(ctx->chunk_count_total > ctx->chunk_count_limit) return SPNG_ECHUNK_LIMITS;
  578. }
  579. size_t new_usage = ctx->chunk_cache_usage + bytes;
  580. if(new_usage < ctx->chunk_cache_usage) return SPNG_EOVERFLOW;
  581. if(new_usage > ctx->chunk_cache_limit) return SPNG_ECHUNK_LIMITS;
  582. ctx->chunk_cache_usage = new_usage;
  583. return 0;
  584. }
  585. static int decrease_cache_usage(spng_ctx *ctx, size_t usage)
  586. {
  587. if(ctx == NULL || !usage) return SPNG_EINTERNAL;
  588. if(usage > ctx->chunk_cache_usage) return SPNG_EINTERNAL;
  589. ctx->chunk_cache_usage -= usage;
  590. return 0;
  591. }
  592. static int is_critical_chunk(struct spng_chunk *chunk)
  593. {
  594. if(chunk == NULL) return 0;
  595. if((chunk->type[0] & (1 << 5)) == 0) return 1;
  596. return 0;
  597. }
  598. static int decode_err(spng_ctx *ctx, int err)
  599. {
  600. ctx->state = SPNG_STATE_INVALID;
  601. return err;
  602. }
  603. static int encode_err(spng_ctx *ctx, int err)
  604. {
  605. ctx->state = SPNG_STATE_INVALID;
  606. return err;
  607. }
  608. static inline int read_data(spng_ctx *ctx, size_t bytes)
  609. {
  610. if(ctx == NULL) return SPNG_EINTERNAL;
  611. if(!bytes) return 0;
  612. if(ctx->streaming && (bytes > SPNG_READ_SIZE)) return SPNG_EINTERNAL;
  613. int ret = ctx->read_fn(ctx, ctx->stream_user_ptr, ctx->stream_buf, bytes);
  614. if(ret)
  615. {
  616. if(ret > 0 || ret < SPNG_IO_ERROR) ret = SPNG_IO_ERROR;
  617. return ret;
  618. }
  619. ctx->bytes_read += bytes;
  620. if(ctx->bytes_read < bytes) return SPNG_EOVERFLOW;
  621. return 0;
  622. }
  623. /* Ensure there is enough space for encoding starting at ctx->write_ptr */
  624. static int require_bytes(spng_ctx *ctx, size_t bytes)
  625. {
  626. if(ctx == NULL) return SPNG_EINTERNAL;
  627. if(ctx->streaming)
  628. {
  629. if(bytes > ctx->stream_buf_size)
  630. {
  631. size_t new_size = ctx->stream_buf_size;
  632. /* Start at default IDAT size + header + crc */
  633. if(new_size < (SPNG_WRITE_SIZE + 12)) new_size = SPNG_WRITE_SIZE + 12;
  634. if(new_size < bytes) new_size = bytes;
  635. void *temp = spng__realloc(ctx, ctx->stream_buf, new_size);
  636. if(temp == NULL) return encode_err(ctx, SPNG_EMEM);
  637. ctx->stream_buf = temp;
  638. ctx->stream_buf_size = bytes;
  639. ctx->write_ptr = ctx->stream_buf;
  640. }
  641. return 0;
  642. }
  643. if(!ctx->internal_buffer) return SPNG_ENODST;
  644. size_t required = ctx->bytes_encoded + bytes;
  645. if(required < bytes) return SPNG_EOVERFLOW;
  646. if(required > ctx->out_png_size)
  647. {
  648. size_t new_size = ctx->out_png_size;
  649. /* Start with a size that doesn't require a realloc() 100% of the time */
  650. if(new_size < (SPNG_WRITE_SIZE * 2)) new_size = SPNG_WRITE_SIZE * 2;
  651. /* Prefer the next power of two over the requested size */
  652. while(new_size < required)
  653. {
  654. if(new_size / SIZE_MAX > 2) return encode_err(ctx, SPNG_EOVERFLOW);
  655. new_size *= 2;
  656. }
  657. void *temp = spng__realloc(ctx, ctx->out_png, new_size);
  658. if(temp == NULL) return encode_err(ctx, SPNG_EMEM);
  659. ctx->out_png = temp;
  660. ctx->out_png_size = new_size;
  661. ctx->write_ptr = ctx->out_png + ctx->bytes_encoded;
  662. }
  663. return 0;
  664. }
  665. static int write_data(spng_ctx *ctx, const void *data, size_t bytes)
  666. {
  667. if(ctx == NULL) return SPNG_EINTERNAL;
  668. if(!bytes) return 0;
  669. if(ctx->streaming)
  670. {
  671. if(bytes > SPNG_WRITE_SIZE) return SPNG_EINTERNAL;
  672. int ret = ctx->write_fn(ctx, ctx->stream_user_ptr, (void*)data, bytes);
  673. if(ret)
  674. {
  675. if(ret > 0 || ret < SPNG_IO_ERROR) ret = SPNG_IO_ERROR;
  676. return encode_err(ctx, ret);
  677. }
  678. }
  679. else
  680. {
  681. int ret = require_bytes(ctx, bytes);
  682. if(ret) return encode_err(ctx, ret);
  683. memcpy(ctx->write_ptr, data, bytes);
  684. ctx->write_ptr += bytes;
  685. }
  686. ctx->bytes_encoded += bytes;
  687. if(ctx->bytes_encoded < bytes) return SPNG_EOVERFLOW;
  688. return 0;
  689. }
  690. static int write_header(spng_ctx *ctx, const uint8_t chunk_type[4], size_t chunk_length, unsigned char **data)
  691. {
  692. if(ctx == NULL || chunk_type == NULL) return SPNG_EINTERNAL;
  693. if(chunk_length > spng_u32max) return SPNG_EINTERNAL;
  694. size_t total = chunk_length + 12;
  695. int ret = require_bytes(ctx, total);
  696. if(ret) return ret;
  697. uint32_t crc = crc32(0, NULL, 0);
  698. ctx->current_chunk.crc = crc32(crc, chunk_type, 4);
  699. memcpy(&ctx->current_chunk.type, chunk_type, 4);
  700. ctx->current_chunk.length = (uint32_t)chunk_length;
  701. if(!data) return SPNG_EINTERNAL;
  702. if(ctx->streaming) *data = ctx->stream_buf + 8;
  703. else *data = ctx->write_ptr + 8;
  704. return 0;
  705. }
  706. static int trim_chunk(spng_ctx *ctx, uint32_t length)
  707. {
  708. if(length > spng_u32max) return SPNG_EINTERNAL;
  709. if(length > ctx->current_chunk.length) return SPNG_EINTERNAL;
  710. ctx->current_chunk.length = length;
  711. return 0;
  712. }
  713. static int finish_chunk(spng_ctx *ctx)
  714. {
  715. if(ctx == NULL) return SPNG_EINTERNAL;
  716. struct spng_chunk *chunk = &ctx->current_chunk;
  717. unsigned char *header;
  718. unsigned char *chunk_data;
  719. if(ctx->streaming)
  720. {
  721. chunk_data = ctx->stream_buf + 8;
  722. header = ctx->stream_buf;
  723. }
  724. else
  725. {
  726. chunk_data = ctx->write_ptr + 8;
  727. header = ctx->write_ptr;
  728. }
  729. write_u32(header, chunk->length);
  730. memcpy(header + 4, chunk->type, 4);
  731. chunk->crc = crc32(chunk->crc, chunk_data, chunk->length);
  732. write_u32(chunk_data + chunk->length, chunk->crc);
  733. if(ctx->streaming)
  734. {
  735. const unsigned char *ptr = ctx->stream_buf;
  736. uint32_t bytes_left = chunk->length + 12;
  737. uint32_t len = 0;
  738. while(bytes_left)
  739. {
  740. ptr += len;
  741. len = SPNG_WRITE_SIZE;
  742. if(len > bytes_left) len = bytes_left;
  743. int ret = write_data(ctx, ptr, len);
  744. if(ret) return ret;
  745. bytes_left -= len;
  746. }
  747. }
  748. else
  749. {
  750. ctx->bytes_encoded += chunk->length;
  751. if(ctx->bytes_encoded < chunk->length) return SPNG_EOVERFLOW;
  752. ctx->bytes_encoded += 12;
  753. if(ctx->bytes_encoded < 12) return SPNG_EOVERFLOW;
  754. ctx->write_ptr += chunk->length + 12;
  755. }
  756. return 0;
  757. }
  758. static int write_chunk(spng_ctx *ctx, const uint8_t type[4], const void *data, size_t length)
  759. {
  760. if(ctx == NULL || type == NULL) return SPNG_EINTERNAL;
  761. if(length && data == NULL) return SPNG_EINTERNAL;
  762. unsigned char *write_ptr;
  763. int ret = write_header(ctx, type, length, &write_ptr);
  764. if(ret) return ret;
  765. if(length) memcpy(write_ptr, data, length);
  766. return finish_chunk(ctx);
  767. }
  768. static int write_iend(spng_ctx *ctx)
  769. {
  770. unsigned char iend_chunk[12] = { 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130 };
  771. return write_data(ctx, iend_chunk, 12);
  772. }
  773. static int write_unknown_chunks(spng_ctx *ctx, enum spng_location location)
  774. {
  775. if(!ctx->stored.unknown) return 0;
  776. const struct spng_unknown_chunk *chunk = ctx->chunk_list;
  777. uint32_t i;
  778. for(i=0; i < ctx->n_chunks; i++, chunk++)
  779. {
  780. if(chunk->location != location) continue;
  781. int ret = write_chunk(ctx, chunk->type, chunk->data, chunk->length);
  782. if(ret) return ret;
  783. }
  784. return 0;
  785. }
  786. /* Read and check the current chunk's crc,
  787. returns -SPNG_CRC_DISCARD if the chunk should be discarded */
  788. static inline int read_and_check_crc(spng_ctx *ctx)
  789. {
  790. if(ctx == NULL) return SPNG_EINTERNAL;
  791. int ret;
  792. ret = read_data(ctx, 4);
  793. if(ret) return ret;
  794. ctx->current_chunk.crc = read_u32(ctx->data);
  795. if(ctx->skip_crc) return 0;
  796. if(ctx->cur_actual_crc != ctx->current_chunk.crc)
  797. {
  798. if(is_critical_chunk(&ctx->current_chunk))
  799. {
  800. if(ctx->crc_action_critical == SPNG_CRC_USE) return 0;
  801. }
  802. else
  803. {
  804. if(ctx->crc_action_ancillary == SPNG_CRC_USE) return 0;
  805. if(ctx->crc_action_ancillary == SPNG_CRC_DISCARD) return -SPNG_CRC_DISCARD;
  806. }
  807. return SPNG_ECHUNK_CRC;
  808. }
  809. return 0;
  810. }
  811. /* Read and validate the current chunk's crc and the next chunk header */
  812. static inline int read_header(spng_ctx *ctx)
  813. {
  814. if(ctx == NULL) return SPNG_EINTERNAL;
  815. int ret;
  816. struct spng_chunk chunk = { 0 };
  817. ret = read_and_check_crc(ctx);
  818. if(ret)
  819. {
  820. if(ret == -SPNG_CRC_DISCARD)
  821. {
  822. ctx->discard = 1;
  823. }
  824. else return ret;
  825. }
  826. ret = read_data(ctx, 8);
  827. if(ret) return ret;
  828. chunk.offset = ctx->bytes_read - 8;
  829. chunk.length = read_u32(ctx->data);
  830. memcpy(&chunk.type, ctx->data + 4, 4);
  831. if(chunk.length > spng_u32max) return SPNG_ECHUNK_STDLEN;
  832. ctx->cur_chunk_bytes_left = chunk.length;
  833. if(is_critical_chunk(&chunk) && ctx->crc_action_critical == SPNG_CRC_USE) ctx->skip_crc = 1;
  834. else if(ctx->crc_action_ancillary == SPNG_CRC_USE) ctx->skip_crc = 1;
  835. else ctx->skip_crc = 0;
  836. if(!ctx->skip_crc)
  837. {
  838. ctx->cur_actual_crc = crc32(0, NULL, 0);
  839. ctx->cur_actual_crc = crc32(ctx->cur_actual_crc, chunk.type, 4);
  840. }
  841. ctx->current_chunk = chunk;
  842. return 0;
  843. }
  844. /* Read chunk bytes and update crc */
  845. static int read_chunk_bytes(spng_ctx *ctx, uint32_t bytes)
  846. {
  847. if(ctx == NULL) return SPNG_EINTERNAL;
  848. if(!ctx->cur_chunk_bytes_left || !bytes) return SPNG_EINTERNAL;
  849. if(bytes > ctx->cur_chunk_bytes_left) return SPNG_EINTERNAL; /* XXX: more specific error? */
  850. int ret;
  851. ret = read_data(ctx, bytes);
  852. if(ret) return ret;
  853. if(!ctx->skip_crc) ctx->cur_actual_crc = crc32(ctx->cur_actual_crc, ctx->data, bytes);
  854. ctx->cur_chunk_bytes_left -= bytes;
  855. return ret;
  856. }
  857. /* read_chunk_bytes() + read_data() with custom output buffer */
  858. static int read_chunk_bytes2(spng_ctx *ctx, void *out, uint32_t bytes)
  859. {
  860. if(ctx == NULL) return SPNG_EINTERNAL;
  861. if(!ctx->cur_chunk_bytes_left || !bytes) return SPNG_EINTERNAL;
  862. if(bytes > ctx->cur_chunk_bytes_left) return SPNG_EINTERNAL; /* XXX: more specific error? */
  863. int ret;
  864. uint32_t len = bytes;
  865. if(ctx->streaming && len > SPNG_READ_SIZE) len = SPNG_READ_SIZE;
  866. while(bytes)
  867. {
  868. if(len > bytes) len = bytes;
  869. ret = ctx->read_fn(ctx, ctx->stream_user_ptr, out, len);
  870. if(ret) return ret;
  871. if(!ctx->streaming) memcpy(out, ctx->data, len);
  872. ctx->bytes_read += len;
  873. if(ctx->bytes_read < len) return SPNG_EOVERFLOW;
  874. if(!ctx->skip_crc) ctx->cur_actual_crc = crc32(ctx->cur_actual_crc, out, len);
  875. ctx->cur_chunk_bytes_left -= len;
  876. out = (char*)out + len;
  877. bytes -= len;
  878. len = SPNG_READ_SIZE;
  879. }
  880. return 0;
  881. }
  882. static int discard_chunk_bytes(spng_ctx *ctx, uint32_t bytes)
  883. {
  884. if(ctx == NULL) return SPNG_EINTERNAL;
  885. if(!bytes) return 0;
  886. int ret;
  887. if(ctx->streaming) /* Do small, consecutive reads */
  888. {
  889. while(bytes)
  890. {
  891. uint32_t len = SPNG_READ_SIZE;
  892. if(len > bytes) len = bytes;
  893. ret = read_chunk_bytes(ctx, len);
  894. if(ret) return ret;
  895. bytes -= len;
  896. }
  897. }
  898. else
  899. {
  900. ret = read_chunk_bytes(ctx, bytes);
  901. if(ret) return ret;
  902. }
  903. return 0;
  904. }
  905. static int spng__inflate_init(spng_ctx *ctx, int window_bits)
  906. {
  907. if(ctx->zstream.state) inflateEnd(&ctx->zstream);
  908. ctx->inflate = 1;
  909. ctx->zstream.zalloc = spng__zalloc;
  910. ctx->zstream.zfree = spng__zfree;
  911. ctx->zstream.opaque = ctx;
  912. if(inflateInit2(&ctx->zstream, window_bits) != Z_OK) return SPNG_EZLIB_INIT;
  913. #if ZLIB_VERNUM >= 0x1290 && !defined(SPNG_USE_MINIZ)
  914. int validate = 1;
  915. if(ctx->flags & SPNG_CTX_IGNORE_ADLER32) validate = 0;
  916. if(is_critical_chunk(&ctx->current_chunk))
  917. {
  918. if(ctx->crc_action_critical == SPNG_CRC_USE) validate = 0;
  919. }
  920. else /* ancillary */
  921. {
  922. if(ctx->crc_action_ancillary == SPNG_CRC_USE) validate = 0;
  923. }
  924. if(inflateValidate(&ctx->zstream, validate)) return SPNG_EZLIB_INIT;
  925. #else /* This requires zlib >= 1.2.11 */
  926. #pragma message ("inflateValidate() not available, SPNG_CTX_IGNORE_ADLER32 will be ignored")
  927. #endif
  928. return 0;
  929. }
  930. static int spng__deflate_init(spng_ctx *ctx, struct spng__zlib_options *options)
  931. {
  932. if(ctx->zstream.state) deflateEnd(&ctx->zstream);
  933. ctx->deflate = 1;
  934. z_stream *zstream = &ctx->zstream;
  935. zstream->zalloc = spng__zalloc;
  936. zstream->zfree = spng__zfree;
  937. zstream->opaque = ctx;
  938. zstream->data_type = options->data_type;
  939. int ret = deflateInit2(zstream, options->compression_level, Z_DEFLATED, options->window_bits, options->mem_level, options->strategy);
  940. if(ret != Z_OK) return SPNG_EZLIB_INIT;
  941. return 0;
  942. }
  943. /* Inflate a zlib stream starting with start_buf if non-NULL,
  944. continuing from the datastream till an end marker,
  945. allocating and writing the inflated stream to *out,
  946. leaving "extra" bytes at the end, final buffer length is *len.
  947. Takes into account the chunk size and cache limits.
  948. */
  949. static int spng__inflate_stream(spng_ctx *ctx, char **out, size_t *len, size_t extra, const void *start_buf, size_t start_len)
  950. {
  951. int ret = spng__inflate_init(ctx, 15);
  952. if(ret) return ret;
  953. size_t max = ctx->chunk_cache_limit - ctx->chunk_cache_usage;
  954. if(ctx->max_chunk_size < max) max = ctx->max_chunk_size;
  955. if(extra > max) return SPNG_ECHUNK_LIMITS;
  956. max -= extra;
  957. uint32_t read_size;
  958. size_t size = 8 * 1024;
  959. void *t, *buf = spng__malloc(ctx, size);
  960. if(buf == NULL) return SPNG_EMEM;
  961. z_stream *stream = &ctx->zstream;
  962. if(start_buf != NULL && start_len)
  963. {
  964. stream->avail_in = (uInt)start_len;
  965. stream->next_in = start_buf;
  966. }
  967. else
  968. {
  969. stream->avail_in = 0;
  970. stream->next_in = NULL;
  971. }
  972. stream->avail_out = (uInt)size;
  973. stream->next_out = buf;
  974. while(ret != Z_STREAM_END)
  975. {
  976. ret = inflate(stream, Z_NO_FLUSH);
  977. if(ret == Z_STREAM_END) break;
  978. if(ret != Z_OK && ret != Z_BUF_ERROR)
  979. {
  980. ret = SPNG_EZLIB;
  981. goto err;
  982. }
  983. if(!stream->avail_out) /* Resize buffer */
  984. {
  985. /* overflow or reached chunk/cache limit */
  986. if( (2 > SIZE_MAX / size) || (size > max / 2) )
  987. {
  988. ret = SPNG_ECHUNK_LIMITS;
  989. goto err;
  990. }
  991. size *= 2;
  992. t = spng__realloc(ctx, buf, size);
  993. if(t == NULL) goto mem;
  994. buf = t;
  995. stream->avail_out = (uInt)size / 2;
  996. stream->next_out = (unsigned char*)buf + size / 2;
  997. }
  998. else if(!stream->avail_in) /* Read more chunk bytes */
  999. {
  1000. read_size = ctx->cur_chunk_bytes_left;
  1001. if(ctx->streaming && read_size > SPNG_READ_SIZE) read_size = SPNG_READ_SIZE;
  1002. ret = read_chunk_bytes(ctx, read_size);
  1003. if(ret)
  1004. {
  1005. if(!read_size) ret = SPNG_EZLIB;
  1006. goto err;
  1007. }
  1008. stream->avail_in = read_size;
  1009. stream->next_in = ctx->data;
  1010. }
  1011. }
  1012. size = stream->total_out;
  1013. if(!size)
  1014. {
  1015. ret = SPNG_EZLIB;
  1016. goto err;
  1017. }
  1018. size += extra;
  1019. if(size < extra) goto mem;
  1020. t = spng__realloc(ctx, buf, size);
  1021. if(t == NULL) goto mem;
  1022. buf = t;
  1023. (void)increase_cache_usage(ctx, size, 0);
  1024. *out = buf;
  1025. *len = size;
  1026. return 0;
  1027. mem:
  1028. ret = SPNG_EMEM;
  1029. err:
  1030. spng__free(ctx, buf);
  1031. return ret;
  1032. }
  1033. /* Read at least one byte from the IDAT stream */
  1034. static int read_idat_bytes(spng_ctx *ctx, uint32_t *bytes_read)
  1035. {
  1036. if(ctx == NULL || bytes_read == NULL) return SPNG_EINTERNAL;
  1037. if(memcmp(ctx->current_chunk.type, type_idat, 4)) return SPNG_EIDAT_TOO_SHORT;
  1038. int ret;
  1039. uint32_t len;
  1040. while(!ctx->cur_chunk_bytes_left)
  1041. {
  1042. ret = read_header(ctx);
  1043. if(ret) return ret;
  1044. if(memcmp(ctx->current_chunk.type, type_idat, 4)) return SPNG_EIDAT_TOO_SHORT;
  1045. }
  1046. if(ctx->streaming)
  1047. {/* TODO: estimate bytes to read for progressive reads */
  1048. len = SPNG_READ_SIZE;
  1049. if(len > ctx->cur_chunk_bytes_left) len = ctx->cur_chunk_bytes_left;
  1050. }
  1051. else len = ctx->current_chunk.length;
  1052. ret = read_chunk_bytes(ctx, len);
  1053. *bytes_read = len;
  1054. return ret;
  1055. }
  1056. static int read_scanline_bytes(spng_ctx *ctx, unsigned char *dest, size_t len)
  1057. {
  1058. if(ctx == NULL || dest == NULL) return SPNG_EINTERNAL;
  1059. int ret = Z_OK;
  1060. uint32_t bytes_read;
  1061. z_stream *zstream = &ctx->zstream;
  1062. zstream->avail_out = (uInt)len;
  1063. zstream->next_out = dest;
  1064. while(zstream->avail_out != 0)
  1065. {
  1066. ret = inflate(zstream, Z_NO_FLUSH);
  1067. if(ret == Z_OK) continue;
  1068. if(ret == Z_STREAM_END) /* Reached an end-marker */
  1069. {
  1070. if(zstream->avail_out != 0) return SPNG_EIDAT_TOO_SHORT;
  1071. }
  1072. else if(ret == Z_BUF_ERROR) /* Read more IDAT bytes */
  1073. {
  1074. ret = read_idat_bytes(ctx, &bytes_read);
  1075. if(ret) return ret;
  1076. zstream->avail_in = bytes_read;
  1077. zstream->next_in = ctx->data;
  1078. }
  1079. else return SPNG_EIDAT_STREAM;
  1080. }
  1081. return 0;
  1082. }
  1083. static uint8_t paeth(uint8_t a, uint8_t b, uint8_t c)
  1084. {
  1085. int16_t p = a + b - c;
  1086. int16_t pa = abs(p - a);
  1087. int16_t pb = abs(p - b);
  1088. int16_t pc = abs(p - c);
  1089. if(pa <= pb && pa <= pc) return a;
  1090. else if(pb <= pc) return b;
  1091. return c;
  1092. }
  1093. SPNG_TARGET_CLONES("default,avx2")
  1094. static void defilter_up(size_t bytes, unsigned char *row, const unsigned char *prev)
  1095. {
  1096. size_t i;
  1097. for(i=0; i < bytes; i++)
  1098. {
  1099. row[i] += prev[i];
  1100. }
  1101. }
  1102. /* Defilter *scanline in-place.
  1103. *prev_scanline and *scanline should point to the first pixel,
  1104. scanline_width is the width of the scanline including the filter byte.
  1105. */
  1106. static int defilter_scanline(const unsigned char *prev_scanline, unsigned char *scanline,
  1107. size_t scanline_width, unsigned bytes_per_pixel, unsigned filter)
  1108. {
  1109. if(prev_scanline == NULL || scanline == NULL || !scanline_width) return SPNG_EINTERNAL;
  1110. size_t i;
  1111. scanline_width--;
  1112. if(filter == 0) return 0;
  1113. #ifndef SPNG_DISABLE_OPT
  1114. if(filter == SPNG_FILTER_UP) goto no_opt;
  1115. if(bytes_per_pixel == 4)
  1116. {
  1117. if(filter == SPNG_FILTER_SUB)
  1118. defilter_sub4(scanline_width, scanline);
  1119. else if(filter == SPNG_FILTER_AVERAGE)
  1120. defilter_avg4(scanline_width, scanline, prev_scanline);
  1121. else if(filter == SPNG_FILTER_PAETH)
  1122. defilter_paeth4(scanline_width, scanline, prev_scanline);
  1123. else return SPNG_EFILTER;
  1124. return 0;
  1125. }
  1126. else if(bytes_per_pixel == 3)
  1127. {
  1128. if(filter == SPNG_FILTER_SUB)
  1129. defilter_sub3(scanline_width, scanline);
  1130. else if(filter == SPNG_FILTER_AVERAGE)
  1131. defilter_avg3(scanline_width, scanline, prev_scanline);
  1132. else if(filter == SPNG_FILTER_PAETH)
  1133. defilter_paeth3(scanline_width, scanline, prev_scanline);
  1134. else return SPNG_EFILTER;
  1135. return 0;
  1136. }
  1137. no_opt:
  1138. #endif
  1139. if(filter == SPNG_FILTER_UP)
  1140. {
  1141. defilter_up(scanline_width, scanline, prev_scanline);
  1142. return 0;
  1143. }
  1144. for(i=0; i < scanline_width; i++)
  1145. {
  1146. uint8_t x, a, b, c;
  1147. if(i >= bytes_per_pixel)
  1148. {
  1149. a = scanline[i - bytes_per_pixel];
  1150. b = prev_scanline[i];
  1151. c = prev_scanline[i - bytes_per_pixel];
  1152. }
  1153. else /* First pixel in row */
  1154. {
  1155. a = 0;
  1156. b = prev_scanline[i];
  1157. c = 0;
  1158. }
  1159. x = scanline[i];
  1160. switch(filter)
  1161. {
  1162. case SPNG_FILTER_SUB:
  1163. {
  1164. x = x + a;
  1165. break;
  1166. }
  1167. case SPNG_FILTER_AVERAGE:
  1168. {
  1169. uint16_t avg = (a + b) / 2;
  1170. x = x + avg;
  1171. break;
  1172. }
  1173. case SPNG_FILTER_PAETH:
  1174. {
  1175. x = x + paeth(a,b,c);
  1176. break;
  1177. }
  1178. }
  1179. scanline[i] = x;
  1180. }
  1181. return 0;
  1182. }
  1183. static int filter_scanline(unsigned char *filtered, const unsigned char *prev_scanline, const unsigned char *scanline,
  1184. size_t scanline_width, unsigned bytes_per_pixel, const unsigned filter)
  1185. {
  1186. if(prev_scanline == NULL || scanline == NULL || scanline_width <= 1) return SPNG_EINTERNAL;
  1187. if(filter > 4) return SPNG_EFILTER;
  1188. if(filter == 0) return 0;
  1189. scanline_width--;
  1190. uint32_t i;
  1191. for(i=0; i < scanline_width; i++)
  1192. {
  1193. uint8_t x, a, b, c;
  1194. if(i >= bytes_per_pixel)
  1195. {
  1196. a = scanline[i - bytes_per_pixel];
  1197. b = prev_scanline[i];
  1198. c = prev_scanline[i - bytes_per_pixel];
  1199. }
  1200. else /* first pixel in row */
  1201. {
  1202. a = 0;
  1203. b = prev_scanline[i];
  1204. c = 0;
  1205. }
  1206. x = scanline[i];
  1207. switch(filter)
  1208. {
  1209. case SPNG_FILTER_SUB:
  1210. {
  1211. x = x - a;
  1212. break;
  1213. }
  1214. case SPNG_FILTER_UP:
  1215. {
  1216. x = x - b;
  1217. break;
  1218. }
  1219. case SPNG_FILTER_AVERAGE:
  1220. {
  1221. uint16_t avg = (a + b) / 2;
  1222. x = x - avg;
  1223. break;
  1224. }
  1225. case SPNG_FILTER_PAETH:
  1226. {
  1227. x = x - paeth(a,b,c);
  1228. break;
  1229. }
  1230. }
  1231. filtered[i] = x;
  1232. }
  1233. return 0;
  1234. }
  1235. static int32_t filter_sum(const unsigned char *prev_scanline, const unsigned char *scanline,
  1236. size_t size, unsigned bytes_per_pixel, const unsigned filter)
  1237. {
  1238. /* prevent potential over/underflow, bails out at a width of ~8M pixels for RGBA8 */
  1239. if(size > (INT32_MAX / 128)) return INT32_MAX;
  1240. uint32_t i;
  1241. int32_t sum = 0;
  1242. uint8_t x, a, b, c;
  1243. for(i=0; i < size; i++)
  1244. {
  1245. if(i >= bytes_per_pixel)
  1246. {
  1247. a = scanline[i - bytes_per_pixel];
  1248. b = prev_scanline[i];
  1249. c = prev_scanline[i - bytes_per_pixel];
  1250. }
  1251. else /* first pixel in row */
  1252. {
  1253. a = 0;
  1254. b = prev_scanline[i];
  1255. c = 0;
  1256. }
  1257. x = scanline[i];
  1258. switch(filter)
  1259. {
  1260. case SPNG_FILTER_NONE:
  1261. {
  1262. break;
  1263. }
  1264. case SPNG_FILTER_SUB:
  1265. {
  1266. x = x - a;
  1267. break;
  1268. }
  1269. case SPNG_FILTER_UP:
  1270. {
  1271. x = x - b;
  1272. break;
  1273. }
  1274. case SPNG_FILTER_AVERAGE:
  1275. {
  1276. uint16_t avg = (a + b) / 2;
  1277. x = x - avg;
  1278. break;
  1279. }
  1280. case SPNG_FILTER_PAETH:
  1281. {
  1282. x = x - paeth(a,b,c);
  1283. break;
  1284. }
  1285. }
  1286. sum += 128 - abs((int)x - 128);
  1287. }
  1288. return sum;
  1289. }
  1290. static unsigned get_best_filter(const unsigned char *prev_scanline, const unsigned char *scanline,
  1291. size_t scanline_width, unsigned bytes_per_pixel, const int choices)
  1292. {
  1293. if(!choices) return SPNG_FILTER_NONE;
  1294. scanline_width--;
  1295. int i;
  1296. unsigned int best_filter = 0;
  1297. enum spng_filter_choice flag;
  1298. int32_t sum, best_score = INT32_MAX;
  1299. int32_t filter_scores[5] = { INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX, INT32_MAX };
  1300. if( !(choices & (choices - 1)) )
  1301. {/* only one choice/bit is set */
  1302. for(i=0; i < 5; i++)
  1303. {
  1304. if(choices == 1 << (i + 3)) return i;
  1305. }
  1306. }
  1307. for(i=0; i < 5; i++)
  1308. {
  1309. flag = 1 << (i + 3);
  1310. if(choices & flag) sum = filter_sum(prev_scanline, scanline, scanline_width, bytes_per_pixel, i);
  1311. else continue;
  1312. filter_scores[i] = abs(sum);
  1313. if(filter_scores[i] < best_score)
  1314. {
  1315. best_score = filter_scores[i];
  1316. best_filter = i;
  1317. }
  1318. }
  1319. return best_filter;
  1320. }
  1321. /* Scale "sbits" significant bits in "sample" from "bit_depth" to "target"
  1322. "bit_depth" must be a valid PNG depth
  1323. "sbits" must be less than or equal to "bit_depth"
  1324. "target" must be between 1 and 16
  1325. */
  1326. static uint16_t sample_to_target(uint16_t sample, unsigned bit_depth, unsigned sbits, unsigned target)
  1327. {
  1328. if(bit_depth == sbits)
  1329. {
  1330. if(target == sbits) return sample; /* No scaling */
  1331. }/* bit_depth > sbits */
  1332. else sample = sample >> (bit_depth - sbits); /* Shift significant bits to bottom */
  1333. /* Downscale */
  1334. if(target < sbits) return sample >> (sbits - target);
  1335. /* Upscale using left bit replication */
  1336. int8_t shift_amount = target - sbits;
  1337. uint16_t sample_bits = sample;
  1338. sample = 0;
  1339. while(shift_amount >= 0)
  1340. {
  1341. sample = sample | (sample_bits << shift_amount);
  1342. shift_amount -= sbits;
  1343. }
  1344. int8_t partial = shift_amount + (int8_t)sbits;
  1345. if(partial != 0) sample = sample | (sample_bits >> abs(shift_amount));
  1346. return sample;
  1347. }
  1348. static inline void gamma_correct_row(unsigned char *row, uint32_t pixels, int fmt, const uint16_t *gamma_lut)
  1349. {
  1350. uint32_t i;
  1351. if(fmt == SPNG_FMT_RGBA8)
  1352. {
  1353. unsigned char *px;
  1354. for(i=0; i < pixels; i++)
  1355. {
  1356. px = row + i * 4;
  1357. px[0] = gamma_lut[px[0]];
  1358. px[1] = gamma_lut[px[1]];
  1359. px[2] = gamma_lut[px[2]];
  1360. }
  1361. }
  1362. else if(fmt == SPNG_FMT_RGBA16)
  1363. {
  1364. for(i=0; i < pixels; i++)
  1365. {
  1366. uint16_t px[4];
  1367. memcpy(px, row + i * 8, 8);
  1368. px[0] = gamma_lut[px[0]];
  1369. px[1] = gamma_lut[px[1]];
  1370. px[2] = gamma_lut[px[2]];
  1371. memcpy(row + i * 8, px, 8);
  1372. }
  1373. }
  1374. else if(fmt == SPNG_FMT_RGB8)
  1375. {
  1376. unsigned char *px;
  1377. for(i=0; i < pixels; i++)
  1378. {
  1379. px = row + i * 3;
  1380. px[0] = gamma_lut[px[0]];
  1381. px[1] = gamma_lut[px[1]];
  1382. px[2] = gamma_lut[px[2]];
  1383. }
  1384. }
  1385. }
  1386. /* Apply transparency to output row */
  1387. static inline void trns_row(unsigned char *row,
  1388. const unsigned char *scanline,
  1389. const unsigned char *trns,
  1390. unsigned scanline_stride,
  1391. struct spng_ihdr *ihdr,
  1392. uint32_t pixels,
  1393. int fmt)
  1394. {
  1395. uint32_t i;
  1396. unsigned row_stride;
  1397. unsigned depth = ihdr->bit_depth;
  1398. if(fmt == SPNG_FMT_RGBA8)
  1399. {
  1400. if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE) return; /* already applied in the decoding loop */
  1401. row_stride = 4;
  1402. for(i=0; i < pixels; i++, scanline+=scanline_stride, row+=row_stride)
  1403. {
  1404. if(!memcmp(scanline, trns, scanline_stride)) row[3] = 0;
  1405. }
  1406. }
  1407. else if(fmt == SPNG_FMT_RGBA16)
  1408. {
  1409. if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE) return; /* already applied in the decoding loop */
  1410. row_stride = 8;
  1411. for(i=0; i < pixels; i++, scanline+=scanline_stride, row+=row_stride)
  1412. {
  1413. if(!memcmp(scanline, trns, scanline_stride)) memset(row + 6, 0, 2);
  1414. }
  1415. }
  1416. else if(fmt == SPNG_FMT_GA8)
  1417. {
  1418. row_stride = 2;
  1419. if(depth == 16)
  1420. {
  1421. for(i=0; i < pixels; i++, scanline+=scanline_stride, row+=row_stride)
  1422. {
  1423. if(!memcmp(scanline, trns, scanline_stride)) memset(row + 1, 0, 1);
  1424. }
  1425. }
  1426. else /* depth <= 8 */
  1427. {
  1428. struct spng__iter iter = spng__iter_init(depth, scanline);
  1429. for(i=0; i < pixels; i++, row+=row_stride)
  1430. {
  1431. if(trns[0] == get_sample(&iter)) row[1] = 0;
  1432. }
  1433. }
  1434. }
  1435. else if(fmt == SPNG_FMT_GA16)
  1436. {
  1437. row_stride = 4;
  1438. if(depth == 16)
  1439. {
  1440. for(i=0; i< pixels; i++, scanline+=scanline_stride, row+=row_stride)
  1441. {
  1442. if(!memcmp(scanline, trns, 2)) memset(row + 2, 0, 2);
  1443. }
  1444. }
  1445. else
  1446. {
  1447. struct spng__iter iter = spng__iter_init(depth, scanline);
  1448. for(i=0; i< pixels; i++, row+=row_stride)
  1449. {
  1450. if(trns[0] == get_sample(&iter)) memset(row + 2, 0, 2);
  1451. }
  1452. }
  1453. }
  1454. else return;
  1455. }
  1456. static inline void scale_row(unsigned char *row, uint32_t pixels, int fmt, unsigned depth, const struct spng_sbit *sbit)
  1457. {
  1458. uint32_t i;
  1459. if(fmt == SPNG_FMT_RGBA8)
  1460. {
  1461. unsigned char px[4];
  1462. for(i=0; i < pixels; i++)
  1463. {
  1464. memcpy(px, row + i * 4, 4);
  1465. px[0] = sample_to_target(px[0], depth, sbit->red_bits, 8);
  1466. px[1] = sample_to_target(px[1], depth, sbit->green_bits, 8);
  1467. px[2] = sample_to_target(px[2], depth, sbit->blue_bits, 8);
  1468. px[3] = sample_to_target(px[3], depth, sbit->alpha_bits, 8);
  1469. memcpy(row + i * 4, px, 4);
  1470. }
  1471. }
  1472. else if(fmt == SPNG_FMT_RGBA16)
  1473. {
  1474. uint16_t px[4];
  1475. for(i=0; i < pixels; i++)
  1476. {
  1477. memcpy(px, row + i * 8, 8);
  1478. px[0] = sample_to_target(px[0], depth, sbit->red_bits, 16);
  1479. px[1] = sample_to_target(px[1], depth, sbit->green_bits, 16);
  1480. px[2] = sample_to_target(px[2], depth, sbit->blue_bits, 16);
  1481. px[3] = sample_to_target(px[3], depth, sbit->alpha_bits, 16);
  1482. memcpy(row + i * 8, px, 8);
  1483. }
  1484. }
  1485. else if(fmt == SPNG_FMT_RGB8)
  1486. {
  1487. unsigned char px[4];
  1488. for(i=0; i < pixels; i++)
  1489. {
  1490. memcpy(px, row + i * 3, 3);
  1491. px[0] = sample_to_target(px[0], depth, sbit->red_bits, 8);
  1492. px[1] = sample_to_target(px[1], depth, sbit->green_bits, 8);
  1493. px[2] = sample_to_target(px[2], depth, sbit->blue_bits, 8);
  1494. memcpy(row + i * 3, px, 3);
  1495. }
  1496. }
  1497. else if(fmt == SPNG_FMT_G8)
  1498. {
  1499. for(i=0; i < pixels; i++)
  1500. {
  1501. row[i] = sample_to_target(row[i], depth, sbit->grayscale_bits, 8);
  1502. }
  1503. }
  1504. else if(fmt == SPNG_FMT_GA8)
  1505. {
  1506. for(i=0; i < pixels; i++)
  1507. {
  1508. row[i*2] = sample_to_target(row[i*2], depth, sbit->grayscale_bits, 8);
  1509. }
  1510. }
  1511. }
  1512. /* Expand to *row using 8-bit palette indices from *scanline */
  1513. static void expand_row(unsigned char *row,
  1514. const unsigned char *scanline,
  1515. const union spng__decode_plte *decode_plte,
  1516. uint32_t width,
  1517. int fmt)
  1518. {
  1519. uint32_t i = 0;
  1520. unsigned char *px;
  1521. unsigned char entry;
  1522. const struct spng_plte_entry *plte = decode_plte->rgba;
  1523. #if defined(SPNG_ARM)
  1524. if(fmt == SPNG_FMT_RGBA8) i = expand_palette_rgba8_neon(row, scanline, decode_plte->raw, width);
  1525. else if(fmt == SPNG_FMT_RGB8)
  1526. {
  1527. i = expand_palette_rgb8_neon(row, scanline, decode_plte->raw, width);
  1528. for(; i < width; i++)
  1529. {/* In this case the LUT is 3 bytes packed */
  1530. px = row + i * 3;
  1531. entry = scanline[i];
  1532. px[0] = decode_plte->raw[entry * 3 + 0];
  1533. px[1] = decode_plte->raw[entry * 3 + 1];
  1534. px[2] = decode_plte->raw[entry * 3 + 2];
  1535. }
  1536. return;
  1537. }
  1538. #endif
  1539. if(fmt == SPNG_FMT_RGBA8)
  1540. {
  1541. for(; i < width; i++)
  1542. {
  1543. px = row + i * 4;
  1544. entry = scanline[i];
  1545. px[0] = plte[entry].red;
  1546. px[1] = plte[entry].green;
  1547. px[2] = plte[entry].blue;
  1548. px[3] = plte[entry].alpha;
  1549. }
  1550. }
  1551. else if(fmt == SPNG_FMT_RGB8)
  1552. {
  1553. for(; i < width; i++)
  1554. {
  1555. px = row + i * 3;
  1556. entry = scanline[i];
  1557. px[0] = plte[entry].red;
  1558. px[1] = plte[entry].green;
  1559. px[2] = plte[entry].blue;
  1560. }
  1561. }
  1562. }
  1563. /* Unpack 1/2/4/8-bit samples to G8/GA8/GA16 or G16 -> GA16 */
  1564. static void unpack_scanline(unsigned char *out, const unsigned char *scanline, uint32_t width, unsigned bit_depth, int fmt)
  1565. {
  1566. struct spng__iter iter = spng__iter_init(bit_depth, scanline);
  1567. uint32_t i;
  1568. uint16_t sample, alpha = 65535;
  1569. if(fmt == SPNG_FMT_GA8) goto ga8;
  1570. else if(fmt == SPNG_FMT_GA16) goto ga16;
  1571. /* 1/2/4-bit -> 8-bit */
  1572. for(i=0; i < width; i++) out[i] = get_sample(&iter);
  1573. return;
  1574. ga8:
  1575. /* 1/2/4/8-bit -> GA8 */
  1576. for(i=0; i < width; i++)
  1577. {
  1578. out[i*2] = get_sample(&iter);
  1579. out[i*2 + 1] = 255;
  1580. }
  1581. return;
  1582. ga16:
  1583. /* 16 -> GA16 */
  1584. if(bit_depth == 16)
  1585. {
  1586. for(i=0; i < width; i++)
  1587. {
  1588. memcpy(out + i * 4, scanline + i * 2, 2);
  1589. memcpy(out + i * 4 + 2, &alpha, 2);
  1590. }
  1591. return;
  1592. }
  1593. /* 1/2/4/8-bit -> GA16 */
  1594. for(i=0; i < width; i++)
  1595. {
  1596. sample = get_sample(&iter);
  1597. memcpy(out + i * 4, &sample, 2);
  1598. memcpy(out + i * 4 + 2, &alpha, 2);
  1599. }
  1600. }
  1601. static int check_ihdr(const struct spng_ihdr *ihdr, uint32_t max_width, uint32_t max_height)
  1602. {
  1603. if(ihdr->width > spng_u32max || !ihdr->width) return SPNG_EWIDTH;
  1604. if(ihdr->height > spng_u32max || !ihdr->height) return SPNG_EHEIGHT;
  1605. if(ihdr->width > max_width) return SPNG_EUSER_WIDTH;
  1606. if(ihdr->height > max_height) return SPNG_EUSER_HEIGHT;
  1607. switch(ihdr->color_type)
  1608. {
  1609. case SPNG_COLOR_TYPE_GRAYSCALE:
  1610. {
  1611. if( !(ihdr->bit_depth == 1 || ihdr->bit_depth == 2 ||
  1612. ihdr->bit_depth == 4 || ihdr->bit_depth == 8 ||
  1613. ihdr->bit_depth == 16) )
  1614. return SPNG_EBIT_DEPTH;
  1615. break;
  1616. }
  1617. case SPNG_COLOR_TYPE_TRUECOLOR:
  1618. case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA:
  1619. case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA:
  1620. {
  1621. if( !(ihdr->bit_depth == 8 || ihdr->bit_depth == 16) )
  1622. return SPNG_EBIT_DEPTH;
  1623. break;
  1624. }
  1625. case SPNG_COLOR_TYPE_INDEXED:
  1626. {
  1627. if( !(ihdr->bit_depth == 1 || ihdr->bit_depth == 2 ||
  1628. ihdr->bit_depth == 4 || ihdr->bit_depth == 8) )
  1629. return SPNG_EBIT_DEPTH;
  1630. break;
  1631. }
  1632. default: return SPNG_ECOLOR_TYPE;
  1633. }
  1634. if(ihdr->compression_method) return SPNG_ECOMPRESSION_METHOD;
  1635. if(ihdr->filter_method) return SPNG_EFILTER_METHOD;
  1636. if(ihdr->interlace_method > 1) return SPNG_EINTERLACE_METHOD;
  1637. return 0;
  1638. }
  1639. static int check_plte(const struct spng_plte *plte, const struct spng_ihdr *ihdr)
  1640. {
  1641. if(plte == NULL || ihdr == NULL) return 1;
  1642. if(plte->n_entries == 0) return 1;
  1643. if(plte->n_entries > 256) return 1;
  1644. if(ihdr->color_type == SPNG_COLOR_TYPE_INDEXED)
  1645. {
  1646. if(plte->n_entries > (1U << ihdr->bit_depth)) return 1;
  1647. }
  1648. return 0;
  1649. }
  1650. static int check_sbit(const struct spng_sbit *sbit, const struct spng_ihdr *ihdr)
  1651. {
  1652. if(sbit == NULL || ihdr == NULL) return 1;
  1653. if(ihdr->color_type == 0)
  1654. {
  1655. if(sbit->grayscale_bits == 0) return SPNG_ESBIT;
  1656. if(sbit->grayscale_bits > ihdr->bit_depth) return SPNG_ESBIT;
  1657. }
  1658. else if(ihdr->color_type == 2 || ihdr->color_type == 3)
  1659. {
  1660. if(sbit->red_bits == 0) return SPNG_ESBIT;
  1661. if(sbit->green_bits == 0) return SPNG_ESBIT;
  1662. if(sbit->blue_bits == 0) return SPNG_ESBIT;
  1663. uint8_t bit_depth;
  1664. if(ihdr->color_type == 3) bit_depth = 8;
  1665. else bit_depth = ihdr->bit_depth;
  1666. if(sbit->red_bits > bit_depth) return SPNG_ESBIT;
  1667. if(sbit->green_bits > bit_depth) return SPNG_ESBIT;
  1668. if(sbit->blue_bits > bit_depth) return SPNG_ESBIT;
  1669. }
  1670. else if(ihdr->color_type == 4)
  1671. {
  1672. if(sbit->grayscale_bits == 0) return SPNG_ESBIT;
  1673. if(sbit->alpha_bits == 0) return SPNG_ESBIT;
  1674. if(sbit->grayscale_bits > ihdr->bit_depth) return SPNG_ESBIT;
  1675. if(sbit->alpha_bits > ihdr->bit_depth) return SPNG_ESBIT;
  1676. }
  1677. else if(ihdr->color_type == 6)
  1678. {
  1679. if(sbit->red_bits == 0) return SPNG_ESBIT;
  1680. if(sbit->green_bits == 0) return SPNG_ESBIT;
  1681. if(sbit->blue_bits == 0) return SPNG_ESBIT;
  1682. if(sbit->alpha_bits == 0) return SPNG_ESBIT;
  1683. if(sbit->red_bits > ihdr->bit_depth) return SPNG_ESBIT;
  1684. if(sbit->green_bits > ihdr->bit_depth) return SPNG_ESBIT;
  1685. if(sbit->blue_bits > ihdr->bit_depth) return SPNG_ESBIT;
  1686. if(sbit->alpha_bits > ihdr->bit_depth) return SPNG_ESBIT;
  1687. }
  1688. return 0;
  1689. }
  1690. static int check_chrm_int(const struct spng_chrm_int *chrm_int)
  1691. {
  1692. if(chrm_int == NULL) return 1;
  1693. if(chrm_int->white_point_x > spng_u32max ||
  1694. chrm_int->white_point_y > spng_u32max ||
  1695. chrm_int->red_x > spng_u32max ||
  1696. chrm_int->red_y > spng_u32max ||
  1697. chrm_int->green_x > spng_u32max ||
  1698. chrm_int->green_y > spng_u32max ||
  1699. chrm_int->blue_x > spng_u32max ||
  1700. chrm_int->blue_y > spng_u32max) return SPNG_ECHRM;
  1701. return 0;
  1702. }
  1703. static int check_phys(const struct spng_phys *phys)
  1704. {
  1705. if(phys == NULL) return 1;
  1706. if(phys->unit_specifier > 1) return SPNG_EPHYS;
  1707. if(phys->ppu_x > spng_u32max) return SPNG_EPHYS;
  1708. if(phys->ppu_y > spng_u32max) return SPNG_EPHYS;
  1709. return 0;
  1710. }
  1711. static int check_time(const struct spng_time *time)
  1712. {
  1713. if(time == NULL) return 1;
  1714. if(time->month == 0 || time->month > 12) return 1;
  1715. if(time->day == 0 || time->day > 31) return 1;
  1716. if(time->hour > 23) return 1;
  1717. if(time->minute > 59) return 1;
  1718. if(time->second > 60) return 1;
  1719. return 0;
  1720. }
  1721. static int check_offs(const struct spng_offs *offs)
  1722. {
  1723. if(offs == NULL) return 1;
  1724. if(offs->unit_specifier > 1) return 1;
  1725. return 0;
  1726. }
  1727. static int check_exif(const struct spng_exif *exif)
  1728. {
  1729. if(exif == NULL) return 1;
  1730. if(exif->data == NULL) return 1;
  1731. if(exif->length < 4) return SPNG_ECHUNK_SIZE;
  1732. if(exif->length > spng_u32max) return SPNG_ECHUNK_STDLEN;
  1733. const uint8_t exif_le[4] = { 73, 73, 42, 0 };
  1734. const uint8_t exif_be[4] = { 77, 77, 0, 42 };
  1735. if(memcmp(exif->data, exif_le, 4) && memcmp(exif->data, exif_be, 4)) return 1;
  1736. return 0;
  1737. }
  1738. /* Validate PNG keyword */
  1739. static int check_png_keyword(const char *str)
  1740. {
  1741. if(str == NULL) return 1;
  1742. size_t len = strlen(str);
  1743. const char *end = str + len;
  1744. if(!len) return 1;
  1745. if(len > 79) return 1;
  1746. if(str[0] == ' ') return 1; /* Leading space */
  1747. if(end[-1] == ' ') return 1; /* Trailing space */
  1748. if(strstr(str, " ") != NULL) return 1; /* Consecutive spaces */
  1749. uint8_t c;
  1750. while(str != end)
  1751. {
  1752. memcpy(&c, str, 1);
  1753. if( (c >= 32 && c <= 126) || (c >= 161) ) str++;
  1754. else return 1; /* Invalid character */
  1755. }
  1756. return 0;
  1757. }
  1758. /* Validate PNG text *str up to 'len' bytes */
  1759. static int check_png_text(const char *str, size_t len)
  1760. {/* XXX: are consecutive newlines permitted? */
  1761. if(str == NULL || len == 0) return 1;
  1762. uint8_t c;
  1763. size_t i = 0;
  1764. while(i < len)
  1765. {
  1766. memcpy(&c, str + i, 1);
  1767. if( (c >= 32 && c <= 126) || (c >= 161) || c == 10) i++;
  1768. else return 1; /* Invalid character */
  1769. }
  1770. return 0;
  1771. }
  1772. /* Returns non-zero for standard chunks which are stored without allocating memory */
  1773. static int is_small_chunk(uint8_t type[4])
  1774. {
  1775. if(!memcmp(type, type_plte, 4)) return 1;
  1776. else if(!memcmp(type, type_chrm, 4)) return 1;
  1777. else if(!memcmp(type, type_gama, 4)) return 1;
  1778. else if(!memcmp(type, type_sbit, 4)) return 1;
  1779. else if(!memcmp(type, type_srgb, 4)) return 1;
  1780. else if(!memcmp(type, type_bkgd, 4)) return 1;
  1781. else if(!memcmp(type, type_trns, 4)) return 1;
  1782. else if(!memcmp(type, type_hist, 4)) return 1;
  1783. else if(!memcmp(type, type_phys, 4)) return 1;
  1784. else if(!memcmp(type, type_time, 4)) return 1;
  1785. else if(!memcmp(type, type_offs, 4)) return 1;
  1786. else return 0;
  1787. }
  1788. static int read_ihdr(spng_ctx *ctx)
  1789. {
  1790. int ret;
  1791. struct spng_chunk *chunk = &ctx->current_chunk;
  1792. const unsigned char *data;
  1793. chunk->offset = 8;
  1794. chunk->length = 13;
  1795. size_t sizeof_sig_ihdr = 29;
  1796. ret = read_data(ctx, sizeof_sig_ihdr);
  1797. if(ret) return ret;
  1798. data = ctx->data;
  1799. if(memcmp(data, spng_signature, sizeof(spng_signature))) return SPNG_ESIGNATURE;
  1800. chunk->length = read_u32(data + 8);
  1801. memcpy(&chunk->type, data + 12, 4);
  1802. if(chunk->length != 13) return SPNG_EIHDR_SIZE;
  1803. if(memcmp(chunk->type, type_ihdr, 4)) return SPNG_ENOIHDR;
  1804. ctx->cur_actual_crc = crc32(0, NULL, 0);
  1805. ctx->cur_actual_crc = crc32(ctx->cur_actual_crc, data + 12, 17);
  1806. ctx->ihdr.width = read_u32(data + 16);
  1807. ctx->ihdr.height = read_u32(data + 20);
  1808. ctx->ihdr.bit_depth = data[24];
  1809. ctx->ihdr.color_type = data[25];
  1810. ctx->ihdr.compression_method = data[26];
  1811. ctx->ihdr.filter_method = data[27];
  1812. ctx->ihdr.interlace_method = data[28];
  1813. ret = check_ihdr(&ctx->ihdr, ctx->max_width, ctx->max_height);
  1814. if(ret) return ret;
  1815. ctx->file.ihdr = 1;
  1816. ctx->stored.ihdr = 1;
  1817. if(ctx->ihdr.bit_depth < 8) ctx->bytes_per_pixel = 1;
  1818. else ctx->bytes_per_pixel = num_channels(&ctx->ihdr) * (ctx->ihdr.bit_depth / 8);
  1819. ret = calculate_subimages(ctx);
  1820. if(ret) return ret;
  1821. return 0;
  1822. }
  1823. static void splt_undo(spng_ctx *ctx)
  1824. {
  1825. struct spng_splt *splt = &ctx->splt_list[ctx->n_splt - 1];
  1826. spng__free(ctx, splt->entries);
  1827. decrease_cache_usage(ctx, sizeof(struct spng_splt));
  1828. decrease_cache_usage(ctx, splt->n_entries * sizeof(struct spng_splt_entry));
  1829. splt->entries = NULL;
  1830. ctx->n_splt--;
  1831. }
  1832. static void text_undo(spng_ctx *ctx)
  1833. {
  1834. struct spng_text2 *text = &ctx->text_list[ctx->n_text - 1];
  1835. spng__free(ctx, text->keyword);
  1836. if(text->compression_flag) spng__free(ctx, text->text);
  1837. decrease_cache_usage(ctx, text->cache_usage);
  1838. decrease_cache_usage(ctx, sizeof(struct spng_text2));
  1839. text->keyword = NULL;
  1840. text->text = NULL;
  1841. ctx->n_text--;
  1842. }
  1843. static void chunk_undo(spng_ctx *ctx)
  1844. {
  1845. struct spng_unknown_chunk *chunk = &ctx->chunk_list[ctx->n_chunks - 1];
  1846. spng__free(ctx, chunk->data);
  1847. decrease_cache_usage(ctx, chunk->length);
  1848. decrease_cache_usage(ctx, sizeof(struct spng_unknown_chunk));
  1849. chunk->data = NULL;
  1850. ctx->n_chunks--;
  1851. }
  1852. static int read_non_idat_chunks(spng_ctx *ctx)
  1853. {
  1854. int ret;
  1855. struct spng_chunk chunk;
  1856. const unsigned char *data;
  1857. ctx->discard = 0;
  1858. ctx->undo = NULL;
  1859. ctx->prev_stored = ctx->stored;
  1860. while( !(ret = read_header(ctx)))
  1861. {
  1862. if(ctx->discard)
  1863. {
  1864. if(ctx->undo) ctx->undo(ctx);
  1865. ctx->stored = ctx->prev_stored;
  1866. }
  1867. ctx->discard = 0;
  1868. ctx->undo = NULL;
  1869. ctx->prev_stored = ctx->stored;
  1870. chunk = ctx->current_chunk;
  1871. if(!memcmp(chunk.type, type_idat, 4))
  1872. {
  1873. if(ctx->state < SPNG_STATE_FIRST_IDAT)
  1874. {
  1875. if(ctx->ihdr.color_type == 3 && !ctx->stored.plte) return SPNG_ENOPLTE;
  1876. ctx->first_idat = chunk;
  1877. return 0;
  1878. }
  1879. if(ctx->prev_was_idat)
  1880. {
  1881. /* Ignore extra IDAT's */
  1882. ret = discard_chunk_bytes(ctx, chunk.length);
  1883. if(ret) return ret;
  1884. continue;
  1885. }
  1886. else return SPNG_ECHUNK_POS; /* IDAT chunk not at the end of the IDAT sequence */
  1887. }
  1888. ctx->prev_was_idat = 0;
  1889. if(is_small_chunk(chunk.type))
  1890. {
  1891. /* None of the known chunks can be zero length */
  1892. if(!chunk.length) return SPNG_ECHUNK_SIZE;
  1893. /* The largest of these chunks is PLTE with 256 entries */
  1894. ret = read_chunk_bytes(ctx, chunk.length > 768 ? 768 : chunk.length);
  1895. if(ret) return ret;
  1896. }
  1897. data = ctx->data;
  1898. if(is_critical_chunk(&chunk))
  1899. {
  1900. if(!memcmp(chunk.type, type_plte, 4))
  1901. {
  1902. if(ctx->file.trns || ctx->file.hist || ctx->file.bkgd) return SPNG_ECHUNK_POS;
  1903. if(chunk.length % 3 != 0) return SPNG_ECHUNK_SIZE;
  1904. ctx->plte.n_entries = chunk.length / 3;
  1905. if(check_plte(&ctx->plte, &ctx->ihdr)) return SPNG_ECHUNK_SIZE; /* XXX: EPLTE? */
  1906. size_t i;
  1907. for(i=0; i < ctx->plte.n_entries; i++)
  1908. {
  1909. ctx->plte.entries[i].red = data[i * 3];
  1910. ctx->plte.entries[i].green = data[i * 3 + 1];
  1911. ctx->plte.entries[i].blue = data[i * 3 + 2];
  1912. }
  1913. ctx->file.plte = 1;
  1914. ctx->stored.plte = 1;
  1915. }
  1916. else if(!memcmp(chunk.type, type_iend, 4))
  1917. {
  1918. if(ctx->state == SPNG_STATE_AFTER_IDAT)
  1919. {
  1920. if(chunk.length) return SPNG_ECHUNK_SIZE;
  1921. ret = read_and_check_crc(ctx);
  1922. if(ret == -SPNG_CRC_DISCARD) ret = 0;
  1923. return ret;
  1924. }
  1925. else return SPNG_ECHUNK_POS;
  1926. }
  1927. else if(!memcmp(chunk.type, type_ihdr, 4)) return SPNG_ECHUNK_POS;
  1928. else return SPNG_ECHUNK_UNKNOWN_CRITICAL;
  1929. }
  1930. else if(!memcmp(chunk.type, type_chrm, 4)) /* Ancillary chunks */
  1931. {
  1932. if(ctx->file.plte) return SPNG_ECHUNK_POS;
  1933. if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
  1934. if(ctx->file.chrm) return SPNG_EDUP_CHRM;
  1935. if(chunk.length != 32) return SPNG_ECHUNK_SIZE;
  1936. ctx->chrm_int.white_point_x = read_u32(data);
  1937. ctx->chrm_int.white_point_y = read_u32(data + 4);
  1938. ctx->chrm_int.red_x = read_u32(data + 8);
  1939. ctx->chrm_int.red_y = read_u32(data + 12);
  1940. ctx->chrm_int.green_x = read_u32(data + 16);
  1941. ctx->chrm_int.green_y = read_u32(data + 20);
  1942. ctx->chrm_int.blue_x = read_u32(data + 24);
  1943. ctx->chrm_int.blue_y = read_u32(data + 28);
  1944. if(check_chrm_int(&ctx->chrm_int)) return SPNG_ECHRM;
  1945. ctx->file.chrm = 1;
  1946. ctx->stored.chrm = 1;
  1947. }
  1948. else if(!memcmp(chunk.type, type_gama, 4))
  1949. {
  1950. if(ctx->file.plte) return SPNG_ECHUNK_POS;
  1951. if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
  1952. if(ctx->file.gama) return SPNG_EDUP_GAMA;
  1953. if(chunk.length != 4) return SPNG_ECHUNK_SIZE;
  1954. ctx->gama = read_u32(data);
  1955. if(!ctx->gama) return SPNG_EGAMA;
  1956. if(ctx->gama > spng_u32max) return SPNG_EGAMA;
  1957. ctx->file.gama = 1;
  1958. ctx->stored.gama = 1;
  1959. }
  1960. else if(!memcmp(chunk.type, type_sbit, 4))
  1961. {
  1962. if(ctx->file.plte) return SPNG_ECHUNK_POS;
  1963. if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
  1964. if(ctx->file.sbit) return SPNG_EDUP_SBIT;
  1965. if(ctx->ihdr.color_type == 0)
  1966. {
  1967. if(chunk.length != 1) return SPNG_ECHUNK_SIZE;
  1968. ctx->sbit.grayscale_bits = data[0];
  1969. }
  1970. else if(ctx->ihdr.color_type == 2 || ctx->ihdr.color_type == 3)
  1971. {
  1972. if(chunk.length != 3) return SPNG_ECHUNK_SIZE;
  1973. ctx->sbit.red_bits = data[0];
  1974. ctx->sbit.green_bits = data[1];
  1975. ctx->sbit.blue_bits = data[2];
  1976. }
  1977. else if(ctx->ihdr.color_type == 4)
  1978. {
  1979. if(chunk.length != 2) return SPNG_ECHUNK_SIZE;
  1980. ctx->sbit.grayscale_bits = data[0];
  1981. ctx->sbit.alpha_bits = data[1];
  1982. }
  1983. else if(ctx->ihdr.color_type == 6)
  1984. {
  1985. if(chunk.length != 4) return SPNG_ECHUNK_SIZE;
  1986. ctx->sbit.red_bits = data[0];
  1987. ctx->sbit.green_bits = data[1];
  1988. ctx->sbit.blue_bits = data[2];
  1989. ctx->sbit.alpha_bits = data[3];
  1990. }
  1991. if(check_sbit(&ctx->sbit, &ctx->ihdr)) return SPNG_ESBIT;
  1992. ctx->file.sbit = 1;
  1993. ctx->stored.sbit = 1;
  1994. }
  1995. else if(!memcmp(chunk.type, type_srgb, 4))
  1996. {
  1997. if(ctx->file.plte) return SPNG_ECHUNK_POS;
  1998. if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
  1999. if(ctx->file.srgb) return SPNG_EDUP_SRGB;
  2000. if(chunk.length != 1) return SPNG_ECHUNK_SIZE;
  2001. ctx->srgb_rendering_intent = data[0];
  2002. if(ctx->srgb_rendering_intent > 3) return SPNG_ESRGB;
  2003. ctx->file.srgb = 1;
  2004. ctx->stored.srgb = 1;
  2005. }
  2006. else if(!memcmp(chunk.type, type_bkgd, 4))
  2007. {
  2008. if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
  2009. if(ctx->file.bkgd) return SPNG_EDUP_BKGD;
  2010. if(ctx->ihdr.color_type == 0 || ctx->ihdr.color_type == 4)
  2011. {
  2012. if(chunk.length != 2) return SPNG_ECHUNK_SIZE;
  2013. ctx->bkgd.gray = read_u16(data);
  2014. }
  2015. else if(ctx->ihdr.color_type == 2 || ctx->ihdr.color_type == 6)
  2016. {
  2017. if(chunk.length != 6) return SPNG_ECHUNK_SIZE;
  2018. ctx->bkgd.red = read_u16(data);
  2019. ctx->bkgd.green = read_u16(data + 2);
  2020. ctx->bkgd.blue = read_u16(data + 4);
  2021. }
  2022. else if(ctx->ihdr.color_type == 3)
  2023. {
  2024. if(chunk.length != 1) return SPNG_ECHUNK_SIZE;
  2025. if(!ctx->file.plte) return SPNG_EBKGD_NO_PLTE;
  2026. ctx->bkgd.plte_index = data[0];
  2027. if(ctx->bkgd.plte_index >= ctx->plte.n_entries) return SPNG_EBKGD_PLTE_IDX;
  2028. }
  2029. ctx->file.bkgd = 1;
  2030. ctx->stored.bkgd = 1;
  2031. }
  2032. else if(!memcmp(chunk.type, type_trns, 4))
  2033. {
  2034. if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
  2035. if(ctx->file.trns) return SPNG_EDUP_TRNS;
  2036. if(!chunk.length) return SPNG_ECHUNK_SIZE;
  2037. if(ctx->ihdr.color_type == 0)
  2038. {
  2039. if(chunk.length != 2) return SPNG_ECHUNK_SIZE;
  2040. ctx->trns.gray = read_u16(data);
  2041. }
  2042. else if(ctx->ihdr.color_type == 2)
  2043. {
  2044. if(chunk.length != 6) return SPNG_ECHUNK_SIZE;
  2045. ctx->trns.red = read_u16(data);
  2046. ctx->trns.green = read_u16(data + 2);
  2047. ctx->trns.blue = read_u16(data + 4);
  2048. }
  2049. else if(ctx->ihdr.color_type == 3)
  2050. {
  2051. if(chunk.length > ctx->plte.n_entries) return SPNG_ECHUNK_SIZE;
  2052. if(!ctx->file.plte) return SPNG_ETRNS_NO_PLTE;
  2053. memcpy(ctx->trns.type3_alpha, data, chunk.length);
  2054. ctx->trns.n_type3_entries = chunk.length;
  2055. }
  2056. if(ctx->ihdr.color_type == 4 || ctx->ihdr.color_type == 6) return SPNG_ETRNS_COLOR_TYPE;
  2057. ctx->file.trns = 1;
  2058. ctx->stored.trns = 1;
  2059. }
  2060. else if(!memcmp(chunk.type, type_hist, 4))
  2061. {
  2062. if(!ctx->file.plte) return SPNG_EHIST_NO_PLTE;
  2063. if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
  2064. if(ctx->file.hist) return SPNG_EDUP_HIST;
  2065. if( (chunk.length / 2) != (ctx->plte.n_entries) ) return SPNG_ECHUNK_SIZE;
  2066. size_t k;
  2067. for(k=0; k < (chunk.length / 2); k++)
  2068. {
  2069. ctx->hist.frequency[k] = read_u16(data + k*2);
  2070. }
  2071. ctx->file.hist = 1;
  2072. ctx->stored.hist = 1;
  2073. }
  2074. else if(!memcmp(chunk.type, type_phys, 4))
  2075. {
  2076. if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
  2077. if(ctx->file.phys) return SPNG_EDUP_PHYS;
  2078. if(chunk.length != 9) return SPNG_ECHUNK_SIZE;
  2079. ctx->phys.ppu_x = read_u32(data);
  2080. ctx->phys.ppu_y = read_u32(data + 4);
  2081. ctx->phys.unit_specifier = data[8];
  2082. if(check_phys(&ctx->phys)) return SPNG_EPHYS;
  2083. ctx->file.phys = 1;
  2084. ctx->stored.phys = 1;
  2085. }
  2086. else if(!memcmp(chunk.type, type_time, 4))
  2087. {
  2088. if(ctx->file.time) return SPNG_EDUP_TIME;
  2089. if(chunk.length != 7) return SPNG_ECHUNK_SIZE;
  2090. struct spng_time time;
  2091. time.year = read_u16(data);
  2092. time.month = data[2];
  2093. time.day = data[3];
  2094. time.hour = data[4];
  2095. time.minute = data[5];
  2096. time.second = data[6];
  2097. if(check_time(&time)) return SPNG_ETIME;
  2098. ctx->file.time = 1;
  2099. if(!ctx->user.time) ctx->time = time;
  2100. ctx->stored.time = 1;
  2101. }
  2102. else if(!memcmp(chunk.type, type_offs, 4))
  2103. {
  2104. if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
  2105. if(ctx->file.offs) return SPNG_EDUP_OFFS;
  2106. if(chunk.length != 9) return SPNG_ECHUNK_SIZE;
  2107. ctx->offs.x = read_s32(data);
  2108. ctx->offs.y = read_s32(data + 4);
  2109. ctx->offs.unit_specifier = data[8];
  2110. if(check_offs(&ctx->offs)) return SPNG_EOFFS;
  2111. ctx->file.offs = 1;
  2112. ctx->stored.offs = 1;
  2113. }
  2114. else /* Arbitrary-length chunk */
  2115. {
  2116. if(!memcmp(chunk.type, type_exif, 4))
  2117. {
  2118. if(ctx->file.exif) return SPNG_EDUP_EXIF;
  2119. if(!chunk.length) return SPNG_EEXIF;
  2120. ctx->file.exif = 1;
  2121. if(ctx->user.exif) goto discard;
  2122. if(increase_cache_usage(ctx, chunk.length, 1)) return SPNG_ECHUNK_LIMITS;
  2123. struct spng_exif exif;
  2124. exif.length = chunk.length;
  2125. exif.data = spng__malloc(ctx, chunk.length);
  2126. if(exif.data == NULL) return SPNG_EMEM;
  2127. ret = read_chunk_bytes2(ctx, exif.data, chunk.length);
  2128. if(ret)
  2129. {
  2130. spng__free(ctx, exif.data);
  2131. return ret;
  2132. }
  2133. if(check_exif(&exif))
  2134. {
  2135. spng__free(ctx, exif.data);
  2136. return SPNG_EEXIF;
  2137. }
  2138. ctx->exif = exif;
  2139. ctx->stored.exif = 1;
  2140. }
  2141. else if(!memcmp(chunk.type, type_iccp, 4))
  2142. {/* TODO: add test file with color profile */
  2143. if(ctx->file.plte) return SPNG_ECHUNK_POS;
  2144. if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
  2145. if(ctx->file.iccp) return SPNG_EDUP_ICCP;
  2146. if(!chunk.length) return SPNG_ECHUNK_SIZE;
  2147. ctx->file.iccp = 1;
  2148. uint32_t peek_bytes = 81 > chunk.length ? chunk.length : 81;
  2149. ret = read_chunk_bytes(ctx, peek_bytes);
  2150. if(ret) return ret;
  2151. unsigned char *keyword_nul = memchr(ctx->data, '\0', peek_bytes);
  2152. if(keyword_nul == NULL) return SPNG_EICCP_NAME;
  2153. uint32_t keyword_len = keyword_nul - ctx->data;
  2154. if(keyword_len > 79) return SPNG_EICCP_NAME;
  2155. memcpy(ctx->iccp.profile_name, ctx->data, keyword_len);
  2156. if(check_png_keyword(ctx->iccp.profile_name)) return SPNG_EICCP_NAME;
  2157. if(chunk.length < (keyword_len + 2)) return SPNG_ECHUNK_SIZE;
  2158. if(ctx->data[keyword_len + 1] != 0) return SPNG_EICCP_COMPRESSION_METHOD;
  2159. ret = spng__inflate_stream(ctx, &ctx->iccp.profile, &ctx->iccp.profile_len, 0, ctx->data + keyword_len + 2, peek_bytes - (keyword_len + 2));
  2160. if(ret) return ret;
  2161. ctx->stored.iccp = 1;
  2162. }
  2163. else if(!memcmp(chunk.type, type_text, 4) ||
  2164. !memcmp(chunk.type, type_ztxt, 4) ||
  2165. !memcmp(chunk.type, type_itxt, 4))
  2166. {
  2167. if(!chunk.length) return SPNG_ECHUNK_SIZE;
  2168. ctx->file.text = 1;
  2169. if(ctx->user.text) goto discard;
  2170. if(increase_cache_usage(ctx, sizeof(struct spng_text2), 1)) return SPNG_ECHUNK_LIMITS;
  2171. ctx->n_text++;
  2172. if(ctx->n_text < 1) return SPNG_EOVERFLOW;
  2173. if(sizeof(struct spng_text2) > SIZE_MAX / ctx->n_text) return SPNG_EOVERFLOW;
  2174. void *buf = spng__realloc(ctx, ctx->text_list, ctx->n_text * sizeof(struct spng_text2));
  2175. if(buf == NULL) return SPNG_EMEM;
  2176. ctx->text_list = buf;
  2177. struct spng_text2 *text = &ctx->text_list[ctx->n_text - 1];
  2178. memset(text, 0, sizeof(struct spng_text2));
  2179. ctx->undo = text_undo;
  2180. uint32_t text_offset = 0, language_tag_offset = 0, translated_keyword_offset = 0;
  2181. uint32_t peek_bytes = 256; /* enough for 3 80-byte keywords and some text bytes */
  2182. uint32_t keyword_len;
  2183. if(peek_bytes > chunk.length) peek_bytes = chunk.length;
  2184. ret = read_chunk_bytes(ctx, peek_bytes);
  2185. if(ret) return ret;
  2186. data = ctx->data;
  2187. const unsigned char *zlib_stream = NULL;
  2188. const unsigned char *peek_end = data + peek_bytes;
  2189. const unsigned char *keyword_nul = memchr(data, 0, chunk.length > 80 ? 80 : chunk.length);
  2190. if(keyword_nul == NULL) return SPNG_ETEXT_KEYWORD;
  2191. keyword_len = keyword_nul - data;
  2192. if(!memcmp(chunk.type, type_text, 4))
  2193. {
  2194. text->type = SPNG_TEXT;
  2195. text->text_length = chunk.length - keyword_len - 1;
  2196. text_offset = keyword_len;
  2197. /* increment past nul if there is a text field */
  2198. if(text->text_length) text_offset++;
  2199. }
  2200. else if(!memcmp(chunk.type, type_ztxt, 4))
  2201. {
  2202. text->type = SPNG_ZTXT;
  2203. if((peek_bytes - keyword_len) <= 2) return SPNG_EZTXT;
  2204. if(keyword_nul[1]) return SPNG_EZTXT_COMPRESSION_METHOD;
  2205. text->compression_flag = 1;
  2206. text_offset = keyword_len + 2;
  2207. }
  2208. else if(!memcmp(chunk.type, type_itxt, 4))
  2209. {
  2210. text->type = SPNG_ITXT;
  2211. /* at least two 1-byte fields, two >=0 length strings, and one byte of (compressed) text */
  2212. if((peek_bytes - keyword_len) < 5) return SPNG_EITXT;
  2213. text->compression_flag = keyword_nul[1];
  2214. if(text->compression_flag > 1) return SPNG_EITXT_COMPRESSION_FLAG;
  2215. if(keyword_nul[2]) return SPNG_EITXT_COMPRESSION_METHOD;
  2216. language_tag_offset = keyword_len + 3;
  2217. const unsigned char *term;
  2218. term = memchr(data + language_tag_offset, 0, peek_bytes - language_tag_offset);
  2219. if(term == NULL) return SPNG_EITXT_LANG_TAG;
  2220. if((peek_end - term) < 2) return SPNG_EITXT;
  2221. translated_keyword_offset = term - data + 1;
  2222. zlib_stream = memchr(data + translated_keyword_offset, 0, peek_bytes - translated_keyword_offset);
  2223. if(zlib_stream == NULL) return SPNG_EITXT;
  2224. if(zlib_stream == peek_end) return SPNG_EITXT;
  2225. text_offset = zlib_stream - data + 1;
  2226. text->text_length = chunk.length - text_offset;
  2227. }
  2228. else return SPNG_EINTERNAL;
  2229. if(text->compression_flag)
  2230. {
  2231. /* cache usage = peek_bytes + decompressed text size + nul */
  2232. if(increase_cache_usage(ctx, peek_bytes, 0)) return SPNG_ECHUNK_LIMITS;
  2233. text->keyword = spng__calloc(ctx, 1, peek_bytes);
  2234. if(text->keyword == NULL) return SPNG_EMEM;
  2235. memcpy(text->keyword, data, peek_bytes);
  2236. zlib_stream = ctx->data + text_offset;
  2237. ret = spng__inflate_stream(ctx, &text->text, &text->text_length, 1, zlib_stream, peek_bytes - text_offset);
  2238. if(ret) return ret;
  2239. text->text[text->text_length - 1] = '\0';
  2240. text->cache_usage = text->text_length + peek_bytes;
  2241. }
  2242. else
  2243. {
  2244. if(increase_cache_usage(ctx, chunk.length + 1, 0)) return SPNG_ECHUNK_LIMITS;
  2245. text->keyword = spng__malloc(ctx, chunk.length + 1);
  2246. if(text->keyword == NULL) return SPNG_EMEM;
  2247. memcpy(text->keyword, data, peek_bytes);
  2248. if(chunk.length > peek_bytes)
  2249. {
  2250. ret = read_chunk_bytes2(ctx, text->keyword + peek_bytes, chunk.length - peek_bytes);
  2251. if(ret) return ret;
  2252. }
  2253. text->text = text->keyword + text_offset;
  2254. text->text_length = chunk.length - text_offset;
  2255. text->text[text->text_length] = '\0';
  2256. text->cache_usage = chunk.length + 1;
  2257. }
  2258. if(check_png_keyword(text->keyword)) return SPNG_ETEXT_KEYWORD;
  2259. text->text_length = strlen(text->text);
  2260. if(text->type != SPNG_ITXT)
  2261. {
  2262. language_tag_offset = keyword_len;
  2263. translated_keyword_offset = keyword_len;
  2264. if(ctx->strict && check_png_text(text->text, text->text_length))
  2265. {
  2266. if(text->type == SPNG_ZTXT) return SPNG_EZTXT;
  2267. else return SPNG_ETEXT;
  2268. }
  2269. }
  2270. text->language_tag = text->keyword + language_tag_offset;
  2271. text->translated_keyword = text->keyword + translated_keyword_offset;
  2272. ctx->stored.text = 1;
  2273. }
  2274. else if(!memcmp(chunk.type, type_splt, 4))
  2275. {
  2276. if(ctx->state == SPNG_STATE_AFTER_IDAT) return SPNG_ECHUNK_POS;
  2277. if(ctx->user.splt) goto discard; /* XXX: could check profile names for uniqueness */
  2278. if(!chunk.length) return SPNG_ECHUNK_SIZE;
  2279. ctx->file.splt = 1;
  2280. /* chunk.length + sizeof(struct spng_splt) + splt->n_entries * sizeof(struct spng_splt_entry) */
  2281. if(increase_cache_usage(ctx, chunk.length + sizeof(struct spng_splt), 1)) return SPNG_ECHUNK_LIMITS;
  2282. ctx->n_splt++;
  2283. if(ctx->n_splt < 1) return SPNG_EOVERFLOW;
  2284. if(sizeof(struct spng_splt) > SIZE_MAX / ctx->n_splt) return SPNG_EOVERFLOW;
  2285. void *buf = spng__realloc(ctx, ctx->splt_list, ctx->n_splt * sizeof(struct spng_splt));
  2286. if(buf == NULL) return SPNG_EMEM;
  2287. ctx->splt_list = buf;
  2288. struct spng_splt *splt = &ctx->splt_list[ctx->n_splt - 1];
  2289. memset(splt, 0, sizeof(struct spng_splt));
  2290. ctx->undo = splt_undo;
  2291. void *t = spng__malloc(ctx, chunk.length);
  2292. if(t == NULL) return SPNG_EMEM;
  2293. splt->entries = t; /* simplifies error handling */
  2294. data = t;
  2295. ret = read_chunk_bytes2(ctx, t, chunk.length);
  2296. if(ret) return ret;
  2297. uint32_t keyword_len = chunk.length < 80 ? chunk.length : 80;
  2298. const unsigned char *keyword_nul = memchr(data, 0, keyword_len);
  2299. if(keyword_nul == NULL) return SPNG_ESPLT_NAME;
  2300. keyword_len = keyword_nul - data;
  2301. memcpy(splt->name, data, keyword_len);
  2302. if(check_png_keyword(splt->name)) return SPNG_ESPLT_NAME;
  2303. uint32_t j;
  2304. for(j=0; j < (ctx->n_splt - 1); j++)
  2305. {
  2306. if(!strcmp(ctx->splt_list[j].name, splt->name)) return SPNG_ESPLT_DUP_NAME;
  2307. }
  2308. if( (chunk.length - keyword_len) <= 2) return SPNG_ECHUNK_SIZE;
  2309. splt->sample_depth = data[keyword_len + 1];
  2310. uint32_t entries_len = chunk.length - keyword_len - 2;
  2311. if(!entries_len) return SPNG_ECHUNK_SIZE;
  2312. if(splt->sample_depth == 16)
  2313. {
  2314. if(entries_len % 10 != 0) return SPNG_ECHUNK_SIZE;
  2315. splt->n_entries = entries_len / 10;
  2316. }
  2317. else if(splt->sample_depth == 8)
  2318. {
  2319. if(entries_len % 6 != 0) return SPNG_ECHUNK_SIZE;
  2320. splt->n_entries = entries_len / 6;
  2321. }
  2322. else return SPNG_ESPLT_DEPTH;
  2323. if(!splt->n_entries) return SPNG_ECHUNK_SIZE;
  2324. size_t list_size = splt->n_entries;
  2325. if(list_size > SIZE_MAX / sizeof(struct spng_splt_entry)) return SPNG_EOVERFLOW;
  2326. list_size *= sizeof(struct spng_splt_entry);
  2327. if(increase_cache_usage(ctx, list_size, 0)) return SPNG_ECHUNK_LIMITS;
  2328. splt->entries = spng__malloc(ctx, list_size);
  2329. if(splt->entries == NULL)
  2330. {
  2331. spng__free(ctx, t);
  2332. return SPNG_EMEM;
  2333. }
  2334. data = (unsigned char*)t + keyword_len + 2;
  2335. uint32_t k;
  2336. if(splt->sample_depth == 16)
  2337. {
  2338. for(k=0; k < splt->n_entries; k++)
  2339. {
  2340. splt->entries[k].red = read_u16(data + k * 10);
  2341. splt->entries[k].green = read_u16(data + k * 10 + 2);
  2342. splt->entries[k].blue = read_u16(data + k * 10 + 4);
  2343. splt->entries[k].alpha = read_u16(data + k * 10 + 6);
  2344. splt->entries[k].frequency = read_u16(data + k * 10 + 8);
  2345. }
  2346. }
  2347. else if(splt->sample_depth == 8)
  2348. {
  2349. for(k=0; k < splt->n_entries; k++)
  2350. {
  2351. splt->entries[k].red = data[k * 6];
  2352. splt->entries[k].green = data[k * 6 + 1];
  2353. splt->entries[k].blue = data[k * 6 + 2];
  2354. splt->entries[k].alpha = data[k * 6 + 3];
  2355. splt->entries[k].frequency = read_u16(data + k * 6 + 4);
  2356. }
  2357. }
  2358. spng__free(ctx, t);
  2359. decrease_cache_usage(ctx, chunk.length);
  2360. ctx->stored.splt = 1;
  2361. }
  2362. else /* Unknown chunk */
  2363. {
  2364. ctx->file.unknown = 1;
  2365. if(!ctx->keep_unknown) goto discard;
  2366. if(ctx->user.unknown) goto discard;
  2367. if(increase_cache_usage(ctx, chunk.length + sizeof(struct spng_unknown_chunk), 1)) return SPNG_ECHUNK_LIMITS;
  2368. ctx->n_chunks++;
  2369. if(ctx->n_chunks < 1) return SPNG_EOVERFLOW;
  2370. if(sizeof(struct spng_unknown_chunk) > SIZE_MAX / ctx->n_chunks) return SPNG_EOVERFLOW;
  2371. void *buf = spng__realloc(ctx, ctx->chunk_list, ctx->n_chunks * sizeof(struct spng_unknown_chunk));
  2372. if(buf == NULL) return SPNG_EMEM;
  2373. ctx->chunk_list = buf;
  2374. struct spng_unknown_chunk *chunkp = &ctx->chunk_list[ctx->n_chunks - 1];
  2375. memset(chunkp, 0, sizeof(struct spng_unknown_chunk));
  2376. ctx->undo = chunk_undo;
  2377. memcpy(chunkp->type, chunk.type, 4);
  2378. if(ctx->state < SPNG_STATE_FIRST_IDAT)
  2379. {
  2380. if(ctx->file.plte) chunkp->location = SPNG_AFTER_PLTE;
  2381. else chunkp->location = SPNG_AFTER_IHDR;
  2382. }
  2383. else if(ctx->state >= SPNG_STATE_AFTER_IDAT) chunkp->location = SPNG_AFTER_IDAT;
  2384. if(chunk.length > 0)
  2385. {
  2386. void *t = spng__malloc(ctx, chunk.length);
  2387. if(t == NULL) return SPNG_EMEM;
  2388. ret = read_chunk_bytes2(ctx, t, chunk.length);
  2389. if(ret)
  2390. {
  2391. spng__free(ctx, t);
  2392. return ret;
  2393. }
  2394. chunkp->length = chunk.length;
  2395. chunkp->data = t;
  2396. }
  2397. ctx->stored.unknown = 1;
  2398. }
  2399. discard:
  2400. ret = discard_chunk_bytes(ctx, ctx->cur_chunk_bytes_left);
  2401. if(ret) return ret;
  2402. }
  2403. }
  2404. return ret;
  2405. }
  2406. /* Read chunks before or after the IDAT chunks depending on state */
  2407. static int read_chunks(spng_ctx *ctx, int only_ihdr)
  2408. {
  2409. if(ctx == NULL) return SPNG_EINTERNAL;
  2410. if(!ctx->state) return SPNG_EBADSTATE;
  2411. if(ctx->data == NULL)
  2412. {
  2413. if(ctx->encode_only) return 0;
  2414. else return SPNG_EINTERNAL;
  2415. }
  2416. int ret = 0;
  2417. if(ctx->state == SPNG_STATE_INPUT)
  2418. {
  2419. ret = read_ihdr(ctx);
  2420. if(ret) return decode_err(ctx, ret);
  2421. ctx->state = SPNG_STATE_IHDR;
  2422. }
  2423. if(only_ihdr) return 0;
  2424. if(ctx->state == SPNG_STATE_EOI)
  2425. {
  2426. ctx->state = SPNG_STATE_AFTER_IDAT;
  2427. ctx->prev_was_idat = 1;
  2428. }
  2429. while(ctx->state < SPNG_STATE_FIRST_IDAT || ctx->state == SPNG_STATE_AFTER_IDAT)
  2430. {
  2431. ret = read_non_idat_chunks(ctx);
  2432. if(!ret)
  2433. {
  2434. if(ctx->state < SPNG_STATE_FIRST_IDAT) ctx->state = SPNG_STATE_FIRST_IDAT;
  2435. else if(ctx->state == SPNG_STATE_AFTER_IDAT) ctx->state = SPNG_STATE_IEND;
  2436. }
  2437. else
  2438. {
  2439. switch(ret)
  2440. {
  2441. case SPNG_ECHUNK_POS:
  2442. case SPNG_ECHUNK_SIZE: /* size != expected size, SPNG_ECHUNK_STDLEN = invalid size */
  2443. case SPNG_EDUP_PLTE:
  2444. case SPNG_EDUP_CHRM:
  2445. case SPNG_EDUP_GAMA:
  2446. case SPNG_EDUP_ICCP:
  2447. case SPNG_EDUP_SBIT:
  2448. case SPNG_EDUP_SRGB:
  2449. case SPNG_EDUP_BKGD:
  2450. case SPNG_EDUP_HIST:
  2451. case SPNG_EDUP_TRNS:
  2452. case SPNG_EDUP_PHYS:
  2453. case SPNG_EDUP_TIME:
  2454. case SPNG_EDUP_OFFS:
  2455. case SPNG_EDUP_EXIF:
  2456. case SPNG_ECHRM:
  2457. case SPNG_ETRNS_COLOR_TYPE:
  2458. case SPNG_ETRNS_NO_PLTE:
  2459. case SPNG_EGAMA:
  2460. case SPNG_EICCP_NAME:
  2461. case SPNG_EICCP_COMPRESSION_METHOD:
  2462. case SPNG_ESBIT:
  2463. case SPNG_ESRGB:
  2464. case SPNG_ETEXT:
  2465. case SPNG_ETEXT_KEYWORD:
  2466. case SPNG_EZTXT:
  2467. case SPNG_EZTXT_COMPRESSION_METHOD:
  2468. case SPNG_EITXT:
  2469. case SPNG_EITXT_COMPRESSION_FLAG:
  2470. case SPNG_EITXT_COMPRESSION_METHOD:
  2471. case SPNG_EITXT_LANG_TAG:
  2472. case SPNG_EITXT_TRANSLATED_KEY:
  2473. case SPNG_EBKGD_NO_PLTE:
  2474. case SPNG_EBKGD_PLTE_IDX:
  2475. case SPNG_EHIST_NO_PLTE:
  2476. case SPNG_EPHYS:
  2477. case SPNG_ESPLT_NAME:
  2478. case SPNG_ESPLT_DUP_NAME:
  2479. case SPNG_ESPLT_DEPTH:
  2480. case SPNG_ETIME:
  2481. case SPNG_EOFFS:
  2482. case SPNG_EEXIF:
  2483. case SPNG_EZLIB:
  2484. {
  2485. if(!ctx->strict && !is_critical_chunk(&ctx->current_chunk))
  2486. {
  2487. ret = discard_chunk_bytes(ctx, ctx->cur_chunk_bytes_left);
  2488. if(ret) return decode_err(ctx, ret);
  2489. if(ctx->undo) ctx->undo(ctx);
  2490. ctx->stored = ctx->prev_stored;
  2491. ctx->discard = 0;
  2492. ctx->undo = NULL;
  2493. continue;
  2494. }
  2495. else return decode_err(ctx, ret);
  2496. break;
  2497. }
  2498. default: return decode_err(ctx, ret);
  2499. }
  2500. }
  2501. }
  2502. return ret;
  2503. }
  2504. static int read_scanline(spng_ctx *ctx)
  2505. {
  2506. int ret, pass = ctx->row_info.pass;
  2507. struct spng_row_info *ri = &ctx->row_info;
  2508. const struct spng_subimage *sub = ctx->subimage;
  2509. size_t scanline_width = sub[pass].scanline_width;
  2510. uint32_t scanline_idx = ri->scanline_idx;
  2511. uint8_t next_filter = 0;
  2512. if(scanline_idx == (sub[pass].height - 1) && ri->pass == ctx->last_pass)
  2513. {
  2514. ret = read_scanline_bytes(ctx, ctx->scanline, scanline_width - 1);
  2515. }
  2516. else
  2517. {
  2518. ret = read_scanline_bytes(ctx, ctx->scanline, scanline_width);
  2519. if(ret) return ret;
  2520. next_filter = ctx->scanline[scanline_width - 1];
  2521. if(next_filter > 4) ret = SPNG_EFILTER;
  2522. }
  2523. if(ret) return ret;
  2524. if(!scanline_idx && ri->filter > 1)
  2525. {
  2526. /* prev_scanline is all zeros for the first scanline */
  2527. memset(ctx->prev_scanline, 0, scanline_width);
  2528. }
  2529. if(ctx->ihdr.bit_depth == 16 && ctx->fmt != SPNG_FMT_RAW) u16_row_to_host(ctx->scanline, scanline_width - 1);
  2530. ret = defilter_scanline(ctx->prev_scanline, ctx->scanline, scanline_width, ctx->bytes_per_pixel, ri->filter);
  2531. if(ret) return ret;
  2532. ri->filter = next_filter;
  2533. return 0;
  2534. }
  2535. static int update_row_info(spng_ctx *ctx)
  2536. {
  2537. int interlacing = ctx->ihdr.interlace_method;
  2538. struct spng_row_info *ri = &ctx->row_info;
  2539. const struct spng_subimage *sub = ctx->subimage;
  2540. if(ri->scanline_idx == (sub[ri->pass].height - 1)) /* Last scanline */
  2541. {
  2542. if(ri->pass == ctx->last_pass)
  2543. {
  2544. ctx->state = SPNG_STATE_EOI;
  2545. return SPNG_EOI;
  2546. }
  2547. ri->scanline_idx = 0;
  2548. ri->pass++;
  2549. /* Skip empty passes */
  2550. while( (!sub[ri->pass].width || !sub[ri->pass].height) && (ri->pass < ctx->last_pass)) ri->pass++;
  2551. }
  2552. else
  2553. {
  2554. ri->row_num++;
  2555. ri->scanline_idx++;
  2556. }
  2557. if(interlacing) ri->row_num = adam7_y_start[ri->pass] + ri->scanline_idx * adam7_y_delta[ri->pass];
  2558. return 0;
  2559. }
  2560. int spng_decode_scanline(spng_ctx *ctx, void *out, size_t len)
  2561. {
  2562. if(ctx == NULL || out == NULL) return 1;
  2563. if(ctx->state >= SPNG_STATE_EOI) return SPNG_EOI;
  2564. struct decode_flags f = ctx->decode_flags;
  2565. struct spng_row_info *ri = &ctx->row_info;
  2566. const struct spng_subimage *sub = ctx->subimage;
  2567. const struct spng_ihdr *ihdr = &ctx->ihdr;
  2568. const uint16_t *gamma_lut = ctx->gamma_lut;
  2569. unsigned char *trns_px = ctx->trns_px;
  2570. const struct spng_sbit *sb = &ctx->decode_sb;
  2571. const struct spng_plte_entry *plte = ctx->decode_plte.rgba;
  2572. struct spng__iter iter = spng__iter_init(ihdr->bit_depth, ctx->scanline);
  2573. const unsigned char *scanline;
  2574. const int pass = ri->pass;
  2575. const int fmt = ctx->fmt;
  2576. const size_t scanline_width = sub[pass].scanline_width;
  2577. const uint32_t width = sub[pass].width;
  2578. uint32_t k;
  2579. uint8_t r_8, g_8, b_8, a_8, gray_8;
  2580. uint16_t r_16, g_16, b_16, a_16, gray_16;
  2581. r_8=0; g_8=0; b_8=0; a_8=0; gray_8=0;
  2582. r_16=0; g_16=0; b_16=0; a_16=0; gray_16=0;
  2583. size_t pixel_size = 4; /* SPNG_FMT_RGBA8 */
  2584. size_t pixel_offset = 0;
  2585. unsigned char *pixel;
  2586. unsigned processing_depth = ihdr->bit_depth;
  2587. if(f.indexed) processing_depth = 8;
  2588. if(fmt == SPNG_FMT_RGBA16) pixel_size = 8;
  2589. else if(fmt == SPNG_FMT_RGB8) pixel_size = 3;
  2590. if(len < sub[pass].out_width) return SPNG_EBUFSIZ;
  2591. int ret = read_scanline(ctx);
  2592. if(ret) return decode_err(ctx, ret);
  2593. scanline = ctx->scanline;
  2594. for(k=0; k < width; k++)
  2595. {
  2596. pixel = (unsigned char*)out + pixel_offset;
  2597. pixel_offset += pixel_size;
  2598. if(f.same_layout)
  2599. {
  2600. if(f.zerocopy) break;
  2601. memcpy(out, scanline, scanline_width - 1);
  2602. break;
  2603. }
  2604. if(f.unpack)
  2605. {
  2606. unpack_scanline(out, scanline, width, ihdr->bit_depth, fmt);
  2607. break;
  2608. }
  2609. if(ihdr->color_type == SPNG_COLOR_TYPE_TRUECOLOR)
  2610. {
  2611. if(ihdr->bit_depth == 16)
  2612. {
  2613. memcpy(&r_16, scanline + (k * 6), 2);
  2614. memcpy(&g_16, scanline + (k * 6) + 2, 2);
  2615. memcpy(&b_16, scanline + (k * 6) + 4, 2);
  2616. a_16 = 65535;
  2617. }
  2618. else /* == 8 */
  2619. {
  2620. if(fmt == SPNG_FMT_RGBA8)
  2621. {
  2622. rgb8_row_to_rgba8(scanline, out, width);
  2623. break;
  2624. }
  2625. r_8 = scanline[k * 3];
  2626. g_8 = scanline[k * 3 + 1];
  2627. b_8 = scanline[k * 3 + 2];
  2628. a_8 = 255;
  2629. }
  2630. }
  2631. else if(ihdr->color_type == SPNG_COLOR_TYPE_INDEXED)
  2632. {
  2633. uint8_t entry = 0;
  2634. if(ihdr->bit_depth == 8)
  2635. {
  2636. if(fmt & (SPNG_FMT_RGBA8 | SPNG_FMT_RGB8))
  2637. {
  2638. expand_row(out, scanline, &ctx->decode_plte, width, fmt);
  2639. break;
  2640. }
  2641. entry = scanline[k];
  2642. }
  2643. else /* < 8 */
  2644. {
  2645. entry = get_sample(&iter);
  2646. }
  2647. if(fmt & (SPNG_FMT_RGBA8 | SPNG_FMT_RGB8))
  2648. {
  2649. pixel[0] = plte[entry].red;
  2650. pixel[1] = plte[entry].green;
  2651. pixel[2] = plte[entry].blue;
  2652. if(fmt == SPNG_FMT_RGBA8) pixel[3] = plte[entry].alpha;
  2653. continue;
  2654. }
  2655. else /* RGBA16 */
  2656. {
  2657. r_16 = plte[entry].red;
  2658. g_16 = plte[entry].green;
  2659. b_16 = plte[entry].blue;
  2660. a_16 = plte[entry].alpha;
  2661. r_16 = (r_16 << 8) | r_16;
  2662. g_16 = (g_16 << 8) | g_16;
  2663. b_16 = (b_16 << 8) | b_16;
  2664. a_16 = (a_16 << 8) | a_16;
  2665. memcpy(pixel, &r_16, 2);
  2666. memcpy(pixel + 2, &g_16, 2);
  2667. memcpy(pixel + 4, &b_16, 2);
  2668. memcpy(pixel + 6, &a_16, 2);
  2669. continue;
  2670. }
  2671. }
  2672. else if(ihdr->color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA)
  2673. {
  2674. if(ihdr->bit_depth == 16)
  2675. {
  2676. memcpy(&r_16, scanline + (k * 8), 2);
  2677. memcpy(&g_16, scanline + (k * 8) + 2, 2);
  2678. memcpy(&b_16, scanline + (k * 8) + 4, 2);
  2679. memcpy(&a_16, scanline + (k * 8) + 6, 2);
  2680. }
  2681. else /* == 8 */
  2682. {
  2683. r_8 = scanline[k * 4];
  2684. g_8 = scanline[k * 4 + 1];
  2685. b_8 = scanline[k * 4 + 2];
  2686. a_8 = scanline[k * 4 + 3];
  2687. }
  2688. }
  2689. else if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE)
  2690. {
  2691. if(ihdr->bit_depth == 16)
  2692. {
  2693. memcpy(&gray_16, scanline + k * 2, 2);
  2694. if(f.apply_trns && ctx->trns.gray == gray_16) a_16 = 0;
  2695. else a_16 = 65535;
  2696. r_16 = gray_16;
  2697. g_16 = gray_16;
  2698. b_16 = gray_16;
  2699. }
  2700. else /* <= 8 */
  2701. {
  2702. gray_8 = get_sample(&iter);
  2703. if(f.apply_trns && ctx->trns.gray == gray_8) a_8 = 0;
  2704. else a_8 = 255;
  2705. r_8 = gray_8; g_8 = gray_8; b_8 = gray_8;
  2706. }
  2707. }
  2708. else if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA)
  2709. {
  2710. if(ihdr->bit_depth == 16)
  2711. {
  2712. memcpy(&gray_16, scanline + (k * 4), 2);
  2713. memcpy(&a_16, scanline + (k * 4) + 2, 2);
  2714. r_16 = gray_16;
  2715. g_16 = gray_16;
  2716. b_16 = gray_16;
  2717. }
  2718. else /* == 8 */
  2719. {
  2720. gray_8 = scanline[k * 2];
  2721. a_8 = scanline[k * 2 + 1];
  2722. r_8 = gray_8;
  2723. g_8 = gray_8;
  2724. b_8 = gray_8;
  2725. }
  2726. }
  2727. if(fmt & (SPNG_FMT_RGBA8 | SPNG_FMT_RGB8))
  2728. {
  2729. if(ihdr->bit_depth == 16)
  2730. {
  2731. r_8 = r_16 >> 8;
  2732. g_8 = g_16 >> 8;
  2733. b_8 = b_16 >> 8;
  2734. a_8 = a_16 >> 8;
  2735. }
  2736. pixel[0] = r_8;
  2737. pixel[1] = g_8;
  2738. pixel[2] = b_8;
  2739. if(fmt == SPNG_FMT_RGBA8) pixel[3] = a_8;
  2740. }
  2741. else if(fmt == SPNG_FMT_RGBA16)
  2742. {
  2743. if(ihdr->bit_depth != 16)
  2744. {
  2745. r_16 = r_8;
  2746. g_16 = g_8;
  2747. b_16 = b_8;
  2748. a_16 = a_8;
  2749. }
  2750. memcpy(pixel, &r_16, 2);
  2751. memcpy(pixel + 2, &g_16, 2);
  2752. memcpy(pixel + 4, &b_16, 2);
  2753. memcpy(pixel + 6, &a_16, 2);
  2754. }
  2755. }/* for(k=0; k < width; k++) */
  2756. if(f.apply_trns) trns_row(out, scanline, trns_px, ctx->bytes_per_pixel, &ctx->ihdr, width, fmt);
  2757. if(f.do_scaling) scale_row(out, width, fmt, processing_depth, sb);
  2758. if(f.apply_gamma) gamma_correct_row(out, width, fmt, gamma_lut);
  2759. /* The previous scanline is always defiltered */
  2760. void *t = ctx->prev_scanline;
  2761. ctx->prev_scanline = ctx->scanline;
  2762. ctx->scanline = t;
  2763. ret = update_row_info(ctx);
  2764. if(ret == SPNG_EOI)
  2765. {
  2766. if(ctx->cur_chunk_bytes_left) /* zlib stream ended before an IDAT chunk boundary */
  2767. {/* Discard the rest of the chunk */
  2768. int error = discard_chunk_bytes(ctx, ctx->cur_chunk_bytes_left);
  2769. if(error) return decode_err(ctx, error);
  2770. }
  2771. ctx->last_idat = ctx->current_chunk;
  2772. }
  2773. return ret;
  2774. }
  2775. int spng_decode_row(spng_ctx *ctx, void *out, size_t len)
  2776. {
  2777. if(ctx == NULL || out == NULL) return 1;
  2778. if(ctx->state >= SPNG_STATE_EOI) return SPNG_EOI;
  2779. if(len < ctx->image_width) return SPNG_EBUFSIZ;
  2780. const struct spng_ihdr *ihdr = &ctx->ihdr;
  2781. int ret, pass = ctx->row_info.pass;
  2782. unsigned char *outptr = out;
  2783. if(!ihdr->interlace_method || pass == 6) return spng_decode_scanline(ctx, out, len);
  2784. ret = spng_decode_scanline(ctx, ctx->row, ctx->image_width);
  2785. if(ret && ret != SPNG_EOI) return ret;
  2786. uint32_t k;
  2787. unsigned pixel_size = 4; /* RGBA8 */
  2788. if(ctx->fmt == SPNG_FMT_RGBA16) pixel_size = 8;
  2789. else if(ctx->fmt == SPNG_FMT_RGB8) pixel_size = 3;
  2790. else if(ctx->fmt == SPNG_FMT_G8) pixel_size = 1;
  2791. else if(ctx->fmt == SPNG_FMT_GA8) pixel_size = 2;
  2792. else if(ctx->fmt & (SPNG_FMT_PNG | SPNG_FMT_RAW))
  2793. {
  2794. if(ihdr->bit_depth < 8)
  2795. {
  2796. struct spng__iter iter = spng__iter_init(ihdr->bit_depth, ctx->row);
  2797. const uint8_t samples_per_byte = 8 / ihdr->bit_depth;
  2798. uint8_t sample;
  2799. for(k=0; k < ctx->subimage[pass].width; k++)
  2800. {
  2801. sample = get_sample(&iter);
  2802. size_t ioffset = adam7_x_start[pass] + k * adam7_x_delta[pass];
  2803. sample = sample << (iter.initial_shift - ioffset * ihdr->bit_depth % 8);
  2804. ioffset /= samples_per_byte;
  2805. outptr[ioffset] |= sample;
  2806. }
  2807. return 0;
  2808. }
  2809. else pixel_size = ctx->bytes_per_pixel;
  2810. }
  2811. for(k=0; k < ctx->subimage[pass].width; k++)
  2812. {
  2813. size_t ioffset = (adam7_x_start[pass] + (size_t) k * adam7_x_delta[pass]) * pixel_size;
  2814. memcpy(outptr + ioffset, ctx->row + k * pixel_size, pixel_size);
  2815. }
  2816. return 0;
  2817. }
  2818. int spng_decode_chunks(spng_ctx *ctx)
  2819. {
  2820. if(ctx == NULL) return 1;
  2821. if(ctx->encode_only) return SPNG_ECTXTYPE;
  2822. if(ctx->state < SPNG_STATE_INPUT) return SPNG_ENOSRC;
  2823. if(ctx->state == SPNG_STATE_IEND) return 0;
  2824. return read_chunks(ctx, 0);
  2825. }
  2826. int spng_decode_image(spng_ctx *ctx, void *out, size_t len, int fmt, int flags)
  2827. {
  2828. if(ctx == NULL) return 1;
  2829. if(ctx->encode_only) return SPNG_ECTXTYPE;
  2830. if(ctx->state >= SPNG_STATE_EOI) return SPNG_EOI;
  2831. const struct spng_ihdr *ihdr = &ctx->ihdr;
  2832. int ret = read_chunks(ctx, 0);
  2833. if(ret) return decode_err(ctx, ret);
  2834. ret = check_decode_fmt(ihdr, fmt);
  2835. if(ret) return ret;
  2836. ret = calculate_image_width(ihdr, fmt, &ctx->image_width);
  2837. if(ret) return decode_err(ctx, ret);
  2838. if(ctx->image_width > SIZE_MAX / ihdr->height) ctx->image_size = 0; /* overflow */
  2839. else ctx->image_size = ctx->image_width * ihdr->height;
  2840. if( !(flags & SPNG_DECODE_PROGRESSIVE) )
  2841. {
  2842. if(out == NULL) return 1;
  2843. if(!ctx->image_size) return SPNG_EOVERFLOW;
  2844. if(len < ctx->image_size) return SPNG_EBUFSIZ;
  2845. }
  2846. uint32_t bytes_read = 0;
  2847. ret = read_idat_bytes(ctx, &bytes_read);
  2848. if(ret) return decode_err(ctx, ret);
  2849. if(bytes_read > 1)
  2850. {
  2851. int valid = read_u16(ctx->data) % 31 ? 0 : 1;
  2852. unsigned flg = ctx->data[1];
  2853. unsigned flevel = flg >> 6;
  2854. int compression_level = Z_DEFAULT_COMPRESSION;
  2855. if(flevel == 0) compression_level = 0; /* fastest */
  2856. else if(flevel == 1) compression_level = 1; /* fast */
  2857. else if(flevel == 2) compression_level = 6; /* default */
  2858. else if(flevel == 3) compression_level = 9; /* slowest, max compression */
  2859. if(valid) ctx->image_options.compression_level = compression_level;
  2860. }
  2861. ret = spng__inflate_init(ctx, ctx->image_options.window_bits);
  2862. if(ret) return decode_err(ctx, ret);
  2863. ctx->zstream.avail_in = bytes_read;
  2864. ctx->zstream.next_in = ctx->data;
  2865. size_t scanline_buf_size = ctx->subimage[ctx->widest_pass].scanline_width;
  2866. scanline_buf_size += 32;
  2867. if(scanline_buf_size < 32) return SPNG_EOVERFLOW;
  2868. ctx->scanline_buf = spng__malloc(ctx, scanline_buf_size);
  2869. ctx->prev_scanline_buf = spng__malloc(ctx, scanline_buf_size);
  2870. ctx->scanline = ctx->scanline_buf;
  2871. ctx->prev_scanline = ctx->prev_scanline_buf;
  2872. struct decode_flags f = {0};
  2873. ctx->fmt = fmt;
  2874. if(ihdr->color_type == SPNG_COLOR_TYPE_INDEXED) f.indexed = 1;
  2875. unsigned processing_depth = ihdr->bit_depth;
  2876. if(f.indexed) processing_depth = 8;
  2877. if(ihdr->interlace_method)
  2878. {
  2879. f.interlaced = 1;
  2880. ctx->row_buf = spng__malloc(ctx, ctx->image_width);
  2881. ctx->row = ctx->row_buf;
  2882. if(ctx->row == NULL) return decode_err(ctx, SPNG_EMEM);
  2883. }
  2884. if(ctx->scanline == NULL || ctx->prev_scanline == NULL)
  2885. {
  2886. return decode_err(ctx, SPNG_EMEM);
  2887. }
  2888. f.do_scaling = 1;
  2889. if(f.indexed) f.do_scaling = 0;
  2890. unsigned depth_target = 8; /* FMT_RGBA8, G8 */
  2891. if(fmt == SPNG_FMT_RGBA16) depth_target = 16;
  2892. if(flags & SPNG_DECODE_TRNS && ctx->stored.trns) f.apply_trns = 1;
  2893. else flags &= ~SPNG_DECODE_TRNS;
  2894. if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA ||
  2895. ihdr->color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA) flags &= ~SPNG_DECODE_TRNS;
  2896. if(flags & SPNG_DECODE_GAMMA && ctx->stored.gama) f.apply_gamma = 1;
  2897. else flags &= ~SPNG_DECODE_GAMMA;
  2898. if(flags & SPNG_DECODE_USE_SBIT && ctx->stored.sbit) f.use_sbit = 1;
  2899. else flags &= ~SPNG_DECODE_USE_SBIT;
  2900. if(fmt & (SPNG_FMT_RGBA8 | SPNG_FMT_RGBA16))
  2901. {
  2902. if(ihdr->color_type == SPNG_COLOR_TYPE_TRUECOLOR_ALPHA &&
  2903. ihdr->bit_depth == depth_target) f.same_layout = 1;
  2904. }
  2905. else if(fmt == SPNG_FMT_RGB8)
  2906. {
  2907. if(ihdr->color_type == SPNG_COLOR_TYPE_TRUECOLOR &&
  2908. ihdr->bit_depth == depth_target) f.same_layout = 1;
  2909. f.apply_trns = 0; /* not applicable */
  2910. }
  2911. else if(fmt & (SPNG_FMT_PNG | SPNG_FMT_RAW))
  2912. {
  2913. f.same_layout = 1;
  2914. f.do_scaling = 0;
  2915. f.apply_gamma = 0; /* for now */
  2916. f.apply_trns = 0;
  2917. }
  2918. else if(fmt == SPNG_FMT_G8 && ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE && ihdr->bit_depth <= 8)
  2919. {
  2920. if(ihdr->bit_depth == depth_target) f.same_layout = 1;
  2921. else if(ihdr->bit_depth < 8) f.unpack = 1;
  2922. f.apply_trns = 0;
  2923. }
  2924. else if(fmt == SPNG_FMT_GA8 && ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE && ihdr->bit_depth <= 8)
  2925. {
  2926. if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA &&
  2927. ihdr->bit_depth == depth_target) f.same_layout = 1;
  2928. else if(ihdr->bit_depth <= 8) f.unpack = 1;
  2929. }
  2930. else if(fmt == SPNG_FMT_GA16 && ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE && ihdr->bit_depth == 16)
  2931. {
  2932. if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE_ALPHA &&
  2933. ihdr->bit_depth == depth_target) f.same_layout = 1;
  2934. else if(ihdr->bit_depth == 16) f.unpack = 1;
  2935. }
  2936. /*if(f.same_layout && !flags && !f.interlaced) f.zerocopy = 1;*/
  2937. uint16_t *gamma_lut = NULL;
  2938. if(f.apply_gamma)
  2939. {
  2940. float file_gamma = (float)ctx->gama / 100000.0f;
  2941. float max;
  2942. unsigned lut_entries;
  2943. if(fmt & (SPNG_FMT_RGBA8 | SPNG_FMT_RGB8))
  2944. {
  2945. lut_entries = 256;
  2946. max = 255.0f;
  2947. gamma_lut = ctx->gamma_lut8;
  2948. ctx->gamma_lut = ctx->gamma_lut8;
  2949. }
  2950. else /* SPNG_FMT_RGBA16 */
  2951. {
  2952. lut_entries = 65536;
  2953. max = 65535.0f;
  2954. ctx->gamma_lut16 = spng__malloc(ctx, lut_entries * sizeof(uint16_t));
  2955. if(ctx->gamma_lut16 == NULL) return decode_err(ctx, SPNG_EMEM);
  2956. gamma_lut = ctx->gamma_lut16;
  2957. ctx->gamma_lut = ctx->gamma_lut16;
  2958. }
  2959. float screen_gamma = 2.2f;
  2960. float exponent = file_gamma * screen_gamma;
  2961. if(FP_ZERO == fpclassify(exponent)) return decode_err(ctx, SPNG_EGAMA);
  2962. exponent = 1.0f / exponent;
  2963. unsigned i;
  2964. for(i=0; i < lut_entries; i++)
  2965. {
  2966. float c = pow((float)i / max, exponent) * max;
  2967. if(c > max) c = max;
  2968. gamma_lut[i] = (uint16_t)c;
  2969. }
  2970. }
  2971. struct spng_sbit *sb = &ctx->decode_sb;
  2972. sb->red_bits = processing_depth;
  2973. sb->green_bits = processing_depth;
  2974. sb->blue_bits = processing_depth;
  2975. sb->alpha_bits = processing_depth;
  2976. sb->grayscale_bits = processing_depth;
  2977. if(f.use_sbit)
  2978. {
  2979. if(ihdr->color_type == 0)
  2980. {
  2981. sb->grayscale_bits = ctx->sbit.grayscale_bits;
  2982. sb->alpha_bits = ihdr->bit_depth;
  2983. }
  2984. else if(ihdr->color_type == 2 || ihdr->color_type == 3)
  2985. {
  2986. sb->red_bits = ctx->sbit.red_bits;
  2987. sb->green_bits = ctx->sbit.green_bits;
  2988. sb->blue_bits = ctx->sbit.blue_bits;
  2989. sb->alpha_bits = ihdr->bit_depth;
  2990. }
  2991. else if(ihdr->color_type == 4)
  2992. {
  2993. sb->grayscale_bits = ctx->sbit.grayscale_bits;
  2994. sb->alpha_bits = ctx->sbit.alpha_bits;
  2995. }
  2996. else /* == 6 */
  2997. {
  2998. sb->red_bits = ctx->sbit.red_bits;
  2999. sb->green_bits = ctx->sbit.green_bits;
  3000. sb->blue_bits = ctx->sbit.blue_bits;
  3001. sb->alpha_bits = ctx->sbit.alpha_bits;
  3002. }
  3003. }
  3004. if(ihdr->bit_depth == 16 && fmt & (SPNG_FMT_RGBA8 | SPNG_FMT_RGB8))
  3005. {/* samples are scaled down by 8 bits in the decode loop */
  3006. sb->red_bits -= 8;
  3007. sb->green_bits -= 8;
  3008. sb->blue_bits -= 8;
  3009. sb->alpha_bits -= 8;
  3010. sb->grayscale_bits -= 8;
  3011. processing_depth = 8;
  3012. }
  3013. /* Prevent infinite loops in sample_to_target() */
  3014. if(!depth_target || depth_target > 16 ||
  3015. !processing_depth || processing_depth > 16 ||
  3016. !sb->grayscale_bits || sb->grayscale_bits > processing_depth ||
  3017. !sb->alpha_bits || sb->alpha_bits > processing_depth ||
  3018. !sb->red_bits || sb->red_bits > processing_depth ||
  3019. !sb->green_bits || sb->green_bits > processing_depth ||
  3020. !sb->blue_bits || sb->blue_bits > processing_depth)
  3021. {
  3022. return decode_err(ctx, SPNG_ESBIT);
  3023. }
  3024. if(sb->red_bits == sb->green_bits &&
  3025. sb->green_bits == sb->blue_bits &&
  3026. sb->blue_bits == sb->alpha_bits &&
  3027. sb->alpha_bits == processing_depth &&
  3028. processing_depth == depth_target) f.do_scaling = 0;
  3029. struct spng_plte_entry *plte = ctx->decode_plte.rgba;
  3030. /* Pre-process palette entries */
  3031. if(f.indexed)
  3032. {
  3033. uint8_t red, green, blue, alpha;
  3034. uint32_t i;
  3035. for(i=0; i < 256; i++)
  3036. {
  3037. if(f.apply_trns && i < ctx->trns.n_type3_entries)
  3038. ctx->plte.entries[i].alpha = ctx->trns.type3_alpha[i];
  3039. else
  3040. ctx->plte.entries[i].alpha = 255;
  3041. red = sample_to_target(ctx->plte.entries[i].red, 8, sb->red_bits, 8);
  3042. green = sample_to_target(ctx->plte.entries[i].green, 8, sb->green_bits, 8);
  3043. blue = sample_to_target(ctx->plte.entries[i].blue, 8, sb->blue_bits, 8);
  3044. alpha = sample_to_target(ctx->plte.entries[i].alpha, 8, sb->alpha_bits, 8);
  3045. #if defined(SPNG_ARM)
  3046. if(fmt == SPNG_FMT_RGB8 && ihdr->bit_depth == 8)
  3047. {/* Working with 3 bytes at a time is more of an ARM thing */
  3048. ctx->decode_plte.rgb[i * 3 + 0] = red;
  3049. ctx->decode_plte.rgb[i * 3 + 1] = green;
  3050. ctx->decode_plte.rgb[i * 3 + 2] = blue;
  3051. continue;
  3052. }
  3053. #endif
  3054. plte[i].red = red;
  3055. plte[i].green = green;
  3056. plte[i].blue = blue;
  3057. plte[i].alpha = alpha;
  3058. }
  3059. f.apply_trns = 0;
  3060. }
  3061. unsigned char *trns_px = ctx->trns_px;
  3062. if(f.apply_trns)
  3063. {
  3064. uint16_t mask = ~0;
  3065. if(ctx->ihdr.bit_depth < 16) mask = (1 << ctx->ihdr.bit_depth) - 1;
  3066. if(fmt & (SPNG_FMT_RGBA8 | SPNG_FMT_RGBA16))
  3067. {
  3068. if(ihdr->color_type == SPNG_COLOR_TYPE_TRUECOLOR)
  3069. {
  3070. if(ihdr->bit_depth == 16)
  3071. {
  3072. memcpy(trns_px, &ctx->trns.red, 2);
  3073. memcpy(trns_px + 2, &ctx->trns.green, 2);
  3074. memcpy(trns_px + 4, &ctx->trns.blue, 2);
  3075. }
  3076. else
  3077. {
  3078. trns_px[0] = ctx->trns.red & mask;
  3079. trns_px[1] = ctx->trns.green & mask;
  3080. trns_px[2] = ctx->trns.blue & mask;
  3081. }
  3082. }
  3083. }
  3084. else if(ihdr->color_type == SPNG_COLOR_TYPE_GRAYSCALE) // fmt == SPNG_FMT_GA8 &&
  3085. {
  3086. if(ihdr->bit_depth == 16)
  3087. {
  3088. memcpy(trns_px, &ctx->trns.gray, 2);
  3089. }
  3090. else
  3091. {
  3092. trns_px[0] = ctx->trns.gray & mask;
  3093. }
  3094. }
  3095. }
  3096. ctx->decode_flags = f;
  3097. ctx->state = SPNG_STATE_DECODE_INIT;
  3098. struct spng_row_info *ri = &ctx->row_info;
  3099. struct spng_subimage *sub = ctx->subimage;
  3100. while(!sub[ri->pass].width || !sub[ri->pass].height) ri->pass++;
  3101. if(f.interlaced) ri->row_num = adam7_y_start[ri->pass];
  3102. unsigned pixel_size = 4; /* SPNG_FMT_RGBA8 */
  3103. if(fmt == SPNG_FMT_RGBA16) pixel_size = 8;
  3104. else if(fmt == SPNG_FMT_RGB8) pixel_size = 3;
  3105. else if(fmt == SPNG_FMT_G8) pixel_size = 1;
  3106. else if(fmt == SPNG_FMT_GA8) pixel_size = 2;
  3107. int i;
  3108. for(i=ri->pass; i <= ctx->last_pass; i++)
  3109. {
  3110. if(!sub[i].scanline_width) continue;
  3111. if(fmt & (SPNG_FMT_PNG | SPNG_FMT_RAW)) sub[i].out_width = sub[i].scanline_width - 1;
  3112. else sub[i].out_width = (size_t)sub[i].width * pixel_size;
  3113. if(sub[i].out_width > UINT32_MAX) return decode_err(ctx, SPNG_EOVERFLOW);
  3114. }
  3115. /* Read the first filter byte, offsetting all reads by 1 byte.
  3116. The scanlines will be aligned with the start of the array with
  3117. the next scanline's filter byte at the end,
  3118. the last scanline will end up being 1 byte "shorter". */
  3119. ret = read_scanline_bytes(ctx, &ri->filter, 1);
  3120. if(ret) return decode_err(ctx, ret);
  3121. if(ri->filter > 4) return decode_err(ctx, SPNG_EFILTER);
  3122. if(flags & SPNG_DECODE_PROGRESSIVE)
  3123. {
  3124. return 0;
  3125. }
  3126. do
  3127. {
  3128. size_t ioffset = ri->row_num * ctx->image_width;
  3129. ret = spng_decode_row(ctx, (unsigned char*)out + ioffset, ctx->image_width);
  3130. }while(!ret);
  3131. if(ret != SPNG_EOI) return decode_err(ctx, ret);
  3132. return 0;
  3133. }
  3134. int spng_get_row_info(spng_ctx *ctx, struct spng_row_info *row_info)
  3135. {
  3136. if(ctx == NULL || row_info == NULL || ctx->state < SPNG_STATE_DECODE_INIT) return 1;
  3137. if(ctx->state >= SPNG_STATE_EOI) return SPNG_EOI;
  3138. *row_info = ctx->row_info;
  3139. return 0;
  3140. }
  3141. static int write_chunks_before_idat(spng_ctx *ctx)
  3142. {
  3143. if(ctx == NULL) return SPNG_EINTERNAL;
  3144. if(!ctx->encode_only) return SPNG_EINTERNAL;
  3145. if(!ctx->stored.ihdr) return SPNG_EINTERNAL;
  3146. int ret;
  3147. uint32_t i;
  3148. size_t length;
  3149. const struct spng_ihdr *ihdr = &ctx->ihdr;
  3150. unsigned char *data = ctx->decode_plte.raw;
  3151. ret = write_data(ctx, spng_signature, 8);
  3152. if(ret) return ret;
  3153. write_u32(data, ihdr->width);
  3154. write_u32(data + 4, ihdr->height);
  3155. data[8] = ihdr->bit_depth;
  3156. data[9] = ihdr->color_type;
  3157. data[10] = ihdr->compression_method;
  3158. data[11] = ihdr->filter_method;
  3159. data[12] = ihdr->interlace_method;
  3160. ret = write_chunk(ctx, type_ihdr, data, 13);
  3161. if(ret) return ret;
  3162. if(ctx->stored.chrm)
  3163. {
  3164. write_u32(data, ctx->chrm_int.white_point_x);
  3165. write_u32(data + 4, ctx->chrm_int.white_point_y);
  3166. write_u32(data + 8, ctx->chrm_int.red_x);
  3167. write_u32(data + 12, ctx->chrm_int.red_y);
  3168. write_u32(data + 16, ctx->chrm_int.green_x);
  3169. write_u32(data + 20, ctx->chrm_int.green_y);
  3170. write_u32(data + 24, ctx->chrm_int.blue_x);
  3171. write_u32(data + 28, ctx->chrm_int.blue_y);
  3172. ret = write_chunk(ctx, type_chrm, data, 32);
  3173. if(ret) return ret;
  3174. }
  3175. if(ctx->stored.gama)
  3176. {
  3177. write_u32(data, ctx->gama);
  3178. ret = write_chunk(ctx, type_gama, data, 4);
  3179. if(ret) return ret;
  3180. }
  3181. if(ctx->stored.iccp)
  3182. {
  3183. uLongf dest_len = compressBound((uLong)ctx->iccp.profile_len);
  3184. Bytef *buf = spng__malloc(ctx, dest_len);
  3185. if(buf == NULL) return SPNG_EMEM;
  3186. ret = compress2(buf, &dest_len, (void*)ctx->iccp.profile, (uLong)ctx->iccp.profile_len, Z_DEFAULT_COMPRESSION);
  3187. if(ret != Z_OK)
  3188. {
  3189. spng__free(ctx, buf);
  3190. return SPNG_EZLIB;
  3191. }
  3192. size_t name_len = strlen(ctx->iccp.profile_name);
  3193. length = name_len + 2;
  3194. length += dest_len;
  3195. if(dest_len > length) return SPNG_EOVERFLOW;
  3196. unsigned char *cdata = NULL;
  3197. ret = write_header(ctx, type_iccp, length, &cdata);
  3198. if(ret)
  3199. {
  3200. spng__free(ctx, buf);
  3201. return ret;
  3202. }
  3203. memcpy(cdata, ctx->iccp.profile_name, name_len + 1);
  3204. cdata[name_len + 1] = 0; /* compression method */
  3205. memcpy(cdata + name_len + 2, buf, dest_len);
  3206. spng__free(ctx, buf);
  3207. ret = finish_chunk(ctx);
  3208. if(ret) return ret;
  3209. }
  3210. if(ctx->stored.sbit)
  3211. {
  3212. switch(ctx->ihdr.color_type)
  3213. {
  3214. case SPNG_COLOR_TYPE_GRAYSCALE:
  3215. {
  3216. length = 1;
  3217. data[0] = ctx->sbit.grayscale_bits;
  3218. break;
  3219. }
  3220. case SPNG_COLOR_TYPE_TRUECOLOR:
  3221. case SPNG_COLOR_TYPE_INDEXED:
  3222. {
  3223. length = 3;
  3224. data[0] = ctx->sbit.red_bits;
  3225. data[1] = ctx->sbit.green_bits;
  3226. data[2] = ctx->sbit.blue_bits;
  3227. break;
  3228. }
  3229. case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA:
  3230. {
  3231. length = 2;
  3232. data[0] = ctx->sbit.grayscale_bits;
  3233. data[1] = ctx->sbit.alpha_bits;
  3234. break;
  3235. }
  3236. case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA:
  3237. {
  3238. length = 4;
  3239. data[0] = ctx->sbit.red_bits;
  3240. data[1] = ctx->sbit.green_bits;
  3241. data[2] = ctx->sbit.blue_bits;
  3242. data[3] = ctx->sbit.alpha_bits;
  3243. break;
  3244. }
  3245. default: return SPNG_EINTERNAL;
  3246. }
  3247. ret = write_chunk(ctx, type_sbit, data, length);
  3248. if(ret) return ret;
  3249. }
  3250. if(ctx->stored.srgb)
  3251. {
  3252. ret = write_chunk(ctx, type_srgb, &ctx->srgb_rendering_intent, 1);
  3253. if(ret) return ret;
  3254. }
  3255. ret = write_unknown_chunks(ctx, SPNG_AFTER_IHDR);
  3256. if(ret) return ret;
  3257. if(ctx->stored.plte)
  3258. {
  3259. for(i=0; i < ctx->plte.n_entries; i++)
  3260. {
  3261. data[i * 3 + 0] = ctx->plte.entries[i].red;
  3262. data[i * 3 + 1] = ctx->plte.entries[i].green;
  3263. data[i * 3 + 2] = ctx->plte.entries[i].blue;
  3264. }
  3265. ret = write_chunk(ctx, type_plte, data, ctx->plte.n_entries * 3);
  3266. if(ret) return ret;
  3267. }
  3268. if(ctx->stored.bkgd)
  3269. {
  3270. switch(ctx->ihdr.color_type)
  3271. {
  3272. case SPNG_COLOR_TYPE_GRAYSCALE:
  3273. case SPNG_COLOR_TYPE_GRAYSCALE_ALPHA:
  3274. {
  3275. length = 2;
  3276. write_u16(data, ctx->bkgd.gray);
  3277. break;
  3278. }
  3279. case SPNG_COLOR_TYPE_TRUECOLOR:
  3280. case SPNG_COLOR_TYPE_TRUECOLOR_ALPHA:
  3281. {
  3282. length = 6;
  3283. write_u16(data, ctx->bkgd.red);
  3284. write_u16(data + 2, ctx->bkgd.green);
  3285. write_u16(data + 4, ctx->bkgd.blue);
  3286. break;
  3287. }
  3288. case SPNG_COLOR_TYPE_INDEXED:
  3289. {
  3290. length = 1;
  3291. data[0] = ctx->bkgd.plte_index;
  3292. break;
  3293. }
  3294. default: return SPNG_EINTERNAL;
  3295. }
  3296. ret = write_chunk(ctx, type_bkgd, data, length);
  3297. if(ret) return ret;
  3298. }
  3299. if(ctx->stored.hist)
  3300. {
  3301. length = ctx->plte.n_entries * 2;
  3302. for(i=0; i < ctx->plte.n_entries; i++)
  3303. {
  3304. write_u16(data + i * 2, ctx->hist.frequency[i]);
  3305. }
  3306. ret = write_chunk(ctx, type_hist, data, length);
  3307. if(ret) return ret;
  3308. }
  3309. if(ctx->stored.trns)
  3310. {
  3311. if(ctx->ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE)
  3312. {
  3313. write_u16(data, ctx->trns.gray);
  3314. ret = write_chunk(ctx, type_trns, data, 2);
  3315. }
  3316. else if(ctx->ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR)
  3317. {
  3318. write_u16(data, ctx->trns.red);
  3319. write_u16(data + 2, ctx->trns.green);
  3320. write_u16(data + 4, ctx->trns.blue);
  3321. ret = write_chunk(ctx, type_trns, data, 6);
  3322. }
  3323. else if(ctx->ihdr.color_type == SPNG_COLOR_TYPE_INDEXED)
  3324. {
  3325. ret = write_chunk(ctx, type_trns, ctx->trns.type3_alpha, ctx->trns.n_type3_entries);
  3326. }
  3327. if(ret) return ret;
  3328. }
  3329. if(ctx->stored.phys)
  3330. {
  3331. write_u32(data, ctx->phys.ppu_x);
  3332. write_u32(data + 4, ctx->phys.ppu_y);
  3333. data[8] = ctx->phys.unit_specifier;
  3334. ret = write_chunk(ctx, type_phys, data, 9);
  3335. if(ret) return ret;
  3336. }
  3337. if(ctx->stored.splt)
  3338. {
  3339. const struct spng_splt *splt;
  3340. unsigned char *cdata = NULL;
  3341. uint32_t k;
  3342. for(i=0; i < ctx->n_splt; i++)
  3343. {
  3344. splt = &ctx->splt_list[i];
  3345. size_t name_len = strlen(splt->name);
  3346. length = name_len + 1;
  3347. if(splt->sample_depth == 8) length += splt->n_entries * 6 + 1;
  3348. else if(splt->sample_depth == 16) length += splt->n_entries * 10 + 1;
  3349. ret = write_header(ctx, type_splt, length, &cdata);
  3350. if(ret) return ret;
  3351. memcpy(cdata, splt->name, name_len + 1);
  3352. cdata += name_len + 2;
  3353. cdata[-1] = splt->sample_depth;
  3354. if(splt->sample_depth == 8)
  3355. {
  3356. for(k=0; k < splt->n_entries; k++)
  3357. {
  3358. cdata[k * 6 + 0] = splt->entries[k].red;
  3359. cdata[k * 6 + 1] = splt->entries[k].green;
  3360. cdata[k * 6 + 2] = splt->entries[k].blue;
  3361. cdata[k * 6 + 3] = splt->entries[k].alpha;
  3362. write_u16(cdata + k * 6 + 4, splt->entries[k].frequency);
  3363. }
  3364. }
  3365. else if(splt->sample_depth == 16)
  3366. {
  3367. for(k=0; k < splt->n_entries; k++)
  3368. {
  3369. write_u16(cdata + k * 10 + 0, splt->entries[k].red);
  3370. write_u16(cdata + k * 10 + 2, splt->entries[k].green);
  3371. write_u16(cdata + k * 10 + 4, splt->entries[k].blue);
  3372. write_u16(cdata + k * 10 + 6, splt->entries[k].alpha);
  3373. write_u16(cdata + k * 10 + 8, splt->entries[k].frequency);
  3374. }
  3375. }
  3376. ret = finish_chunk(ctx);
  3377. if(ret) return ret;
  3378. }
  3379. }
  3380. if(ctx->stored.time)
  3381. {
  3382. write_u16(data, ctx->time.year);
  3383. data[2] = ctx->time.month;
  3384. data[3] = ctx->time.day;
  3385. data[4] = ctx->time.hour;
  3386. data[5] = ctx->time.minute;
  3387. data[6] = ctx->time.second;
  3388. ret = write_chunk(ctx, type_time, data, 7);
  3389. if(ret) return ret;
  3390. }
  3391. if(ctx->stored.text)
  3392. {
  3393. unsigned char *cdata = NULL;
  3394. const struct spng_text2 *text;
  3395. const uint8_t *text_type_array[4] = { 0, type_text, type_ztxt, type_itxt };
  3396. for(i=0; i < ctx->n_text; i++)
  3397. {
  3398. text = &ctx->text_list[i];
  3399. const uint8_t *text_chunk_type = text_type_array[text->type];
  3400. Bytef *compressed_text = NULL;
  3401. size_t keyword_len = 0;
  3402. size_t language_tag_len = 0;
  3403. size_t translated_keyword_len = 0;
  3404. size_t compressed_length = 0;
  3405. size_t text_length = 0;
  3406. keyword_len = strlen(text->keyword);
  3407. text_length = strlen(text->text);
  3408. length = keyword_len + 1;
  3409. if(text->type == SPNG_ZTXT)
  3410. {
  3411. length += 1; /* compression method */
  3412. }
  3413. else if(text->type == SPNG_ITXT)
  3414. {
  3415. if(!text->language_tag || !text->translated_keyword) return SPNG_EINTERNAL;
  3416. language_tag_len = strlen(text->language_tag);
  3417. translated_keyword_len = strlen(text->translated_keyword);
  3418. length += language_tag_len;
  3419. if(length < language_tag_len) return SPNG_EOVERFLOW;
  3420. length += translated_keyword_len;
  3421. if(length < translated_keyword_len) return SPNG_EOVERFLOW;
  3422. length += 4; /* compression flag + method + nul for the two strings */
  3423. if(length < 4) return SPNG_EOVERFLOW;
  3424. }
  3425. if(text->compression_flag)
  3426. {
  3427. ret = spng__deflate_init(ctx, &ctx->text_options);
  3428. if(ret) return ret;
  3429. z_stream *zstream = &ctx->zstream;
  3430. uLongf dest_len = deflateBound(zstream, (uLong)text_length);
  3431. compressed_text = spng__malloc(ctx, dest_len);
  3432. if(compressed_text == NULL) return SPNG_EMEM;
  3433. zstream->next_in = (void*)text->text;
  3434. zstream->avail_in = (uInt)text_length;
  3435. zstream->next_out = compressed_text;
  3436. zstream->avail_out = dest_len;
  3437. ret = deflate(zstream, Z_FINISH);
  3438. if(ret != Z_STREAM_END)
  3439. {
  3440. spng__free(ctx, compressed_text);
  3441. return SPNG_EZLIB;
  3442. }
  3443. compressed_length = zstream->total_out;
  3444. length += compressed_length;
  3445. if(length < compressed_length) return SPNG_EOVERFLOW;
  3446. }
  3447. else
  3448. {
  3449. text_length = strlen(text->text);
  3450. length += text_length;
  3451. if(length < text_length) return SPNG_EOVERFLOW;
  3452. }
  3453. ret = write_header(ctx, text_chunk_type, length, &cdata);
  3454. if(ret)
  3455. {
  3456. spng__free(ctx, compressed_text);
  3457. return ret;
  3458. }
  3459. memcpy(cdata, text->keyword, keyword_len + 1);
  3460. cdata += keyword_len + 1;
  3461. if(text->type == SPNG_ITXT)
  3462. {
  3463. cdata[0] = text->compression_flag;
  3464. cdata[1] = 0; /* compression method */
  3465. cdata += 2;
  3466. memcpy(cdata, text->language_tag, language_tag_len + 1);
  3467. cdata += language_tag_len + 1;
  3468. memcpy(cdata, text->translated_keyword, translated_keyword_len + 1);
  3469. cdata += translated_keyword_len + 1;
  3470. }
  3471. else if(text->type == SPNG_ZTXT)
  3472. {
  3473. cdata[0] = 0; /* compression method */
  3474. cdata++;
  3475. }
  3476. if(text->compression_flag) memcpy(cdata, compressed_text, compressed_length);
  3477. else memcpy(cdata, text->text, text_length);
  3478. spng__free(ctx, compressed_text);
  3479. ret = finish_chunk(ctx);
  3480. if(ret) return ret;
  3481. }
  3482. }
  3483. if(ctx->stored.offs)
  3484. {
  3485. write_s32(data, ctx->offs.x);
  3486. write_s32(data + 4, ctx->offs.y);
  3487. data[8] = ctx->offs.unit_specifier;
  3488. ret = write_chunk(ctx, type_offs, data, 9);
  3489. if(ret) return ret;
  3490. }
  3491. if(ctx->stored.exif)
  3492. {
  3493. ret = write_chunk(ctx, type_exif, ctx->exif.data, ctx->exif.length);
  3494. if(ret) return ret;
  3495. }
  3496. ret = write_unknown_chunks(ctx, SPNG_AFTER_PLTE);
  3497. if(ret) return ret;
  3498. return 0;
  3499. }
  3500. static int write_chunks_after_idat(spng_ctx *ctx)
  3501. {
  3502. if(ctx == NULL) return SPNG_EINTERNAL;
  3503. int ret = write_unknown_chunks(ctx, SPNG_AFTER_IDAT);
  3504. if(ret) return ret;
  3505. return write_iend(ctx);
  3506. }
  3507. /* Compress and write scanline to IDAT stream */
  3508. static int write_idat_bytes(spng_ctx *ctx, const void *scanline, size_t len, int flush)
  3509. {
  3510. if(ctx == NULL || scanline == NULL) return SPNG_EINTERNAL;
  3511. if(len > UINT_MAX) return SPNG_EINTERNAL;
  3512. int ret = 0;
  3513. unsigned char *data = NULL;
  3514. z_stream *zstream = &ctx->zstream;
  3515. uint32_t idat_length = SPNG_WRITE_SIZE;
  3516. zstream->next_in = scanline;
  3517. zstream->avail_in = (uInt)len;
  3518. do
  3519. {
  3520. ret = deflate(zstream, flush);
  3521. if(zstream->avail_out == 0)
  3522. {
  3523. ret = finish_chunk(ctx);
  3524. if(ret) return encode_err(ctx, ret);
  3525. ret = write_header(ctx, type_idat, idat_length, &data);
  3526. if(ret) return encode_err(ctx, ret);
  3527. zstream->next_out = data;
  3528. zstream->avail_out = idat_length;
  3529. }
  3530. }while(zstream->avail_in);
  3531. if(ret != Z_OK) return SPNG_EZLIB;
  3532. return 0;
  3533. }
  3534. static int finish_idat(spng_ctx *ctx)
  3535. {
  3536. int ret = 0;
  3537. unsigned char *data = NULL;
  3538. z_stream *zstream = &ctx->zstream;
  3539. uint32_t idat_length = SPNG_WRITE_SIZE;
  3540. while(ret != Z_STREAM_END)
  3541. {
  3542. ret = deflate(zstream, Z_FINISH);
  3543. if(ret)
  3544. {
  3545. if(ret == Z_STREAM_END) break;
  3546. if(ret != Z_BUF_ERROR) return SPNG_EZLIB;
  3547. }
  3548. if(zstream->avail_out == 0)
  3549. {
  3550. ret = finish_chunk(ctx);
  3551. if(ret) return encode_err(ctx, ret);
  3552. ret = write_header(ctx, type_idat, idat_length, &data);
  3553. if(ret) return encode_err(ctx, ret);
  3554. zstream->next_out = data;
  3555. zstream->avail_out = idat_length;
  3556. }
  3557. }
  3558. uint32_t trimmed_length = idat_length - zstream->avail_out;
  3559. ret = trim_chunk(ctx, trimmed_length);
  3560. if(ret) return ret;
  3561. return finish_chunk(ctx);
  3562. }
  3563. static int encode_scanline(spng_ctx *ctx, const void *scanline, size_t len)
  3564. {
  3565. if(ctx == NULL || scanline == NULL) return SPNG_EINTERNAL;
  3566. int ret, pass = ctx->row_info.pass;
  3567. uint8_t filter = 0;
  3568. struct spng_row_info *ri = &ctx->row_info;
  3569. const struct spng_subimage *sub = ctx->subimage;
  3570. struct encode_flags f = ctx->encode_flags;
  3571. unsigned char *filtered_scanline = ctx->filtered_scanline;
  3572. size_t scanline_width = sub[pass].scanline_width;
  3573. if(len < scanline_width - 1) return SPNG_EINTERNAL;
  3574. /* encode_row() interlaces directly to ctx->scanline */
  3575. if(scanline != ctx->scanline) memcpy(ctx->scanline, scanline, scanline_width - 1);
  3576. if(f.to_bigendian) u16_row_to_bigendian(ctx->scanline, scanline_width - 1);
  3577. const int requires_previous = f.filter_choice & (SPNG_FILTER_CHOICE_UP | SPNG_FILTER_CHOICE_AVG | SPNG_FILTER_CHOICE_PAETH);
  3578. /* XXX: exclude 'requires_previous' filters by default for first scanline? */
  3579. if(!ri->scanline_idx && requires_previous)
  3580. {
  3581. /* prev_scanline is all zeros for the first scanline */
  3582. memset(ctx->prev_scanline, 0, scanline_width);
  3583. }
  3584. filter = get_best_filter(ctx->prev_scanline, ctx->scanline, scanline_width, ctx->bytes_per_pixel, f.filter_choice);
  3585. if(!filter) filtered_scanline = ctx->scanline;
  3586. filtered_scanline[-1] = filter;
  3587. if(filter)
  3588. {
  3589. ret = filter_scanline(filtered_scanline, ctx->prev_scanline, ctx->scanline, scanline_width, ctx->bytes_per_pixel, filter);
  3590. if(ret) return encode_err(ctx, ret);
  3591. }
  3592. ret = write_idat_bytes(ctx, filtered_scanline - 1, scanline_width, Z_NO_FLUSH);
  3593. if(ret) return encode_err(ctx, ret);
  3594. /* The previous scanline is always unfiltered */
  3595. void *t = ctx->prev_scanline;
  3596. ctx->prev_scanline = ctx->scanline;
  3597. ctx->scanline = t;
  3598. ret = update_row_info(ctx);
  3599. if(ret == SPNG_EOI)
  3600. {
  3601. int error = finish_idat(ctx);
  3602. if(error) encode_err(ctx, error);
  3603. if(f.finalize)
  3604. {
  3605. error = spng_encode_chunks(ctx);
  3606. if(error) return encode_err(ctx, error);
  3607. }
  3608. }
  3609. return ret;
  3610. }
  3611. static int encode_row(spng_ctx *ctx, const void *row, size_t len)
  3612. {
  3613. if(ctx == NULL || row == NULL) return SPNG_EINTERNAL;
  3614. const int pass = ctx->row_info.pass;
  3615. if(!ctx->ihdr.interlace_method || pass == 6) return encode_scanline(ctx, row, len);
  3616. uint32_t k;
  3617. const unsigned pixel_size = ctx->pixel_size;
  3618. const unsigned bit_depth = ctx->ihdr.bit_depth;
  3619. if(bit_depth < 8)
  3620. {
  3621. const unsigned samples_per_byte = 8 / bit_depth;
  3622. const uint8_t mask = (1 << bit_depth) - 1;
  3623. const unsigned initial_shift = 8 - bit_depth;
  3624. unsigned shift_amount = initial_shift;
  3625. unsigned char *scanline = ctx->scanline;
  3626. const unsigned char *row_uc = row;
  3627. uint8_t sample;
  3628. memset(scanline, 0, ctx->subimage[pass].scanline_width);
  3629. for(k=0; k < ctx->subimage[pass].width; k++)
  3630. {
  3631. size_t ioffset = adam7_x_start[pass] + k * adam7_x_delta[pass];
  3632. sample = row_uc[ioffset / samples_per_byte];
  3633. sample = sample >> (initial_shift - ioffset * bit_depth % 8);
  3634. sample = sample & mask;
  3635. sample = sample << shift_amount;
  3636. scanline[0] |= sample;
  3637. shift_amount -= bit_depth;
  3638. if(shift_amount > 7)
  3639. {
  3640. shift_amount = initial_shift;
  3641. scanline++;
  3642. }
  3643. }
  3644. return encode_scanline(ctx, ctx->scanline, len);
  3645. }
  3646. for(k=0; k < ctx->subimage[pass].width; k++)
  3647. {
  3648. size_t ioffset = (adam7_x_start[pass] + (size_t) k * adam7_x_delta[pass]) * pixel_size;
  3649. memcpy(ctx->scanline + k * pixel_size, (unsigned char*)row + ioffset, pixel_size);
  3650. }
  3651. return encode_scanline(ctx, ctx->scanline, len);
  3652. }
  3653. int spng_encode_scanline(spng_ctx *ctx, const void *scanline, size_t len)
  3654. {
  3655. if(ctx == NULL || scanline == NULL) return SPNG_EINVAL;
  3656. if(ctx->state >= SPNG_STATE_EOI) return SPNG_EOI;
  3657. if(len < (ctx->subimage[ctx->row_info.pass].scanline_width -1) ) return SPNG_EBUFSIZ;
  3658. return encode_scanline(ctx, scanline, len);
  3659. }
  3660. int spng_encode_row(spng_ctx *ctx, const void *row, size_t len)
  3661. {
  3662. if(ctx == NULL || row == NULL) return SPNG_EINVAL;
  3663. if(ctx->state >= SPNG_STATE_EOI) return SPNG_EOI;
  3664. if(len < ctx->image_width) return SPNG_EBUFSIZ;
  3665. return encode_row(ctx, row, len);
  3666. }
  3667. int spng_encode_chunks(spng_ctx *ctx)
  3668. {
  3669. if(ctx == NULL) return 1;
  3670. if(!ctx->state) return SPNG_EBADSTATE;
  3671. if(ctx->state < SPNG_STATE_OUTPUT) return SPNG_ENODST;
  3672. if(!ctx->encode_only) return SPNG_ECTXTYPE;
  3673. int ret = 0;
  3674. if(ctx->state < SPNG_STATE_FIRST_IDAT)
  3675. {
  3676. if(!ctx->stored.ihdr) return SPNG_ENOIHDR;
  3677. ret = write_chunks_before_idat(ctx);
  3678. if(ret) return encode_err(ctx, ret);
  3679. ctx->state = SPNG_STATE_FIRST_IDAT;
  3680. }
  3681. else if(ctx->state == SPNG_STATE_FIRST_IDAT)
  3682. {
  3683. return 0;
  3684. }
  3685. else if(ctx->state == SPNG_STATE_EOI)
  3686. {
  3687. ret = write_chunks_after_idat(ctx);
  3688. if(ret) return encode_err(ctx, ret);
  3689. ctx->state = SPNG_STATE_IEND;
  3690. }
  3691. else return SPNG_EOPSTATE;
  3692. return 0;
  3693. }
  3694. int spng_encode_image(spng_ctx *ctx, const void *img, size_t len, int fmt, int flags)
  3695. {
  3696. if(ctx == NULL) return 1;
  3697. if(!ctx->state) return SPNG_EBADSTATE;
  3698. if(!ctx->encode_only) return SPNG_ECTXTYPE;
  3699. if(!ctx->stored.ihdr) return SPNG_ENOIHDR;
  3700. if( !(fmt == SPNG_FMT_PNG || fmt == SPNG_FMT_RAW) ) return SPNG_EFMT;
  3701. int ret = 0;
  3702. const struct spng_ihdr *ihdr = &ctx->ihdr;
  3703. struct encode_flags *encode_flags = &ctx->encode_flags;
  3704. if(ihdr->color_type == SPNG_COLOR_TYPE_INDEXED && !ctx->stored.plte) return SPNG_ENOPLTE;
  3705. ret = calculate_image_width(ihdr, fmt, &ctx->image_width);
  3706. if(ret) return encode_err(ctx, ret);
  3707. if(ctx->image_width > SIZE_MAX / ihdr->height) ctx->image_size = 0; /* overflow */
  3708. else ctx->image_size = ctx->image_width * ihdr->height;
  3709. if( !(flags & SPNG_ENCODE_PROGRESSIVE) )
  3710. {
  3711. if(img == NULL) return 1;
  3712. if(!ctx->image_size) return SPNG_EOVERFLOW;
  3713. if(len != ctx->image_size) return SPNG_EBUFSIZ;
  3714. }
  3715. ret = spng_encode_chunks(ctx);
  3716. if(ret) return encode_err(ctx, ret);
  3717. ret = calculate_subimages(ctx);
  3718. if(ret) return encode_err(ctx, ret);
  3719. if(ihdr->bit_depth < 8) ctx->bytes_per_pixel = 1;
  3720. else ctx->bytes_per_pixel = num_channels(ihdr) * (ihdr->bit_depth / 8);
  3721. if(spng__optimize(SPNG_FILTER_CHOICE))
  3722. {
  3723. /* Filtering would make no difference */
  3724. if(!ctx->image_options.compression_level)
  3725. {
  3726. encode_flags->filter_choice = SPNG_DISABLE_FILTERING;
  3727. }
  3728. /* Palette indices and low bit-depth images do not benefit from filtering */
  3729. if(ihdr->color_type == SPNG_COLOR_TYPE_INDEXED || ihdr->bit_depth < 8)
  3730. {
  3731. encode_flags->filter_choice = SPNG_DISABLE_FILTERING;
  3732. }
  3733. }
  3734. /* This is technically the same as disabling filtering */
  3735. if(encode_flags->filter_choice == SPNG_FILTER_CHOICE_NONE)
  3736. {
  3737. encode_flags->filter_choice = SPNG_DISABLE_FILTERING;
  3738. }
  3739. if(!encode_flags->filter_choice && spng__optimize(SPNG_IMG_COMPRESSION_STRATEGY))
  3740. {
  3741. ctx->image_options.strategy = Z_DEFAULT_STRATEGY;
  3742. }
  3743. ret = spng__deflate_init(ctx, &ctx->image_options);
  3744. if(ret) return encode_err(ctx, ret);
  3745. size_t scanline_buf_size = ctx->subimage[ctx->widest_pass].scanline_width;
  3746. scanline_buf_size += 32;
  3747. if(scanline_buf_size < 32) return SPNG_EOVERFLOW;
  3748. ctx->scanline_buf = spng__malloc(ctx, scanline_buf_size);
  3749. ctx->prev_scanline_buf = spng__malloc(ctx, scanline_buf_size);
  3750. if(ctx->scanline_buf == NULL || ctx->prev_scanline_buf == NULL) return encode_err(ctx, SPNG_EMEM);
  3751. /* Maintain alignment for pixels, filter at [-1] */
  3752. ctx->scanline = ctx->scanline_buf + 16;
  3753. ctx->prev_scanline = ctx->prev_scanline_buf + 16;
  3754. if(encode_flags->filter_choice)
  3755. {
  3756. ctx->filtered_scanline_buf = spng__malloc(ctx, scanline_buf_size);
  3757. if(ctx->filtered_scanline_buf == NULL) return encode_err(ctx, SPNG_EMEM);
  3758. ctx->filtered_scanline = ctx->filtered_scanline_buf + 16;
  3759. }
  3760. struct spng_subimage *sub = ctx->subimage;
  3761. struct spng_row_info *ri = &ctx->row_info;
  3762. ctx->fmt = fmt;
  3763. z_stream *zstream = &ctx->zstream;
  3764. zstream->avail_out = SPNG_WRITE_SIZE;
  3765. ret = write_header(ctx, type_idat, zstream->avail_out, &zstream->next_out);
  3766. if(ret) return encode_err(ctx, ret);
  3767. if(ihdr->interlace_method) encode_flags->interlace = 1;
  3768. if(fmt & (SPNG_FMT_PNG | SPNG_FMT_RAW) ) encode_flags->same_layout = 1;
  3769. if(ihdr->bit_depth == 16 && fmt != SPNG_FMT_RAW) encode_flags->to_bigendian = 1;
  3770. if(flags & SPNG_ENCODE_FINALIZE) encode_flags->finalize = 1;
  3771. while(!sub[ri->pass].width || !sub[ri->pass].height) ri->pass++;
  3772. if(encode_flags->interlace) ri->row_num = adam7_y_start[ri->pass];
  3773. ctx->pixel_size = 4; /* SPNG_FMT_RGBA8 */
  3774. if(fmt == SPNG_FMT_RGBA16) ctx->pixel_size = 8;
  3775. else if(fmt == SPNG_FMT_RGB8) ctx->pixel_size = 3;
  3776. else if(fmt == SPNG_FMT_G8) ctx->pixel_size = 1;
  3777. else if(fmt == SPNG_FMT_GA8) ctx->pixel_size = 2;
  3778. else if(fmt & (SPNG_FMT_PNG | SPNG_FMT_RAW)) ctx->pixel_size = ctx->bytes_per_pixel;
  3779. ctx->state = SPNG_STATE_ENCODE_INIT;
  3780. if(flags & SPNG_ENCODE_PROGRESSIVE)
  3781. {
  3782. encode_flags->progressive = 1;
  3783. return 0;
  3784. }
  3785. do
  3786. {
  3787. size_t ioffset = ri->row_num * ctx->image_width;
  3788. ret = encode_row(ctx, (unsigned char*)img + ioffset, ctx->image_width);
  3789. }while(!ret);
  3790. if(ret != SPNG_EOI) return encode_err(ctx, ret);
  3791. return 0;
  3792. }
  3793. spng_ctx *spng_ctx_new(int flags)
  3794. {
  3795. struct spng_alloc alloc =
  3796. {
  3797. .malloc_fn = malloc,
  3798. .realloc_fn = realloc,
  3799. .calloc_fn = calloc,
  3800. .free_fn = free
  3801. };
  3802. return spng_ctx_new2(&alloc, flags);
  3803. }
  3804. spng_ctx *spng_ctx_new2(struct spng_alloc *alloc, int flags)
  3805. {
  3806. if(alloc == NULL) return NULL;
  3807. if(flags != (flags & SPNG__CTX_FLAGS_ALL)) return NULL;
  3808. if(alloc->malloc_fn == NULL) return NULL;
  3809. if(alloc->realloc_fn == NULL) return NULL;
  3810. if(alloc->calloc_fn == NULL) return NULL;
  3811. if(alloc->free_fn == NULL) return NULL;
  3812. spng_ctx *ctx = alloc->calloc_fn(1, sizeof(spng_ctx));
  3813. if(ctx == NULL) return NULL;
  3814. ctx->alloc = *alloc;
  3815. ctx->max_width = spng_u32max;
  3816. ctx->max_height = spng_u32max;
  3817. ctx->max_chunk_size = spng_u32max;
  3818. ctx->chunk_cache_limit = SIZE_MAX;
  3819. ctx->chunk_count_limit = SPNG_MAX_CHUNK_COUNT;
  3820. ctx->state = SPNG_STATE_INIT;
  3821. ctx->crc_action_critical = SPNG_CRC_ERROR;
  3822. ctx->crc_action_ancillary = SPNG_CRC_DISCARD;
  3823. const struct spng__zlib_options image_defaults =
  3824. {
  3825. .compression_level = Z_DEFAULT_COMPRESSION,
  3826. .window_bits = 15,
  3827. .mem_level = 8,
  3828. .strategy = Z_FILTERED,
  3829. .data_type = 0 /* Z_BINARY */
  3830. };
  3831. const struct spng__zlib_options text_defaults =
  3832. {
  3833. .compression_level = Z_DEFAULT_COMPRESSION,
  3834. .window_bits = 15,
  3835. .mem_level = 8,
  3836. .strategy = Z_DEFAULT_STRATEGY,
  3837. .data_type = 1 /* Z_TEXT */
  3838. };
  3839. ctx->image_options = image_defaults;
  3840. ctx->text_options = text_defaults;
  3841. ctx->optimize_option = ~0;
  3842. ctx->encode_flags.filter_choice = SPNG_FILTER_CHOICE_ALL;
  3843. ctx->flags = flags;
  3844. if(flags & SPNG_CTX_ENCODER) ctx->encode_only = 1;
  3845. return ctx;
  3846. }
  3847. void spng_ctx_free(spng_ctx *ctx)
  3848. {
  3849. if(ctx == NULL) return;
  3850. if(ctx->streaming && ctx->stream_buf != NULL) spng__free(ctx, ctx->stream_buf);
  3851. if(!ctx->user.exif) spng__free(ctx, ctx->exif.data);
  3852. if(!ctx->user.iccp) spng__free(ctx, ctx->iccp.profile);
  3853. uint32_t i;
  3854. if(ctx->splt_list != NULL && !ctx->user.splt)
  3855. {
  3856. for(i=0; i < ctx->n_splt; i++)
  3857. {
  3858. spng__free(ctx, ctx->splt_list[i].entries);
  3859. }
  3860. spng__free(ctx, ctx->splt_list);
  3861. }
  3862. if(ctx->text_list != NULL)
  3863. {
  3864. for(i=0; i< ctx->n_text; i++)
  3865. {
  3866. if(ctx->user.text) break;
  3867. spng__free(ctx, ctx->text_list[i].keyword);
  3868. if(ctx->text_list[i].compression_flag) spng__free(ctx, ctx->text_list[i].text);
  3869. }
  3870. spng__free(ctx, ctx->text_list);
  3871. }
  3872. if(ctx->chunk_list != NULL && !ctx->user.unknown)
  3873. {
  3874. for(i=0; i< ctx->n_chunks; i++)
  3875. {
  3876. spng__free(ctx, ctx->chunk_list[i].data);
  3877. }
  3878. spng__free(ctx, ctx->chunk_list);
  3879. }
  3880. if(ctx->deflate) deflateEnd(&ctx->zstream);
  3881. else inflateEnd(&ctx->zstream);
  3882. if(!ctx->user_owns_out_png) spng__free(ctx, ctx->out_png);
  3883. spng__free(ctx, ctx->gamma_lut16);
  3884. spng__free(ctx, ctx->row_buf);
  3885. spng__free(ctx, ctx->scanline_buf);
  3886. spng__free(ctx, ctx->prev_scanline_buf);
  3887. spng__free(ctx, ctx->filtered_scanline_buf);
  3888. spng_free_fn *free_fn = ctx->alloc.free_fn;
  3889. memset(ctx, 0, sizeof(spng_ctx));
  3890. free_fn(ctx);
  3891. }
  3892. static int buffer_read_fn(spng_ctx *ctx, void *user, void *data, size_t n)
  3893. {
  3894. if(n > ctx->bytes_left) return SPNG_IO_EOF;
  3895. (void)user;
  3896. (void)data;
  3897. ctx->data = ctx->data + ctx->last_read_size;
  3898. ctx->last_read_size = n;
  3899. ctx->bytes_left -= n;
  3900. return 0;
  3901. }
  3902. static int file_read_fn(spng_ctx *ctx, void *user, void *data, size_t n)
  3903. {
  3904. FILE *file = user;
  3905. (void)ctx;
  3906. if(fread(data, n, 1, file) != 1)
  3907. {
  3908. if(feof(file)) return SPNG_IO_EOF;
  3909. else return SPNG_IO_ERROR;
  3910. }
  3911. return 0;
  3912. }
  3913. static int file_write_fn(spng_ctx *ctx, void *user, void *data, size_t n)
  3914. {
  3915. FILE *file = user;
  3916. (void)ctx;
  3917. if(fwrite(data, n, 1, file) != 1) return SPNG_IO_ERROR;
  3918. return 0;
  3919. }
  3920. int spng_set_png_buffer(spng_ctx *ctx, const void *buf, size_t size)
  3921. {
  3922. if(ctx == NULL || buf == NULL) return 1;
  3923. if(!ctx->state) return SPNG_EBADSTATE;
  3924. if(ctx->encode_only) return SPNG_ECTXTYPE; /* not supported */
  3925. if(ctx->data != NULL) return SPNG_EBUF_SET;
  3926. ctx->data = buf;
  3927. ctx->png_base = buf;
  3928. ctx->data_size = size;
  3929. ctx->bytes_left = size;
  3930. ctx->read_fn = buffer_read_fn;
  3931. ctx->state = SPNG_STATE_INPUT;
  3932. return 0;
  3933. }
  3934. int spng_set_png_stream(spng_ctx *ctx, spng_rw_fn *rw_func, void *user)
  3935. {
  3936. if(ctx == NULL || rw_func == NULL) return 1;
  3937. if(!ctx->state) return SPNG_EBADSTATE;
  3938. /* SPNG_STATE_OUTPUT shares the same value */
  3939. if(ctx->state >= SPNG_STATE_INPUT) return SPNG_EBUF_SET;
  3940. if(ctx->encode_only)
  3941. {
  3942. if(ctx->out_png != NULL) return SPNG_EBUF_SET;
  3943. ctx->write_fn = rw_func;
  3944. ctx->write_ptr = ctx->stream_buf;
  3945. ctx->state = SPNG_STATE_OUTPUT;
  3946. }
  3947. else
  3948. {
  3949. ctx->stream_buf = spng__malloc(ctx, SPNG_READ_SIZE);
  3950. if(ctx->stream_buf == NULL) return SPNG_EMEM;
  3951. ctx->read_fn = rw_func;
  3952. ctx->data = ctx->stream_buf;
  3953. ctx->data_size = SPNG_READ_SIZE;
  3954. ctx->state = SPNG_STATE_INPUT;
  3955. }
  3956. ctx->stream_user_ptr = user;
  3957. ctx->streaming = 1;
  3958. return 0;
  3959. }
  3960. int spng_set_png_file(spng_ctx *ctx, FILE *file)
  3961. {
  3962. if(file == NULL) return 1;
  3963. if(ctx->encode_only) return spng_set_png_stream(ctx, file_write_fn, file);
  3964. return spng_set_png_stream(ctx, file_read_fn, file);
  3965. }
  3966. void *spng_get_png_buffer(spng_ctx *ctx, size_t *len, int *error)
  3967. {
  3968. int tmp = 0;
  3969. error = error ? error : &tmp;
  3970. *error = 0;
  3971. if(ctx == NULL || !len) *error = SPNG_EINVAL;
  3972. if(*error) return NULL;
  3973. if(!ctx->encode_only) *error = SPNG_ECTXTYPE;
  3974. else if(!ctx->state) *error = SPNG_EBADSTATE;
  3975. else if(!ctx->internal_buffer) *error = SPNG_EOPSTATE;
  3976. else if(ctx->state < SPNG_STATE_EOI) *error = SPNG_EOPSTATE;
  3977. else if(ctx->state != SPNG_STATE_IEND) *error = SPNG_ENOTFINAL;
  3978. if(*error) return NULL;
  3979. ctx->user_owns_out_png = 1;
  3980. *len = ctx->bytes_encoded;
  3981. return ctx->out_png;
  3982. }
  3983. int spng_set_image_limits(spng_ctx *ctx, uint32_t width, uint32_t height)
  3984. {
  3985. if(ctx == NULL) return 1;
  3986. if(width > spng_u32max || height > spng_u32max) return 1;
  3987. ctx->max_width = width;
  3988. ctx->max_height = height;
  3989. return 0;
  3990. }
  3991. int spng_get_image_limits(spng_ctx *ctx, uint32_t *width, uint32_t *height)
  3992. {
  3993. if(ctx == NULL || width == NULL || height == NULL) return 1;
  3994. *width = ctx->max_width;
  3995. *height = ctx->max_height;
  3996. return 0;
  3997. }
  3998. int spng_set_chunk_limits(spng_ctx *ctx, size_t chunk_size, size_t cache_limit)
  3999. {
  4000. if(ctx == NULL || chunk_size > spng_u32max || chunk_size > cache_limit) return 1;
  4001. ctx->max_chunk_size = chunk_size;
  4002. ctx->chunk_cache_limit = cache_limit;
  4003. return 0;
  4004. }
  4005. int spng_get_chunk_limits(spng_ctx *ctx, size_t *chunk_size, size_t *cache_limit)
  4006. {
  4007. if(ctx == NULL || chunk_size == NULL || cache_limit == NULL) return 1;
  4008. *chunk_size = ctx->max_chunk_size;
  4009. *cache_limit = ctx->chunk_cache_limit;
  4010. return 0;
  4011. }
  4012. int spng_set_crc_action(spng_ctx *ctx, int critical, int ancillary)
  4013. {
  4014. if(ctx == NULL) return 1;
  4015. if(ctx->encode_only) return SPNG_ECTXTYPE;
  4016. if(critical > 2 || critical < 0) return 1;
  4017. if(ancillary > 2 || ancillary < 0) return 1;
  4018. if(critical == SPNG_CRC_DISCARD) return 1;
  4019. ctx->crc_action_critical = critical;
  4020. ctx->crc_action_ancillary = ancillary;
  4021. return 0;
  4022. }
  4023. int spng_set_option(spng_ctx *ctx, enum spng_option option, int value)
  4024. {
  4025. if(ctx == NULL) return 1;
  4026. if(!ctx->state) return SPNG_EBADSTATE;
  4027. switch(option)
  4028. {
  4029. case SPNG_KEEP_UNKNOWN_CHUNKS:
  4030. {
  4031. ctx->keep_unknown = value ? 1 : 0;
  4032. break;
  4033. }
  4034. case SPNG_IMG_COMPRESSION_LEVEL:
  4035. {
  4036. ctx->image_options.compression_level = value;
  4037. break;
  4038. }
  4039. case SPNG_IMG_WINDOW_BITS:
  4040. {
  4041. ctx->image_options.window_bits = value;
  4042. break;
  4043. }
  4044. case SPNG_IMG_MEM_LEVEL:
  4045. {
  4046. ctx->image_options.mem_level = value;
  4047. break;
  4048. }
  4049. case SPNG_IMG_COMPRESSION_STRATEGY:
  4050. {
  4051. ctx->image_options.strategy = value;
  4052. break;
  4053. }
  4054. case SPNG_TEXT_COMPRESSION_LEVEL:
  4055. {
  4056. ctx->text_options.compression_level = value;
  4057. break;
  4058. }
  4059. case SPNG_TEXT_WINDOW_BITS:
  4060. {
  4061. ctx->text_options.window_bits = value;
  4062. break;
  4063. }
  4064. case SPNG_TEXT_MEM_LEVEL:
  4065. {
  4066. ctx->text_options.mem_level = value;
  4067. break;
  4068. }
  4069. case SPNG_TEXT_COMPRESSION_STRATEGY:
  4070. {
  4071. ctx->text_options.strategy = value;
  4072. break;
  4073. }
  4074. case SPNG_FILTER_CHOICE:
  4075. {
  4076. if(value & ~SPNG_FILTER_CHOICE_ALL) return 1;
  4077. ctx->encode_flags.filter_choice = value;
  4078. break;
  4079. }
  4080. case SPNG_CHUNK_COUNT_LIMIT:
  4081. {
  4082. if(value < 0) return 1;
  4083. if(value > (int)ctx->chunk_count_total) return 1;
  4084. ctx->chunk_count_limit = value;
  4085. break;
  4086. }
  4087. case SPNG_ENCODE_TO_BUFFER:
  4088. {
  4089. if(value < 0) return 1;
  4090. if(!ctx->encode_only) return SPNG_ECTXTYPE;
  4091. if(ctx->state >= SPNG_STATE_OUTPUT) return SPNG_EOPSTATE;
  4092. if(!value) break;
  4093. ctx->internal_buffer = 1;
  4094. ctx->state = SPNG_STATE_OUTPUT;
  4095. break;
  4096. }
  4097. default: return 1;
  4098. }
  4099. /* Option can no longer be overriden by the library */
  4100. if(option < 32) ctx->optimize_option &= ~(1 << option);
  4101. return 0;
  4102. }
  4103. int spng_get_option(spng_ctx *ctx, enum spng_option option, int *value)
  4104. {
  4105. if(ctx == NULL || value == NULL) return 1;
  4106. if(!ctx->state) return SPNG_EBADSTATE;
  4107. switch(option)
  4108. {
  4109. case SPNG_KEEP_UNKNOWN_CHUNKS:
  4110. {
  4111. *value = ctx->keep_unknown;
  4112. break;
  4113. }
  4114. case SPNG_IMG_COMPRESSION_LEVEL:
  4115. {
  4116. *value = ctx->image_options.compression_level;
  4117. break;
  4118. }
  4119. case SPNG_IMG_WINDOW_BITS:
  4120. {
  4121. *value = ctx->image_options.window_bits;
  4122. break;
  4123. }
  4124. case SPNG_IMG_MEM_LEVEL:
  4125. {
  4126. *value = ctx->image_options.mem_level;
  4127. break;
  4128. }
  4129. case SPNG_IMG_COMPRESSION_STRATEGY:
  4130. {
  4131. *value = ctx->image_options.strategy;
  4132. break;
  4133. }
  4134. case SPNG_TEXT_COMPRESSION_LEVEL:
  4135. {
  4136. *value = ctx->text_options.compression_level;
  4137. break;
  4138. }
  4139. case SPNG_TEXT_WINDOW_BITS:
  4140. {
  4141. *value = ctx->text_options.window_bits;
  4142. break;
  4143. }
  4144. case SPNG_TEXT_MEM_LEVEL:
  4145. {
  4146. *value = ctx->text_options.mem_level;
  4147. break;
  4148. }
  4149. case SPNG_TEXT_COMPRESSION_STRATEGY:
  4150. {
  4151. *value = ctx->text_options.strategy;
  4152. break;
  4153. }
  4154. case SPNG_FILTER_CHOICE:
  4155. {
  4156. *value = ctx->encode_flags.filter_choice;
  4157. break;
  4158. }
  4159. case SPNG_CHUNK_COUNT_LIMIT:
  4160. {
  4161. *value = ctx->chunk_count_limit;
  4162. break;
  4163. }
  4164. case SPNG_ENCODE_TO_BUFFER:
  4165. {
  4166. if(ctx->internal_buffer) *value = 1;
  4167. else *value = 0;
  4168. break;
  4169. }
  4170. default: return 1;
  4171. }
  4172. return 0;
  4173. }
  4174. int spng_decoded_image_size(spng_ctx *ctx, int fmt, size_t *len)
  4175. {
  4176. if(ctx == NULL || len == NULL) return 1;
  4177. int ret = read_chunks(ctx, 1);
  4178. if(ret) return ret;
  4179. ret = check_decode_fmt(&ctx->ihdr, fmt);
  4180. if(ret) return ret;
  4181. return calculate_image_size(&ctx->ihdr, fmt, len);
  4182. }
  4183. int spng_get_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr)
  4184. {
  4185. if(ctx == NULL) return 1;
  4186. int ret = read_chunks(ctx, 1);
  4187. if(ret) return ret;
  4188. if(ihdr == NULL) return 1;
  4189. *ihdr = ctx->ihdr;
  4190. return 0;
  4191. }
  4192. int spng_get_plte(spng_ctx *ctx, struct spng_plte *plte)
  4193. {
  4194. SPNG_GET_CHUNK_BOILERPLATE(plte);
  4195. *plte = ctx->plte;
  4196. return 0;
  4197. }
  4198. int spng_get_trns(spng_ctx *ctx, struct spng_trns *trns)
  4199. {
  4200. SPNG_GET_CHUNK_BOILERPLATE(trns);
  4201. *trns = ctx->trns;
  4202. return 0;
  4203. }
  4204. int spng_get_chrm(spng_ctx *ctx, struct spng_chrm *chrm)
  4205. {
  4206. SPNG_GET_CHUNK_BOILERPLATE(chrm);
  4207. chrm->white_point_x = (double)ctx->chrm_int.white_point_x / 100000.0;
  4208. chrm->white_point_y = (double)ctx->chrm_int.white_point_y / 100000.0;
  4209. chrm->red_x = (double)ctx->chrm_int.red_x / 100000.0;
  4210. chrm->red_y = (double)ctx->chrm_int.red_y / 100000.0;
  4211. chrm->blue_y = (double)ctx->chrm_int.blue_y / 100000.0;
  4212. chrm->blue_x = (double)ctx->chrm_int.blue_x / 100000.0;
  4213. chrm->green_x = (double)ctx->chrm_int.green_x / 100000.0;
  4214. chrm->green_y = (double)ctx->chrm_int.green_y / 100000.0;
  4215. return 0;
  4216. }
  4217. int spng_get_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm)
  4218. {
  4219. SPNG_GET_CHUNK_BOILERPLATE(chrm);
  4220. *chrm = ctx->chrm_int;
  4221. return 0;
  4222. }
  4223. int spng_get_gama(spng_ctx *ctx, double *gamma)
  4224. {
  4225. double *gama = gamma;
  4226. SPNG_GET_CHUNK_BOILERPLATE(gama);
  4227. *gama = (double)ctx->gama / 100000.0;
  4228. return 0;
  4229. }
  4230. int spng_get_gama_int(spng_ctx *ctx, uint32_t *gama_int)
  4231. {
  4232. uint32_t *gama = gama_int;
  4233. SPNG_GET_CHUNK_BOILERPLATE(gama);
  4234. *gama_int = ctx->gama;
  4235. return 0;
  4236. }
  4237. int spng_get_iccp(spng_ctx *ctx, struct spng_iccp *iccp)
  4238. {
  4239. SPNG_GET_CHUNK_BOILERPLATE(iccp);
  4240. *iccp = ctx->iccp;
  4241. return 0;
  4242. }
  4243. int spng_get_sbit(spng_ctx *ctx, struct spng_sbit *sbit)
  4244. {
  4245. SPNG_GET_CHUNK_BOILERPLATE(sbit);
  4246. *sbit = ctx->sbit;
  4247. return 0;
  4248. }
  4249. int spng_get_srgb(spng_ctx *ctx, uint8_t *rendering_intent)
  4250. {
  4251. uint8_t *srgb = rendering_intent;
  4252. SPNG_GET_CHUNK_BOILERPLATE(srgb);
  4253. *srgb = ctx->srgb_rendering_intent;
  4254. return 0;
  4255. }
  4256. int spng_get_text(spng_ctx *ctx, struct spng_text *text, uint32_t *n_text)
  4257. {
  4258. if(ctx == NULL) return 1;
  4259. int ret = read_chunks(ctx, 0);
  4260. if(ret) return ret;
  4261. if(!ctx->stored.text) return SPNG_ECHUNKAVAIL;
  4262. if(n_text == NULL) return 1;
  4263. if(text == NULL)
  4264. {
  4265. *n_text = ctx->n_text;
  4266. return 0;
  4267. }
  4268. if(*n_text < ctx->n_text) return 1;
  4269. uint32_t i;
  4270. for(i=0; i< ctx->n_text; i++)
  4271. {
  4272. text[i].type = ctx->text_list[i].type;
  4273. memcpy(&text[i].keyword, ctx->text_list[i].keyword, strlen(ctx->text_list[i].keyword) + 1);
  4274. text[i].compression_method = 0;
  4275. text[i].compression_flag = ctx->text_list[i].compression_flag;
  4276. text[i].language_tag = ctx->text_list[i].language_tag;
  4277. text[i].translated_keyword = ctx->text_list[i].translated_keyword;
  4278. text[i].length = ctx->text_list[i].text_length;
  4279. text[i].text = ctx->text_list[i].text;
  4280. }
  4281. return ret;
  4282. }
  4283. int spng_get_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd)
  4284. {
  4285. SPNG_GET_CHUNK_BOILERPLATE(bkgd);
  4286. *bkgd = ctx->bkgd;
  4287. return 0;
  4288. }
  4289. int spng_get_hist(spng_ctx *ctx, struct spng_hist *hist)
  4290. {
  4291. SPNG_GET_CHUNK_BOILERPLATE(hist);
  4292. *hist = ctx->hist;
  4293. return 0;
  4294. }
  4295. int spng_get_phys(spng_ctx *ctx, struct spng_phys *phys)
  4296. {
  4297. SPNG_GET_CHUNK_BOILERPLATE(phys);
  4298. *phys = ctx->phys;
  4299. return 0;
  4300. }
  4301. int spng_get_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t *n_splt)
  4302. {
  4303. if(ctx == NULL) return 1;
  4304. int ret = read_chunks(ctx, 0);
  4305. if(ret) return ret;
  4306. if(!ctx->stored.splt) return SPNG_ECHUNKAVAIL;
  4307. if(n_splt == NULL) return 1;
  4308. if(splt == NULL)
  4309. {
  4310. *n_splt = ctx->n_splt;
  4311. return 0;
  4312. }
  4313. if(*n_splt < ctx->n_splt) return 1;
  4314. memcpy(splt, ctx->splt_list, ctx->n_splt * sizeof(struct spng_splt));
  4315. return 0;
  4316. }
  4317. int spng_get_time(spng_ctx *ctx, struct spng_time *time)
  4318. {
  4319. SPNG_GET_CHUNK_BOILERPLATE(time);
  4320. *time = ctx->time;
  4321. return 0;
  4322. }
  4323. int spng_get_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t *n_chunks)
  4324. {
  4325. if(ctx == NULL) return 1;
  4326. int ret = read_chunks(ctx, 0);
  4327. if(ret) return ret;
  4328. if(!ctx->stored.unknown) return SPNG_ECHUNKAVAIL;
  4329. if(n_chunks == NULL) return 1;
  4330. if(chunks == NULL)
  4331. {
  4332. *n_chunks = ctx->n_chunks;
  4333. return 0;
  4334. }
  4335. if(*n_chunks < ctx->n_chunks) return 1;
  4336. memcpy(chunks, ctx->chunk_list, sizeof(struct spng_unknown_chunk));
  4337. return 0;
  4338. }
  4339. int spng_get_offs(spng_ctx *ctx, struct spng_offs *offs)
  4340. {
  4341. SPNG_GET_CHUNK_BOILERPLATE(offs);
  4342. *offs = ctx->offs;
  4343. return 0;
  4344. }
  4345. int spng_get_exif(spng_ctx *ctx, struct spng_exif *exif)
  4346. {
  4347. SPNG_GET_CHUNK_BOILERPLATE(exif);
  4348. *exif = ctx->exif;
  4349. return 0;
  4350. }
  4351. int spng_set_ihdr(spng_ctx *ctx, struct spng_ihdr *ihdr)
  4352. {
  4353. SPNG_SET_CHUNK_BOILERPLATE(ihdr);
  4354. if(ctx->stored.ihdr) return 1;
  4355. ret = check_ihdr(ihdr, ctx->max_width, ctx->max_height);
  4356. if(ret) return ret;
  4357. ctx->ihdr = *ihdr;
  4358. ctx->stored.ihdr = 1;
  4359. ctx->user.ihdr = 1;
  4360. return 0;
  4361. }
  4362. int spng_set_plte(spng_ctx *ctx, struct spng_plte *plte)
  4363. {
  4364. SPNG_SET_CHUNK_BOILERPLATE(plte);
  4365. if(!ctx->stored.ihdr) return 1;
  4366. if(check_plte(plte, &ctx->ihdr)) return 1;
  4367. ctx->plte.n_entries = plte->n_entries;
  4368. memcpy(ctx->plte.entries, plte->entries, plte->n_entries * sizeof(struct spng_plte_entry));
  4369. ctx->stored.plte = 1;
  4370. ctx->user.plte = 1;
  4371. return 0;
  4372. }
  4373. int spng_set_trns(spng_ctx *ctx, struct spng_trns *trns)
  4374. {
  4375. SPNG_SET_CHUNK_BOILERPLATE(trns);
  4376. if(!ctx->stored.ihdr) return SPNG_ENOIHDR;
  4377. if(ctx->ihdr.color_type == SPNG_COLOR_TYPE_GRAYSCALE)
  4378. {
  4379. ctx->trns.gray = trns->gray;
  4380. }
  4381. else if(ctx->ihdr.color_type == SPNG_COLOR_TYPE_TRUECOLOR)
  4382. {
  4383. ctx->trns.red = trns->red;
  4384. ctx->trns.green = trns->green;
  4385. ctx->trns.blue = trns->blue;
  4386. }
  4387. else if(ctx->ihdr.color_type == SPNG_COLOR_TYPE_INDEXED)
  4388. {
  4389. if(!ctx->stored.plte) return SPNG_ETRNS_NO_PLTE;
  4390. if(trns->n_type3_entries > ctx->plte.n_entries) return 1;
  4391. ctx->trns.n_type3_entries = trns->n_type3_entries;
  4392. memcpy(ctx->trns.type3_alpha, trns->type3_alpha, trns->n_type3_entries);
  4393. }
  4394. else return SPNG_ETRNS_COLOR_TYPE;
  4395. ctx->stored.trns = 1;
  4396. ctx->user.trns = 1;
  4397. return 0;
  4398. }
  4399. int spng_set_chrm(spng_ctx *ctx, struct spng_chrm *chrm)
  4400. {
  4401. SPNG_SET_CHUNK_BOILERPLATE(chrm);
  4402. struct spng_chrm_int chrm_int;
  4403. chrm_int.white_point_x = (uint32_t)(chrm->white_point_x * 100000.0);
  4404. chrm_int.white_point_y = (uint32_t)(chrm->white_point_y * 100000.0);
  4405. chrm_int.red_x = (uint32_t)(chrm->red_x * 100000.0);
  4406. chrm_int.red_y = (uint32_t)(chrm->red_y * 100000.0);
  4407. chrm_int.green_x = (uint32_t)(chrm->green_x * 100000.0);
  4408. chrm_int.green_y = (uint32_t)(chrm->green_y * 100000.0);
  4409. chrm_int.blue_x = (uint32_t)(chrm->blue_x * 100000.0);
  4410. chrm_int.blue_y = (uint32_t)(chrm->blue_y * 100000.0);
  4411. if(check_chrm_int(&chrm_int)) return SPNG_ECHRM;
  4412. ctx->chrm_int = chrm_int;
  4413. ctx->stored.chrm = 1;
  4414. ctx->user.chrm = 1;
  4415. return 0;
  4416. }
  4417. int spng_set_chrm_int(spng_ctx *ctx, struct spng_chrm_int *chrm_int)
  4418. {
  4419. SPNG_SET_CHUNK_BOILERPLATE(chrm_int);
  4420. if(check_chrm_int(chrm_int)) return SPNG_ECHRM;
  4421. ctx->chrm_int = *chrm_int;
  4422. ctx->stored.chrm = 1;
  4423. ctx->user.chrm = 1;
  4424. return 0;
  4425. }
  4426. int spng_set_gama(spng_ctx *ctx, double gamma)
  4427. {
  4428. SPNG_SET_CHUNK_BOILERPLATE(ctx);
  4429. uint32_t gama = gamma * 100000.0;
  4430. if(!gama) return 1;
  4431. if(gama > spng_u32max) return 1;
  4432. ctx->gama = gama;
  4433. ctx->stored.gama = 1;
  4434. ctx->user.gama = 1;
  4435. return 0;
  4436. }
  4437. int spng_set_gama_int(spng_ctx *ctx, uint32_t gamma)
  4438. {
  4439. SPNG_SET_CHUNK_BOILERPLATE(ctx);
  4440. if(!gamma) return 1;
  4441. if(gamma > spng_u32max) return 1;
  4442. ctx->gama = gamma;
  4443. ctx->stored.gama = 1;
  4444. ctx->user.gama = 1;
  4445. return 0;
  4446. }
  4447. int spng_set_iccp(spng_ctx *ctx, struct spng_iccp *iccp)
  4448. {
  4449. SPNG_SET_CHUNK_BOILERPLATE(iccp);
  4450. if(check_png_keyword(iccp->profile_name)) return SPNG_EICCP_NAME;
  4451. if(!iccp->profile_len) return SPNG_ECHUNK_SIZE;
  4452. if(iccp->profile_len > spng_u32max) return SPNG_ECHUNK_STDLEN;
  4453. if(ctx->iccp.profile && !ctx->user.iccp) spng__free(ctx, ctx->iccp.profile);
  4454. ctx->iccp = *iccp;
  4455. ctx->stored.iccp = 1;
  4456. ctx->user.iccp = 1;
  4457. return 0;
  4458. }
  4459. int spng_set_sbit(spng_ctx *ctx, struct spng_sbit *sbit)
  4460. {
  4461. SPNG_SET_CHUNK_BOILERPLATE(sbit);
  4462. if(check_sbit(sbit, &ctx->ihdr)) return 1;
  4463. if(!ctx->stored.ihdr) return 1;
  4464. ctx->sbit = *sbit;
  4465. ctx->stored.sbit = 1;
  4466. ctx->user.sbit = 1;
  4467. return 0;
  4468. }
  4469. int spng_set_srgb(spng_ctx *ctx, uint8_t rendering_intent)
  4470. {
  4471. SPNG_SET_CHUNK_BOILERPLATE(ctx);
  4472. if(rendering_intent > 3) return 1;
  4473. ctx->srgb_rendering_intent = rendering_intent;
  4474. ctx->stored.srgb = 1;
  4475. ctx->user.srgb = 1;
  4476. return 0;
  4477. }
  4478. int spng_set_text(spng_ctx *ctx, struct spng_text *text, uint32_t n_text)
  4479. {
  4480. if(!n_text) return 1;
  4481. SPNG_SET_CHUNK_BOILERPLATE(text);
  4482. uint32_t i;
  4483. for(i=0; i < n_text; i++)
  4484. {
  4485. if(check_png_keyword(text[i].keyword)) return SPNG_ETEXT_KEYWORD;
  4486. if(!text[i].length) return 1;
  4487. if(text[i].length > UINT_MAX) return 1;
  4488. if(text[i].text == NULL) return 1;
  4489. if(text[i].type == SPNG_TEXT)
  4490. {
  4491. if(ctx->strict && check_png_text(text[i].text, text[i].length)) return 1;
  4492. }
  4493. else if(text[i].type == SPNG_ZTXT)
  4494. {
  4495. if(ctx->strict && check_png_text(text[i].text, text[i].length)) return 1;
  4496. if(text[i].compression_method != 0) return SPNG_EZTXT_COMPRESSION_METHOD;
  4497. }
  4498. else if(text[i].type == SPNG_ITXT)
  4499. {
  4500. if(text[i].compression_flag > 1) return SPNG_EITXT_COMPRESSION_FLAG;
  4501. if(text[i].compression_method != 0) return SPNG_EITXT_COMPRESSION_METHOD;
  4502. if(text[i].language_tag == NULL) return SPNG_EITXT_LANG_TAG;
  4503. if(text[i].translated_keyword == NULL) return SPNG_EITXT_TRANSLATED_KEY;
  4504. }
  4505. else return 1;
  4506. }
  4507. struct spng_text2 *text_list = spng__calloc(ctx, sizeof(struct spng_text2), n_text);
  4508. if(!text_list) return SPNG_EMEM;
  4509. if(ctx->text_list != NULL)
  4510. {
  4511. for(i=0; i < ctx->n_text; i++)
  4512. {
  4513. if(ctx->user.text) break;
  4514. spng__free(ctx, ctx->text_list[i].keyword);
  4515. if(ctx->text_list[i].compression_flag) spng__free(ctx, ctx->text_list[i].text);
  4516. }
  4517. spng__free(ctx, ctx->text_list);
  4518. }
  4519. for(i=0; i < n_text; i++)
  4520. {
  4521. text_list[i].type = text[i].type;
  4522. /* Prevent issues with spng_text.keyword[80] going out of scope */
  4523. text_list[i].keyword = text_list[i].user_keyword_storage;
  4524. memcpy(text_list[i].user_keyword_storage, text[i].keyword, strlen(text[i].keyword));
  4525. text_list[i].text = text[i].text;
  4526. text_list[i].text_length = text[i].length;
  4527. if(text[i].type == SPNG_ZTXT)
  4528. {
  4529. text_list[i].compression_flag = 1;
  4530. }
  4531. else if(text[i].type == SPNG_ITXT)
  4532. {
  4533. text_list[i].compression_flag = text[i].compression_flag;
  4534. text_list[i].language_tag = text[i].language_tag;
  4535. text_list[i].translated_keyword = text[i].translated_keyword;
  4536. }
  4537. }
  4538. ctx->text_list = text_list;
  4539. ctx->n_text = n_text;
  4540. ctx->stored.text = 1;
  4541. ctx->user.text = 1;
  4542. return 0;
  4543. }
  4544. int spng_set_bkgd(spng_ctx *ctx, struct spng_bkgd *bkgd)
  4545. {
  4546. SPNG_SET_CHUNK_BOILERPLATE(bkgd);
  4547. if(!ctx->stored.ihdr) return 1;
  4548. if(ctx->ihdr.color_type == 0 || ctx->ihdr.color_type == 4)
  4549. {
  4550. ctx->bkgd.gray = bkgd->gray;
  4551. }
  4552. else if(ctx->ihdr.color_type == 2 || ctx->ihdr.color_type == 6)
  4553. {
  4554. ctx->bkgd.red = bkgd->red;
  4555. ctx->bkgd.green = bkgd->green;
  4556. ctx->bkgd.blue = bkgd->blue;
  4557. }
  4558. else if(ctx->ihdr.color_type == 3)
  4559. {
  4560. if(!ctx->stored.plte) return SPNG_EBKGD_NO_PLTE;
  4561. if(bkgd->plte_index >= ctx->plte.n_entries) return SPNG_EBKGD_PLTE_IDX;
  4562. ctx->bkgd.plte_index = bkgd->plte_index;
  4563. }
  4564. ctx->stored.bkgd = 1;
  4565. ctx->user.bkgd = 1;
  4566. return 0;
  4567. }
  4568. int spng_set_hist(spng_ctx *ctx, struct spng_hist *hist)
  4569. {
  4570. SPNG_SET_CHUNK_BOILERPLATE(hist);
  4571. if(!ctx->stored.plte) return SPNG_EHIST_NO_PLTE;
  4572. ctx->hist = *hist;
  4573. ctx->stored.hist = 1;
  4574. ctx->user.hist = 1;
  4575. return 0;
  4576. }
  4577. int spng_set_phys(spng_ctx *ctx, struct spng_phys *phys)
  4578. {
  4579. SPNG_SET_CHUNK_BOILERPLATE(phys);
  4580. if(check_phys(phys)) return SPNG_EPHYS;
  4581. ctx->phys = *phys;
  4582. ctx->stored.phys = 1;
  4583. ctx->user.phys = 1;
  4584. return 0;
  4585. }
  4586. int spng_set_splt(spng_ctx *ctx, struct spng_splt *splt, uint32_t n_splt)
  4587. {
  4588. if(!n_splt) return 1;
  4589. SPNG_SET_CHUNK_BOILERPLATE(splt);
  4590. uint32_t i;
  4591. for(i=0; i < n_splt; i++)
  4592. {
  4593. if(check_png_keyword(splt[i].name)) return SPNG_ESPLT_NAME;
  4594. if( !(splt[i].sample_depth == 8 || splt[i].sample_depth == 16) ) return SPNG_ESPLT_DEPTH;
  4595. }
  4596. if(ctx->stored.splt && !ctx->user.splt)
  4597. {
  4598. for(i=0; i < ctx->n_splt; i++)
  4599. {
  4600. if(ctx->splt_list[i].entries != NULL) spng__free(ctx, ctx->splt_list[i].entries);
  4601. }
  4602. spng__free(ctx, ctx->splt_list);
  4603. }
  4604. ctx->splt_list = splt;
  4605. ctx->n_splt = n_splt;
  4606. ctx->stored.splt = 1;
  4607. ctx->user.splt = 1;
  4608. return 0;
  4609. }
  4610. int spng_set_time(spng_ctx *ctx, struct spng_time *time)
  4611. {
  4612. SPNG_SET_CHUNK_BOILERPLATE(time);
  4613. if(check_time(time)) return SPNG_ETIME;
  4614. ctx->time = *time;
  4615. ctx->stored.time = 1;
  4616. ctx->user.time = 1;
  4617. return 0;
  4618. }
  4619. int spng_set_unknown_chunks(spng_ctx *ctx, struct spng_unknown_chunk *chunks, uint32_t n_chunks)
  4620. {
  4621. if(!n_chunks) return 1;
  4622. SPNG_SET_CHUNK_BOILERPLATE(chunks);
  4623. uint32_t i;
  4624. for(i=0; i < n_chunks; i++)
  4625. {
  4626. if(chunks[i].length > spng_u32max) return SPNG_ECHUNK_STDLEN;
  4627. if(chunks[i].length && chunks[i].data == NULL) return 1;
  4628. switch(chunks[i].location)
  4629. {
  4630. case SPNG_AFTER_IHDR:
  4631. case SPNG_AFTER_PLTE:
  4632. case SPNG_AFTER_IDAT:
  4633. break;
  4634. default: return SPNG_ECHUNK_POS;
  4635. }
  4636. }
  4637. if(ctx->stored.unknown && !ctx->user.unknown)
  4638. {
  4639. for(i=0; i < ctx->n_chunks; i++)
  4640. {
  4641. spng__free(ctx, ctx->chunk_list[i].data);
  4642. }
  4643. spng__free(ctx, ctx->chunk_list);
  4644. }
  4645. ctx->chunk_list = chunks;
  4646. ctx->n_chunks = n_chunks;
  4647. ctx->stored.unknown = 1;
  4648. ctx->user.unknown = 1;
  4649. return 0;
  4650. }
  4651. int spng_set_offs(spng_ctx *ctx, struct spng_offs *offs)
  4652. {
  4653. SPNG_SET_CHUNK_BOILERPLATE(offs);
  4654. if(check_offs(offs)) return SPNG_EOFFS;
  4655. ctx->offs = *offs;
  4656. ctx->stored.offs = 1;
  4657. ctx->user.offs = 1;
  4658. return 0;
  4659. }
  4660. int spng_set_exif(spng_ctx *ctx, struct spng_exif *exif)
  4661. {
  4662. SPNG_SET_CHUNK_BOILERPLATE(exif);
  4663. if(check_exif(exif)) return SPNG_EEXIF;
  4664. if(ctx->exif.data != NULL && !ctx->user.exif) spng__free(ctx, ctx->exif.data);
  4665. ctx->exif = *exif;
  4666. ctx->stored.exif = 1;
  4667. ctx->user.exif = 1;
  4668. return 0;
  4669. }
  4670. const char *spng_strerror(int err)
  4671. {
  4672. switch(err)
  4673. {
  4674. case SPNG_IO_EOF: return "end of stream";
  4675. case SPNG_IO_ERROR: return "stream error";
  4676. case SPNG_OK: return "success";
  4677. case SPNG_EINVAL: return "invalid argument";
  4678. case SPNG_EMEM: return "out of memory";
  4679. case SPNG_EOVERFLOW: return "arithmetic overflow";
  4680. case SPNG_ESIGNATURE: return "invalid signature";
  4681. case SPNG_EWIDTH: return "invalid image width";
  4682. case SPNG_EHEIGHT: return "invalid image height";
  4683. case SPNG_EUSER_WIDTH: return "image width exceeds user limit";
  4684. case SPNG_EUSER_HEIGHT: return "image height exceeds user limit";
  4685. case SPNG_EBIT_DEPTH: return "invalid bit depth";
  4686. case SPNG_ECOLOR_TYPE: return "invalid color type";
  4687. case SPNG_ECOMPRESSION_METHOD: return "invalid compression method";
  4688. case SPNG_EFILTER_METHOD: return "invalid filter method";
  4689. case SPNG_EINTERLACE_METHOD: return "invalid interlace method";
  4690. case SPNG_EIHDR_SIZE: return "invalid IHDR chunk size";
  4691. case SPNG_ENOIHDR: return "missing IHDR chunk";
  4692. case SPNG_ECHUNK_POS: return "invalid chunk position";
  4693. case SPNG_ECHUNK_SIZE: return "invalid chunk length";
  4694. case SPNG_ECHUNK_CRC: return "invalid chunk checksum";
  4695. case SPNG_ECHUNK_TYPE: return "invalid chunk type";
  4696. case SPNG_ECHUNK_UNKNOWN_CRITICAL: return "unknown critical chunk";
  4697. case SPNG_EDUP_PLTE: return "duplicate PLTE chunk";
  4698. case SPNG_EDUP_CHRM: return "duplicate cHRM chunk";
  4699. case SPNG_EDUP_GAMA: return "duplicate gAMA chunk";
  4700. case SPNG_EDUP_ICCP: return "duplicate iCCP chunk";
  4701. case SPNG_EDUP_SBIT: return "duplicate sBIT chunk";
  4702. case SPNG_EDUP_SRGB: return "duplicate sRGB chunk";
  4703. case SPNG_EDUP_BKGD: return "duplicate bKGD chunk";
  4704. case SPNG_EDUP_HIST: return "duplicate hIST chunk";
  4705. case SPNG_EDUP_TRNS: return "duplicate tRNS chunk";
  4706. case SPNG_EDUP_PHYS: return "duplicate pHYs chunk";
  4707. case SPNG_EDUP_TIME: return "duplicate tIME chunk";
  4708. case SPNG_EDUP_OFFS: return "duplicate oFFs chunk";
  4709. case SPNG_EDUP_EXIF: return "duplicate eXIf chunk";
  4710. case SPNG_ECHRM: return "invalid cHRM chunk";
  4711. case SPNG_EPLTE_IDX: return "invalid palette (PLTE) index";
  4712. case SPNG_ETRNS_COLOR_TYPE: return "tRNS chunk with incompatible color type";
  4713. case SPNG_ETRNS_NO_PLTE: return "missing palette (PLTE) for tRNS chunk";
  4714. case SPNG_EGAMA: return "invalid gAMA chunk";
  4715. case SPNG_EICCP_NAME: return "invalid iCCP profile name";
  4716. case SPNG_EICCP_COMPRESSION_METHOD: return "invalid iCCP compression method";
  4717. case SPNG_ESBIT: return "invalid sBIT chunk";
  4718. case SPNG_ESRGB: return "invalid sRGB chunk";
  4719. case SPNG_ETEXT: return "invalid tEXt chunk";
  4720. case SPNG_ETEXT_KEYWORD: return "invalid tEXt keyword";
  4721. case SPNG_EZTXT: return "invalid zTXt chunk";
  4722. case SPNG_EZTXT_COMPRESSION_METHOD: return "invalid zTXt compression method";
  4723. case SPNG_EITXT: return "invalid iTXt chunk";
  4724. case SPNG_EITXT_COMPRESSION_FLAG: return "invalid iTXt compression flag";
  4725. case SPNG_EITXT_COMPRESSION_METHOD: return "invalid iTXt compression method";
  4726. case SPNG_EITXT_LANG_TAG: return "invalid iTXt language tag";
  4727. case SPNG_EITXT_TRANSLATED_KEY: return "invalid iTXt translated key";
  4728. case SPNG_EBKGD_NO_PLTE: return "missing palette for bKGD chunk";
  4729. case SPNG_EBKGD_PLTE_IDX: return "invalid palette index for bKGD chunk";
  4730. case SPNG_EHIST_NO_PLTE: return "missing palette for hIST chunk";
  4731. case SPNG_EPHYS: return "invalid pHYs chunk";
  4732. case SPNG_ESPLT_NAME: return "invalid suggested palette name";
  4733. case SPNG_ESPLT_DUP_NAME: return "duplicate suggested palette (sPLT) name";
  4734. case SPNG_ESPLT_DEPTH: return "invalid suggested palette (sPLT) sample depth";
  4735. case SPNG_ETIME: return "invalid tIME chunk";
  4736. case SPNG_EOFFS: return "invalid oFFs chunk";
  4737. case SPNG_EEXIF: return "invalid eXIf chunk";
  4738. case SPNG_EIDAT_TOO_SHORT: return "IDAT stream too short";
  4739. case SPNG_EIDAT_STREAM: return "IDAT stream error";
  4740. case SPNG_EZLIB: return "zlib error";
  4741. case SPNG_EFILTER: return "invalid scanline filter";
  4742. case SPNG_EBUFSIZ: return "invalid buffer size";
  4743. case SPNG_EIO: return "i/o error";
  4744. case SPNG_EOF: return "end of file";
  4745. case SPNG_EBUF_SET: return "buffer already set";
  4746. case SPNG_EBADSTATE: return "non-recoverable state";
  4747. case SPNG_EFMT: return "invalid format";
  4748. case SPNG_EFLAGS: return "invalid flags";
  4749. case SPNG_ECHUNKAVAIL: return "chunk not available";
  4750. case SPNG_ENCODE_ONLY: return "encode only context";
  4751. case SPNG_EOI: return "reached end-of-image state";
  4752. case SPNG_ENOPLTE: return "missing PLTE for indexed image";
  4753. case SPNG_ECHUNK_LIMITS: return "reached chunk/cache limits";
  4754. case SPNG_EZLIB_INIT: return "zlib init error";
  4755. case SPNG_ECHUNK_STDLEN: return "chunk exceeds maximum standard length";
  4756. case SPNG_EINTERNAL: return "internal error";
  4757. case SPNG_ECTXTYPE: return "invalid operation for context type";
  4758. case SPNG_ENOSRC: return "source PNG not set";
  4759. case SPNG_ENODST: return "PNG output not set";
  4760. case SPNG_EOPSTATE: return "invalid operation for state";
  4761. case SPNG_ENOTFINAL: return "PNG not finalized";
  4762. default: return "unknown error";
  4763. }
  4764. }
  4765. const char *spng_version_string(void)
  4766. {
  4767. return SPNG_VERSION_STRING;
  4768. }
  4769. #if defined(_MSC_VER)
  4770. #pragma warning(pop)
  4771. #endif
  4772. /* The following SIMD optimizations are derived from libpng source code. */
  4773. /*
  4774. * PNG Reference Library License version 2
  4775. *
  4776. * Copyright (c) 1995-2019 The PNG Reference Library Authors.
  4777. * Copyright (c) 2018-2019 Cosmin Truta.
  4778. * Copyright (c) 2000-2002, 2004, 2006-2018 Glenn Randers-Pehrson.
  4779. * Copyright (c) 1996-1997 Andreas Dilger.
  4780. * Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.
  4781. *
  4782. * The software is supplied "as is", without warranty of any kind,
  4783. * express or implied, including, without limitation, the warranties
  4784. * of merchantability, fitness for a particular purpose, title, and
  4785. * non-infringement. In no event shall the Copyright owners, or
  4786. * anyone distributing the software, be liable for any damages or
  4787. * other liability, whether in contract, tort or otherwise, arising
  4788. * from, out of, or in connection with the software, or the use or
  4789. * other dealings in the software, even if advised of the possibility
  4790. * of such damage.
  4791. *
  4792. * Permission is hereby granted to use, copy, modify, and distribute
  4793. * this software, or portions hereof, for any purpose, without fee,
  4794. * subject to the following restrictions:
  4795. *
  4796. * 1. The origin of this software must not be misrepresented; you
  4797. * must not claim that you wrote the original software. If you
  4798. * use this software in a product, an acknowledgment in the product
  4799. * documentation would be appreciated, but is not required.
  4800. *
  4801. * 2. Altered source versions must be plainly marked as such, and must
  4802. * not be misrepresented as being the original software.
  4803. *
  4804. * 3. This Copyright notice may not be removed or altered from any
  4805. * source or altered source distribution.
  4806. */
  4807. #if defined(SPNG_X86)
  4808. #ifndef SPNG_SSE
  4809. #define SPNG_SSE 1
  4810. #endif
  4811. #if defined(__GNUC__) && !defined(__clang__)
  4812. #if SPNG_SSE == 3
  4813. #pragma GCC target("ssse3")
  4814. #elif SPNG_SSE == 4
  4815. #pragma GCC target("sse4.1")
  4816. #else
  4817. #pragma GCC target("sse2")
  4818. #endif
  4819. #endif
  4820. /* SSE2 optimised filter functions
  4821. * Derived from filter_neon_intrinsics.c
  4822. *
  4823. * Copyright (c) 2018 Cosmin Truta
  4824. * Copyright (c) 2016-2017 Glenn Randers-Pehrson
  4825. * Written by Mike Klein and Matt Sarett
  4826. * Derived from arm/filter_neon_intrinsics.c
  4827. *
  4828. * This code is derived from libpng source code.
  4829. * For conditions of distribution and use, see the disclaimer
  4830. * and license above.
  4831. */
  4832. #include <immintrin.h>
  4833. #include <inttypes.h>
  4834. #include <string.h>
  4835. /* Functions in this file look at most 3 pixels (a,b,c) to predict the 4th (d).
  4836. * They're positioned like this:
  4837. * prev: c b
  4838. * row: a d
  4839. * The Sub filter predicts d=a, Avg d=(a+b)/2, and Paeth predicts d to be
  4840. * whichever of a, b, or c is closest to p=a+b-c.
  4841. */
  4842. static __m128i load4(const void* p)
  4843. {
  4844. int tmp;
  4845. memcpy(&tmp, p, sizeof(tmp));
  4846. return _mm_cvtsi32_si128(tmp);
  4847. }
  4848. static void store4(void* p, __m128i v)
  4849. {
  4850. int tmp = _mm_cvtsi128_si32(v);
  4851. memcpy(p, &tmp, sizeof(int));
  4852. }
  4853. static __m128i load3(const void* p)
  4854. {
  4855. uint32_t tmp = 0;
  4856. memcpy(&tmp, p, 3);
  4857. return _mm_cvtsi32_si128(tmp);
  4858. }
  4859. static void store3(void* p, __m128i v)
  4860. {
  4861. int tmp = _mm_cvtsi128_si32(v);
  4862. memcpy(p, &tmp, 3);
  4863. }
  4864. static void defilter_sub3(size_t rowbytes, unsigned char *row)
  4865. {
  4866. /* The Sub filter predicts each pixel as the previous pixel, a.
  4867. * There is no pixel to the left of the first pixel. It's encoded directly.
  4868. * That works with our main loop if we just say that left pixel was zero.
  4869. */
  4870. size_t rb = rowbytes;
  4871. __m128i a, d = _mm_setzero_si128();
  4872. while(rb >= 4)
  4873. {
  4874. a = d; d = load4(row);
  4875. d = _mm_add_epi8(d, a);
  4876. store3(row, d);
  4877. row += 3;
  4878. rb -= 3;
  4879. }
  4880. if(rb > 0)
  4881. {
  4882. a = d; d = load3(row);
  4883. d = _mm_add_epi8(d, a);
  4884. store3(row, d);
  4885. }
  4886. }
  4887. static void defilter_sub4(size_t rowbytes, unsigned char *row)
  4888. {
  4889. /* The Sub filter predicts each pixel as the previous pixel, a.
  4890. * There is no pixel to the left of the first pixel. It's encoded directly.
  4891. * That works with our main loop if we just say that left pixel was zero.
  4892. */
  4893. size_t rb = rowbytes+4;
  4894. __m128i a, d = _mm_setzero_si128();
  4895. while(rb > 4)
  4896. {
  4897. a = d; d = load4(row);
  4898. d = _mm_add_epi8(d, a);
  4899. store4(row, d);
  4900. row += 4;
  4901. rb -= 4;
  4902. }
  4903. }
  4904. static void defilter_avg3(size_t rowbytes, unsigned char *row, const unsigned char *prev)
  4905. {
  4906. /* The Avg filter predicts each pixel as the (truncated) average of a and b.
  4907. * There's no pixel to the left of the first pixel. Luckily, it's
  4908. * predicted to be half of the pixel above it. So again, this works
  4909. * perfectly with our loop if we make sure a starts at zero.
  4910. */
  4911. size_t rb = rowbytes;
  4912. const __m128i zero = _mm_setzero_si128();
  4913. __m128i b;
  4914. __m128i a, d = zero;
  4915. while(rb >= 4)
  4916. {
  4917. __m128i avg;
  4918. b = load4(prev);
  4919. a = d; d = load4(row );
  4920. /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
  4921. avg = _mm_avg_epu8(a,b);
  4922. /* ...but we can fix it up by subtracting off 1 if it rounded up. */
  4923. avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a, b),
  4924. _mm_set1_epi8(1)));
  4925. d = _mm_add_epi8(d, avg);
  4926. store3(row, d);
  4927. prev += 3;
  4928. row += 3;
  4929. rb -= 3;
  4930. }
  4931. if(rb > 0)
  4932. {
  4933. __m128i avg;
  4934. b = load3(prev);
  4935. a = d; d = load3(row );
  4936. /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
  4937. avg = _mm_avg_epu8(a, b);
  4938. /* ...but we can fix it up by subtracting off 1 if it rounded up. */
  4939. avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a, b),
  4940. _mm_set1_epi8(1)));
  4941. d = _mm_add_epi8(d, avg);
  4942. store3(row, d);
  4943. }
  4944. }
  4945. static void defilter_avg4(size_t rowbytes, unsigned char *row, const unsigned char *prev)
  4946. {
  4947. /* The Avg filter predicts each pixel as the (truncated) average of a and b.
  4948. * There's no pixel to the left of the first pixel. Luckily, it's
  4949. * predicted to be half of the pixel above it. So again, this works
  4950. * perfectly with our loop if we make sure a starts at zero.
  4951. */
  4952. size_t rb = rowbytes+4;
  4953. const __m128i zero = _mm_setzero_si128();
  4954. __m128i b;
  4955. __m128i a, d = zero;
  4956. while(rb > 4)
  4957. {
  4958. __m128i avg;
  4959. b = load4(prev);
  4960. a = d; d = load4(row );
  4961. /* PNG requires a truncating average, so we can't just use _mm_avg_epu8 */
  4962. avg = _mm_avg_epu8(a,b);
  4963. /* ...but we can fix it up by subtracting off 1 if it rounded up. */
  4964. avg = _mm_sub_epi8(avg, _mm_and_si128(_mm_xor_si128(a, b),
  4965. _mm_set1_epi8(1)));
  4966. d = _mm_add_epi8(d, avg);
  4967. store4(row, d);
  4968. prev += 4;
  4969. row += 4;
  4970. rb -= 4;
  4971. }
  4972. }
  4973. /* Returns |x| for 16-bit lanes. */
  4974. #if (SPNG_SSE >= 3) && !defined(_MSC_VER)
  4975. __attribute__((target("ssse3")))
  4976. #endif
  4977. static __m128i abs_i16(__m128i x)
  4978. {
  4979. #if SPNG_SSE >= 3
  4980. return _mm_abs_epi16(x);
  4981. #else
  4982. /* Read this all as, return x<0 ? -x : x.
  4983. * To negate two's complement, you flip all the bits then add 1.
  4984. */
  4985. __m128i is_negative = _mm_cmplt_epi16(x, _mm_setzero_si128());
  4986. /* Flip negative lanes. */
  4987. x = _mm_xor_si128(x, is_negative);
  4988. /* +1 to negative lanes, else +0. */
  4989. x = _mm_sub_epi16(x, is_negative);
  4990. return x;
  4991. #endif
  4992. }
  4993. /* Bytewise c ? t : e. */
  4994. static __m128i if_then_else(__m128i c, __m128i t, __m128i e)
  4995. {
  4996. #if SPNG_SSE >= 4
  4997. return _mm_blendv_epi8(e, t, c);
  4998. #else
  4999. return _mm_or_si128(_mm_and_si128(c, t), _mm_andnot_si128(c, e));
  5000. #endif
  5001. }
  5002. static void defilter_paeth3(size_t rowbytes, unsigned char *row, const unsigned char *prev)
  5003. {
  5004. /* Paeth tries to predict pixel d using the pixel to the left of it, a,
  5005. * and two pixels from the previous row, b and c:
  5006. * prev: c b
  5007. * row: a d
  5008. * The Paeth function predicts d to be whichever of a, b, or c is nearest to
  5009. * p=a+b-c.
  5010. *
  5011. * The first pixel has no left context, and so uses an Up filter, p = b.
  5012. * This works naturally with our main loop's p = a+b-c if we force a and c
  5013. * to zero.
  5014. * Here we zero b and d, which become c and a respectively at the start of
  5015. * the loop.
  5016. */
  5017. size_t rb = rowbytes;
  5018. const __m128i zero = _mm_setzero_si128();
  5019. __m128i c, b = zero,
  5020. a, d = zero;
  5021. while(rb >= 4)
  5022. {
  5023. /* It's easiest to do this math (particularly, deal with pc) with 16-bit
  5024. * intermediates.
  5025. */
  5026. __m128i pa,pb,pc,smallest,nearest;
  5027. c = b; b = _mm_unpacklo_epi8(load4(prev), zero);
  5028. a = d; d = _mm_unpacklo_epi8(load4(row ), zero);
  5029. /* (p-a) == (a+b-c - a) == (b-c) */
  5030. pa = _mm_sub_epi16(b, c);
  5031. /* (p-b) == (a+b-c - b) == (a-c) */
  5032. pb = _mm_sub_epi16(a, c);
  5033. /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
  5034. pc = _mm_add_epi16(pa, pb);
  5035. pa = abs_i16(pa); /* |p-a| */
  5036. pb = abs_i16(pb); /* |p-b| */
  5037. pc = abs_i16(pc); /* |p-c| */
  5038. smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
  5039. /* Paeth breaks ties favoring a over b over c. */
  5040. nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
  5041. if_then_else(_mm_cmpeq_epi16(smallest, pb), b, c));
  5042. /* Note `_epi8`: we need addition to wrap modulo 255. */
  5043. d = _mm_add_epi8(d, nearest);
  5044. store3(row, _mm_packus_epi16(d, d));
  5045. prev += 3;
  5046. row += 3;
  5047. rb -= 3;
  5048. }
  5049. if(rb > 0)
  5050. {
  5051. /* It's easiest to do this math (particularly, deal with pc) with 16-bit
  5052. * intermediates.
  5053. */
  5054. __m128i pa, pb, pc, smallest, nearest;
  5055. c = b; b = _mm_unpacklo_epi8(load3(prev), zero);
  5056. a = d; d = _mm_unpacklo_epi8(load3(row ), zero);
  5057. /* (p-a) == (a+b-c - a) == (b-c) */
  5058. pa = _mm_sub_epi16(b, c);
  5059. /* (p-b) == (a+b-c - b) == (a-c) */
  5060. pb = _mm_sub_epi16(a, c);
  5061. /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
  5062. pc = _mm_add_epi16(pa, pb);
  5063. pa = abs_i16(pa); /* |p-a| */
  5064. pb = abs_i16(pb); /* |p-b| */
  5065. pc = abs_i16(pc); /* |p-c| */
  5066. smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
  5067. /* Paeth breaks ties favoring a over b over c. */
  5068. nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
  5069. if_then_else(_mm_cmpeq_epi16(smallest, pb), b, c));
  5070. /* Note `_epi8`: we need addition to wrap modulo 255. */
  5071. d = _mm_add_epi8(d, nearest);
  5072. store3(row, _mm_packus_epi16(d, d));
  5073. }
  5074. }
  5075. static void defilter_paeth4(size_t rowbytes, unsigned char *row, const unsigned char *prev)
  5076. {
  5077. /* Paeth tries to predict pixel d using the pixel to the left of it, a,
  5078. * and two pixels from the previous row, b and c:
  5079. * prev: c b
  5080. * row: a d
  5081. * The Paeth function predicts d to be whichever of a, b, or c is nearest to
  5082. * p=a+b-c.
  5083. *
  5084. * The first pixel has no left context, and so uses an Up filter, p = b.
  5085. * This works naturally with our main loop's p = a+b-c if we force a and c
  5086. * to zero.
  5087. * Here we zero b and d, which become c and a respectively at the start of
  5088. * the loop.
  5089. */
  5090. size_t rb = rowbytes+4;
  5091. const __m128i zero = _mm_setzero_si128();
  5092. __m128i pa, pb, pc, smallest, nearest;
  5093. __m128i c, b = zero,
  5094. a, d = zero;
  5095. while(rb > 4)
  5096. {
  5097. /* It's easiest to do this math (particularly, deal with pc) with 16-bit
  5098. * intermediates.
  5099. */
  5100. c = b; b = _mm_unpacklo_epi8(load4(prev), zero);
  5101. a = d; d = _mm_unpacklo_epi8(load4(row ), zero);
  5102. /* (p-a) == (a+b-c - a) == (b-c) */
  5103. pa = _mm_sub_epi16(b, c);
  5104. /* (p-b) == (a+b-c - b) == (a-c) */
  5105. pb = _mm_sub_epi16(a, c);
  5106. /* (p-c) == (a+b-c - c) == (a+b-c-c) == (b-c)+(a-c) */
  5107. pc = _mm_add_epi16(pa, pb);
  5108. pa = abs_i16(pa); /* |p-a| */
  5109. pb = abs_i16(pb); /* |p-b| */
  5110. pc = abs_i16(pc); /* |p-c| */
  5111. smallest = _mm_min_epi16(pc, _mm_min_epi16(pa, pb));
  5112. /* Paeth breaks ties favoring a over b over c. */
  5113. nearest = if_then_else(_mm_cmpeq_epi16(smallest, pa), a,
  5114. if_then_else(_mm_cmpeq_epi16(smallest, pb), b, c));
  5115. /* Note `_epi8`: we need addition to wrap modulo 255. */
  5116. d = _mm_add_epi8(d, nearest);
  5117. store4(row, _mm_packus_epi16(d, d));
  5118. prev += 4;
  5119. row += 4;
  5120. rb -= 4;
  5121. }
  5122. }
  5123. #endif /* SPNG_X86 */
  5124. #if defined(SPNG_ARM)
  5125. /* NEON optimised filter functions
  5126. * Derived from filter_neon_intrinsics.c
  5127. *
  5128. * Copyright (c) 2018 Cosmin Truta
  5129. * Copyright (c) 2014,2016 Glenn Randers-Pehrson
  5130. * Written by James Yu <james.yu at linaro.org>, October 2013.
  5131. * Based on filter_neon.S, written by Mans Rullgard, 2011.
  5132. *
  5133. * This code is derived from libpng source code.
  5134. * For conditions of distribution and use, see the disclaimer
  5135. * and license in this file.
  5136. */
  5137. #define png_aligncast(type, value) ((void*)(value))
  5138. #define png_aligncastconst(type, value) ((const void*)(value))
  5139. /* libpng row pointers are not necessarily aligned to any particular boundary,
  5140. * however this code will only work with appropriate alignment. mips/mips_init.c
  5141. * checks for this (and will not compile unless it is done). This code uses
  5142. * variants of png_aligncast to avoid compiler warnings.
  5143. */
  5144. #define png_ptr(type,pointer) png_aligncast(type *,pointer)
  5145. #define png_ptrc(type,pointer) png_aligncastconst(const type *,pointer)
  5146. /* The following relies on a variable 'temp_pointer' being declared with type
  5147. * 'type'. This is written this way just to hide the GCC strict aliasing
  5148. * warning; note that the code is safe because there never is an alias between
  5149. * the input and output pointers.
  5150. */
  5151. #define png_ldr(type,pointer)\
  5152. (temp_pointer = png_ptr(type,pointer), *temp_pointer)
  5153. #if defined(_MSC_VER) && !defined(__clang__) && defined(_M_ARM64)
  5154. #include <arm64_neon.h>
  5155. #else
  5156. #include <arm_neon.h>
  5157. #endif
  5158. static void defilter_sub3(size_t rowbytes, unsigned char *row)
  5159. {
  5160. unsigned char *rp = row;
  5161. unsigned char *rp_stop = row + rowbytes;
  5162. uint8x16_t vtmp = vld1q_u8(rp);
  5163. uint8x8x2_t *vrpt = png_ptr(uint8x8x2_t, &vtmp);
  5164. uint8x8x2_t vrp = *vrpt;
  5165. uint8x8x4_t vdest;
  5166. vdest.val[3] = vdup_n_u8(0);
  5167. for (; rp < rp_stop;)
  5168. {
  5169. uint8x8_t vtmp1, vtmp2;
  5170. uint32x2_t *temp_pointer;
  5171. vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
  5172. vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
  5173. vtmp2 = vext_u8(vrp.val[0], vrp.val[1], 6);
  5174. vdest.val[1] = vadd_u8(vdest.val[0], vtmp1);
  5175. vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
  5176. vdest.val[2] = vadd_u8(vdest.val[1], vtmp2);
  5177. vdest.val[3] = vadd_u8(vdest.val[2], vtmp1);
  5178. vtmp = vld1q_u8(rp + 12);
  5179. vrpt = png_ptr(uint8x8x2_t, &vtmp);
  5180. vrp = *vrpt;
  5181. vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
  5182. rp += 3;
  5183. vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
  5184. rp += 3;
  5185. vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
  5186. rp += 3;
  5187. vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
  5188. rp += 3;
  5189. }
  5190. }
  5191. static void defilter_sub4(size_t rowbytes, unsigned char *row)
  5192. {
  5193. unsigned char *rp = row;
  5194. unsigned char *rp_stop = row + rowbytes;
  5195. uint8x8x4_t vdest;
  5196. vdest.val[3] = vdup_n_u8(0);
  5197. for (; rp < rp_stop; rp += 16)
  5198. {
  5199. uint32x2x4_t vtmp = vld4_u32(png_ptr(uint32_t,rp));
  5200. uint8x8x4_t *vrpt = png_ptr(uint8x8x4_t,&vtmp);
  5201. uint8x8x4_t vrp = *vrpt;
  5202. uint32x2x4_t *temp_pointer;
  5203. uint32x2x4_t vdest_val;
  5204. vdest.val[0] = vadd_u8(vdest.val[3], vrp.val[0]);
  5205. vdest.val[1] = vadd_u8(vdest.val[0], vrp.val[1]);
  5206. vdest.val[2] = vadd_u8(vdest.val[1], vrp.val[2]);
  5207. vdest.val[3] = vadd_u8(vdest.val[2], vrp.val[3]);
  5208. vdest_val = png_ldr(uint32x2x4_t, &vdest);
  5209. vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
  5210. }
  5211. }
  5212. static void defilter_avg3(size_t rowbytes, unsigned char *row, const unsigned char *prev_row)
  5213. {
  5214. unsigned char *rp = row;
  5215. const unsigned char *pp = prev_row;
  5216. unsigned char *rp_stop = row + rowbytes;
  5217. uint8x16_t vtmp;
  5218. uint8x8x2_t *vrpt;
  5219. uint8x8x2_t vrp;
  5220. uint8x8x4_t vdest;
  5221. vdest.val[3] = vdup_n_u8(0);
  5222. vtmp = vld1q_u8(rp);
  5223. vrpt = png_ptr(uint8x8x2_t,&vtmp);
  5224. vrp = *vrpt;
  5225. for (; rp < rp_stop; pp += 12)
  5226. {
  5227. uint8x8_t vtmp1, vtmp2, vtmp3;
  5228. uint8x8x2_t *vppt;
  5229. uint8x8x2_t vpp;
  5230. uint32x2_t *temp_pointer;
  5231. vtmp = vld1q_u8(pp);
  5232. vppt = png_ptr(uint8x8x2_t,&vtmp);
  5233. vpp = *vppt;
  5234. vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
  5235. vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
  5236. vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
  5237. vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
  5238. vtmp3 = vext_u8(vrp.val[0], vrp.val[1], 6);
  5239. vdest.val[1] = vhadd_u8(vdest.val[0], vtmp2);
  5240. vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
  5241. vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 6);
  5242. vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
  5243. vtmp = vld1q_u8(rp + 12);
  5244. vrpt = png_ptr(uint8x8x2_t,&vtmp);
  5245. vrp = *vrpt;
  5246. vdest.val[2] = vhadd_u8(vdest.val[1], vtmp2);
  5247. vdest.val[2] = vadd_u8(vdest.val[2], vtmp3);
  5248. vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
  5249. vdest.val[3] = vhadd_u8(vdest.val[2], vtmp2);
  5250. vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
  5251. vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
  5252. rp += 3;
  5253. vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
  5254. rp += 3;
  5255. vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
  5256. rp += 3;
  5257. vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
  5258. rp += 3;
  5259. }
  5260. }
  5261. static void defilter_avg4(size_t rowbytes, unsigned char *row, const unsigned char *prev_row)
  5262. {
  5263. unsigned char *rp = row;
  5264. unsigned char *rp_stop = row + rowbytes;
  5265. const unsigned char *pp = prev_row;
  5266. uint8x8x4_t vdest;
  5267. vdest.val[3] = vdup_n_u8(0);
  5268. for (; rp < rp_stop; rp += 16, pp += 16)
  5269. {
  5270. uint32x2x4_t vtmp;
  5271. uint8x8x4_t *vrpt, *vppt;
  5272. uint8x8x4_t vrp, vpp;
  5273. uint32x2x4_t *temp_pointer;
  5274. uint32x2x4_t vdest_val;
  5275. vtmp = vld4_u32(png_ptr(uint32_t,rp));
  5276. vrpt = png_ptr(uint8x8x4_t,&vtmp);
  5277. vrp = *vrpt;
  5278. vtmp = vld4_u32(png_ptrc(uint32_t,pp));
  5279. vppt = png_ptr(uint8x8x4_t,&vtmp);
  5280. vpp = *vppt;
  5281. vdest.val[0] = vhadd_u8(vdest.val[3], vpp.val[0]);
  5282. vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
  5283. vdest.val[1] = vhadd_u8(vdest.val[0], vpp.val[1]);
  5284. vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
  5285. vdest.val[2] = vhadd_u8(vdest.val[1], vpp.val[2]);
  5286. vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
  5287. vdest.val[3] = vhadd_u8(vdest.val[2], vpp.val[3]);
  5288. vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
  5289. vdest_val = png_ldr(uint32x2x4_t, &vdest);
  5290. vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
  5291. }
  5292. }
  5293. static uint8x8_t paeth_arm(uint8x8_t a, uint8x8_t b, uint8x8_t c)
  5294. {
  5295. uint8x8_t d, e;
  5296. uint16x8_t p1, pa, pb, pc;
  5297. p1 = vaddl_u8(a, b); /* a + b */
  5298. pc = vaddl_u8(c, c); /* c * 2 */
  5299. pa = vabdl_u8(b, c); /* pa */
  5300. pb = vabdl_u8(a, c); /* pb */
  5301. pc = vabdq_u16(p1, pc); /* pc */
  5302. p1 = vcleq_u16(pa, pb); /* pa <= pb */
  5303. pa = vcleq_u16(pa, pc); /* pa <= pc */
  5304. pb = vcleq_u16(pb, pc); /* pb <= pc */
  5305. p1 = vandq_u16(p1, pa); /* pa <= pb && pa <= pc */
  5306. d = vmovn_u16(pb);
  5307. e = vmovn_u16(p1);
  5308. d = vbsl_u8(d, b, c);
  5309. e = vbsl_u8(e, a, d);
  5310. return e;
  5311. }
  5312. static void defilter_paeth3(size_t rowbytes, unsigned char *row, const unsigned char *prev_row)
  5313. {
  5314. unsigned char *rp = row;
  5315. const unsigned char *pp = prev_row;
  5316. unsigned char *rp_stop = row + rowbytes;
  5317. uint8x16_t vtmp;
  5318. uint8x8x2_t *vrpt;
  5319. uint8x8x2_t vrp;
  5320. uint8x8_t vlast = vdup_n_u8(0);
  5321. uint8x8x4_t vdest;
  5322. vdest.val[3] = vdup_n_u8(0);
  5323. vtmp = vld1q_u8(rp);
  5324. vrpt = png_ptr(uint8x8x2_t,&vtmp);
  5325. vrp = *vrpt;
  5326. for (; rp < rp_stop; pp += 12)
  5327. {
  5328. uint8x8x2_t *vppt;
  5329. uint8x8x2_t vpp;
  5330. uint8x8_t vtmp1, vtmp2, vtmp3;
  5331. uint32x2_t *temp_pointer;
  5332. vtmp = vld1q_u8(pp);
  5333. vppt = png_ptr(uint8x8x2_t,&vtmp);
  5334. vpp = *vppt;
  5335. vdest.val[0] = paeth_arm(vdest.val[3], vpp.val[0], vlast);
  5336. vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
  5337. vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 3);
  5338. vtmp2 = vext_u8(vpp.val[0], vpp.val[1], 3);
  5339. vdest.val[1] = paeth_arm(vdest.val[0], vtmp2, vpp.val[0]);
  5340. vdest.val[1] = vadd_u8(vdest.val[1], vtmp1);
  5341. vtmp1 = vext_u8(vrp.val[0], vrp.val[1], 6);
  5342. vtmp3 = vext_u8(vpp.val[0], vpp.val[1], 6);
  5343. vdest.val[2] = paeth_arm(vdest.val[1], vtmp3, vtmp2);
  5344. vdest.val[2] = vadd_u8(vdest.val[2], vtmp1);
  5345. vtmp1 = vext_u8(vrp.val[1], vrp.val[1], 1);
  5346. vtmp2 = vext_u8(vpp.val[1], vpp.val[1], 1);
  5347. vtmp = vld1q_u8(rp + 12);
  5348. vrpt = png_ptr(uint8x8x2_t,&vtmp);
  5349. vrp = *vrpt;
  5350. vdest.val[3] = paeth_arm(vdest.val[2], vtmp2, vtmp3);
  5351. vdest.val[3] = vadd_u8(vdest.val[3], vtmp1);
  5352. vlast = vtmp2;
  5353. vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[0]), 0);
  5354. rp += 3;
  5355. vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[1]), 0);
  5356. rp += 3;
  5357. vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[2]), 0);
  5358. rp += 3;
  5359. vst1_lane_u32(png_ptr(uint32_t,rp), png_ldr(uint32x2_t,&vdest.val[3]), 0);
  5360. rp += 3;
  5361. }
  5362. }
  5363. static void defilter_paeth4(size_t rowbytes, unsigned char *row, const unsigned char *prev_row)
  5364. {
  5365. unsigned char *rp = row;
  5366. unsigned char *rp_stop = row + rowbytes;
  5367. const unsigned char *pp = prev_row;
  5368. uint8x8_t vlast = vdup_n_u8(0);
  5369. uint8x8x4_t vdest;
  5370. vdest.val[3] = vdup_n_u8(0);
  5371. for (; rp < rp_stop; rp += 16, pp += 16)
  5372. {
  5373. uint32x2x4_t vtmp;
  5374. uint8x8x4_t *vrpt, *vppt;
  5375. uint8x8x4_t vrp, vpp;
  5376. uint32x2x4_t *temp_pointer;
  5377. uint32x2x4_t vdest_val;
  5378. vtmp = vld4_u32(png_ptr(uint32_t,rp));
  5379. vrpt = png_ptr(uint8x8x4_t,&vtmp);
  5380. vrp = *vrpt;
  5381. vtmp = vld4_u32(png_ptrc(uint32_t,pp));
  5382. vppt = png_ptr(uint8x8x4_t,&vtmp);
  5383. vpp = *vppt;
  5384. vdest.val[0] = paeth_arm(vdest.val[3], vpp.val[0], vlast);
  5385. vdest.val[0] = vadd_u8(vdest.val[0], vrp.val[0]);
  5386. vdest.val[1] = paeth_arm(vdest.val[0], vpp.val[1], vpp.val[0]);
  5387. vdest.val[1] = vadd_u8(vdest.val[1], vrp.val[1]);
  5388. vdest.val[2] = paeth_arm(vdest.val[1], vpp.val[2], vpp.val[1]);
  5389. vdest.val[2] = vadd_u8(vdest.val[2], vrp.val[2]);
  5390. vdest.val[3] = paeth_arm(vdest.val[2], vpp.val[3], vpp.val[2]);
  5391. vdest.val[3] = vadd_u8(vdest.val[3], vrp.val[3]);
  5392. vlast = vpp.val[3];
  5393. vdest_val = png_ldr(uint32x2x4_t, &vdest);
  5394. vst4_lane_u32(png_ptr(uint32_t,rp), vdest_val, 0);
  5395. }
  5396. }
  5397. /* NEON optimised palette expansion functions
  5398. * Derived from palette_neon_intrinsics.c
  5399. *
  5400. * Copyright (c) 2018-2019 Cosmin Truta
  5401. * Copyright (c) 2017-2018 Arm Holdings. All rights reserved.
  5402. * Written by Richard Townsend <Richard.Townsend@arm.com>, February 2017.
  5403. *
  5404. * This code is derived from libpng source code.
  5405. * For conditions of distribution and use, see the disclaimer
  5406. * and license in this file.
  5407. *
  5408. * Related: https://developer.arm.com/documentation/101964/latest/Color-palette-expansion
  5409. *
  5410. * The functions were refactored to iterate forward.
  5411. *
  5412. */
  5413. /* Expands a palettized row into RGBA8. */
  5414. static uint32_t expand_palette_rgba8_neon(unsigned char *row, const unsigned char *scanline, const unsigned char *plte, uint32_t width)
  5415. {
  5416. const uint32_t scanline_stride = 4;
  5417. const uint32_t row_stride = scanline_stride * 4;
  5418. const uint32_t count = width / scanline_stride;
  5419. const uint32_t *palette = (const uint32_t*)plte;
  5420. if(!count) return 0;
  5421. uint32_t i;
  5422. uint32x4_t cur;
  5423. for(i=0; i < count; i++, scanline += scanline_stride)
  5424. {
  5425. cur = vld1q_dup_u32 (palette + scanline[0]);
  5426. cur = vld1q_lane_u32(palette + scanline[1], cur, 1);
  5427. cur = vld1q_lane_u32(palette + scanline[2], cur, 2);
  5428. cur = vld1q_lane_u32(palette + scanline[3], cur, 3);
  5429. vst1q_u32((uint32_t*)(row + i * row_stride), cur);
  5430. }
  5431. return count * scanline_stride;
  5432. }
  5433. /* Expands a palettized row into RGB8. */
  5434. static uint32_t expand_palette_rgb8_neon(unsigned char *row, const unsigned char *scanline, const unsigned char *plte, uint32_t width)
  5435. {
  5436. const uint32_t scanline_stride = 8;
  5437. const uint32_t row_stride = scanline_stride * 3;
  5438. const uint32_t count = width / scanline_stride;
  5439. if(!count) return 0;
  5440. uint32_t i;
  5441. uint8x8x3_t cur;
  5442. for(i=0; i < count; i++, scanline += scanline_stride)
  5443. {
  5444. cur = vld3_dup_u8 (plte + 3 * scanline[0]);
  5445. cur = vld3_lane_u8(plte + 3 * scanline[1], cur, 1);
  5446. cur = vld3_lane_u8(plte + 3 * scanline[2], cur, 2);
  5447. cur = vld3_lane_u8(plte + 3 * scanline[3], cur, 3);
  5448. cur = vld3_lane_u8(plte + 3 * scanline[4], cur, 4);
  5449. cur = vld3_lane_u8(plte + 3 * scanline[5], cur, 5);
  5450. cur = vld3_lane_u8(plte + 3 * scanline[6], cur, 6);
  5451. cur = vld3_lane_u8(plte + 3 * scanline[7], cur, 7);
  5452. vst3_u8(row + i * row_stride, cur);
  5453. }
  5454. return count * scanline_stride;
  5455. }
  5456. #endif /* SPNG_ARM */