123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495 |
- /*
- * Copyright (c) 1988-1997 Sam Leffler
- * Copyright (c) 1991-1997 Silicon Graphics, Inc.
- *
- * Permission to use, copy, modify, distribute, and sell this software and
- * its documentation for any purpose is hereby granted without fee, provided
- * that (i) the above copyright notices and this permission notice appear in
- * all copies of the software and related documentation, and (ii) the names of
- * Sam Leffler and Silicon Graphics may not be used in any advertising or
- * publicity relating to the software without the specific, prior written
- * permission of Sam Leffler and Silicon Graphics.
- *
- * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
- * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
- *
- * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
- * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
- * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
- * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
- * OF THIS SOFTWARE.
- */
- /*
- * TIFF Library.
- *
- * Directory Read Support Routines.
- */
- /* Suggested pending improvements:
- * - add a field 'field_info' to the TIFFDirEntry structure, and set that with
- * the pointer to the appropriate TIFFField structure early on in
- * TIFFReadDirectory, so as to eliminate current possibly repetitive lookup.
- */
- #include "tiffiop.h"
- #include <float.h>
- #include <stdlib.h>
- #define FAILED_FII ((uint32) -1)
- /*
- * Largest 64-bit signed integer value.
- */
- #define TIFF_INT64_MAX ((int64)(TIFF_UINT64_MAX >> 1))
- #ifdef HAVE_IEEEFP
- # define TIFFCvtIEEEFloatToNative(tif, n, fp)
- # define TIFFCvtIEEEDoubleToNative(tif, n, dp)
- #else
- extern void TIFFCvtIEEEFloatToNative(TIFF*, uint32, float*);
- extern void TIFFCvtIEEEDoubleToNative(TIFF*, uint32, double*);
- #endif
- enum TIFFReadDirEntryErr {
- TIFFReadDirEntryErrOk = 0,
- TIFFReadDirEntryErrCount = 1,
- TIFFReadDirEntryErrType = 2,
- TIFFReadDirEntryErrIo = 3,
- TIFFReadDirEntryErrRange = 4,
- TIFFReadDirEntryErrPsdif = 5,
- TIFFReadDirEntryErrSizesan = 6,
- TIFFReadDirEntryErrAlloc = 7,
- };
- static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
- #if 0
- static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
- #endif
- static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value);
- static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value);
- static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value);
- static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value);
- static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value);
- static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value);
- static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongLong8(uint64 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong8(int64 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong(uint32 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongLong8(uint64 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlongSlong8(int64 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Sshort(int16 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong(int32 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLong8Slong8(int64 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value);
- static enum TIFFReadDirEntryErr TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest);
- static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover);
- static void TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount);
- static TIFFDirEntry* TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid);
- static void TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii);
- static int EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount);
- static void MissingRequired(TIFF*, const char*);
- static int TIFFCheckDirOffset(TIFF* tif, uint64 diroff);
- static int CheckDirCount(TIFF*, TIFFDirEntry*, uint32);
- static uint16 TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir, uint64* nextdiroff);
- static int TIFFFetchNormalTag(TIFF*, TIFFDirEntry*, int recover);
- static int TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp);
- static int TIFFFetchSubjectDistance(TIFF*, TIFFDirEntry*);
- static void ChopUpSingleUncompressedStrip(TIFF*);
- static void TryChopUpUncompressedBigTiff(TIFF*);
- static uint64 TIFFReadUInt64(const uint8 *value);
- static int _TIFFGetMaxColorChannels(uint16 photometric);
- static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount );
- typedef union _UInt64Aligned_t
- {
- double d;
- uint64 l;
- uint32 i[2];
- uint16 s[4];
- uint8 c[8];
- } UInt64Aligned_t;
- /*
- Unaligned safe copy of a uint64 value from an octet array.
- */
- static uint64 TIFFReadUInt64(const uint8 *value)
- {
- UInt64Aligned_t result;
- result.c[0]=value[0];
- result.c[1]=value[1];
- result.c[2]=value[2];
- result.c[3]=value[3];
- result.c[4]=value[4];
- result.c[5]=value[5];
- result.c[6]=value[6];
- result.c[7]=value[7];
- return result.l;
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value)
- {
- enum TIFFReadDirEntryErr err;
- if (direntry->tdir_count!=1)
- return(TIFFReadDirEntryErrCount);
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- case TIFF_UNDEFINED: /* Support to read TIFF_UNDEFINED with field_readcount==1 */
- TIFFReadDirEntryCheckedByte(tif,direntry,value);
- return(TIFFReadDirEntryErrOk);
- case TIFF_SBYTE:
- {
- int8 m;
- TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeByteSbyte(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint8)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SHORT:
- {
- uint16 m;
- TIFFReadDirEntryCheckedShort(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeByteShort(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint8)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SSHORT:
- {
- int16 m;
- TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeByteSshort(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint8)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_LONG:
- {
- uint32 m;
- TIFFReadDirEntryCheckedLong(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeByteLong(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint8)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SLONG:
- {
- int32 m;
- TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeByteSlong(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint8)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_LONG8:
- {
- uint64 m;
- err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- err=TIFFReadDirEntryCheckRangeByteLong8(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint8)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SLONG8:
- {
- int64 m;
- err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- err=TIFFReadDirEntryCheckRangeByteSlong8(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint8)m;
- return(TIFFReadDirEntryErrOk);
- }
- default:
- return(TIFFReadDirEntryErrType);
- }
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value)
- {
- enum TIFFReadDirEntryErr err;
- if (direntry->tdir_count!=1)
- return(TIFFReadDirEntryErrCount);
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- {
- uint8 m;
- TIFFReadDirEntryCheckedByte(tif,direntry,&m);
- *value=(uint16)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SBYTE:
- {
- int8 m;
- TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeShortSbyte(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint16)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SHORT:
- TIFFReadDirEntryCheckedShort(tif,direntry,value);
- return(TIFFReadDirEntryErrOk);
- case TIFF_SSHORT:
- {
- int16 m;
- TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeShortSshort(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint16)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_LONG:
- {
- uint32 m;
- TIFFReadDirEntryCheckedLong(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeShortLong(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint16)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SLONG:
- {
- int32 m;
- TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeShortSlong(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint16)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_LONG8:
- {
- uint64 m;
- err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- err=TIFFReadDirEntryCheckRangeShortLong8(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint16)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SLONG8:
- {
- int64 m;
- err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- err=TIFFReadDirEntryCheckRangeShortSlong8(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint16)m;
- return(TIFFReadDirEntryErrOk);
- }
- default:
- return(TIFFReadDirEntryErrType);
- }
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value)
- {
- enum TIFFReadDirEntryErr err;
- if (direntry->tdir_count!=1)
- return(TIFFReadDirEntryErrCount);
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- {
- uint8 m;
- TIFFReadDirEntryCheckedByte(tif,direntry,&m);
- *value=(uint32)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SBYTE:
- {
- int8 m;
- TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeLongSbyte(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint32)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SHORT:
- {
- uint16 m;
- TIFFReadDirEntryCheckedShort(tif,direntry,&m);
- *value=(uint32)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SSHORT:
- {
- int16 m;
- TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeLongSshort(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint32)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_LONG:
- TIFFReadDirEntryCheckedLong(tif,direntry,value);
- return(TIFFReadDirEntryErrOk);
- case TIFF_SLONG:
- {
- int32 m;
- TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeLongSlong(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint32)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_LONG8:
- {
- uint64 m;
- err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- err=TIFFReadDirEntryCheckRangeLongLong8(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint32)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SLONG8:
- {
- int64 m;
- err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- err=TIFFReadDirEntryCheckRangeLongSlong8(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint32)m;
- return(TIFFReadDirEntryErrOk);
- }
- default:
- return(TIFFReadDirEntryErrType);
- }
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
- {
- enum TIFFReadDirEntryErr err;
- if (direntry->tdir_count!=1)
- return(TIFFReadDirEntryErrCount);
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- {
- uint8 m;
- TIFFReadDirEntryCheckedByte(tif,direntry,&m);
- *value=(uint64)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SBYTE:
- {
- int8 m;
- TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeLong8Sbyte(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint64)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SHORT:
- {
- uint16 m;
- TIFFReadDirEntryCheckedShort(tif,direntry,&m);
- *value=(uint64)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SSHORT:
- {
- int16 m;
- TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeLong8Sshort(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint64)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_LONG:
- {
- uint32 m;
- TIFFReadDirEntryCheckedLong(tif,direntry,&m);
- *value=(uint64)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SLONG:
- {
- int32 m;
- TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
- err=TIFFReadDirEntryCheckRangeLong8Slong(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint64)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_LONG8:
- err=TIFFReadDirEntryCheckedLong8(tif,direntry,value);
- return(err);
- case TIFF_SLONG8:
- {
- int64 m;
- err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- err=TIFFReadDirEntryCheckRangeLong8Slong8(m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(uint64)m;
- return(TIFFReadDirEntryErrOk);
- }
- default:
- return(TIFFReadDirEntryErrType);
- }
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryFloat(TIFF* tif, TIFFDirEntry* direntry, float* value)
- {
- enum TIFFReadDirEntryErr err;
- if (direntry->tdir_count!=1)
- return(TIFFReadDirEntryErrCount);
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- {
- uint8 m;
- TIFFReadDirEntryCheckedByte(tif,direntry,&m);
- *value=(float)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SBYTE:
- {
- int8 m;
- TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
- *value=(float)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SHORT:
- {
- uint16 m;
- TIFFReadDirEntryCheckedShort(tif,direntry,&m);
- *value=(float)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SSHORT:
- {
- int16 m;
- TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
- *value=(float)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_LONG:
- {
- uint32 m;
- TIFFReadDirEntryCheckedLong(tif,direntry,&m);
- *value=(float)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SLONG:
- {
- int32 m;
- TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
- *value=(float)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_LONG8:
- {
- uint64 m;
- err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- #if defined(__WIN32__) && (_MSC_VER < 1500)
- /*
- * XXX: MSVC 6.0 does not support conversion
- * of 64-bit integers into floating point
- * values.
- */
- *value = _TIFFUInt64ToFloat(m);
- #else
- *value=(float)m;
- #endif
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SLONG8:
- {
- int64 m;
- err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(float)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_RATIONAL:
- {
- double m;
- err=TIFFReadDirEntryCheckedRational(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(float)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SRATIONAL:
- {
- double m;
- err=TIFFReadDirEntryCheckedSrational(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(float)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_FLOAT:
- TIFFReadDirEntryCheckedFloat(tif,direntry,value);
- return(TIFFReadDirEntryErrOk);
- case TIFF_DOUBLE:
- {
- double m;
- err=TIFFReadDirEntryCheckedDouble(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- if ((m > FLT_MAX) || (m < -FLT_MAX))
- return(TIFFReadDirEntryErrRange);
- *value=(float)m;
- return(TIFFReadDirEntryErrOk);
- }
- default:
- return(TIFFReadDirEntryErrType);
- }
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryDouble(TIFF* tif, TIFFDirEntry* direntry, double* value)
- {
- enum TIFFReadDirEntryErr err;
- if (direntry->tdir_count!=1)
- return(TIFFReadDirEntryErrCount);
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- {
- uint8 m;
- TIFFReadDirEntryCheckedByte(tif,direntry,&m);
- *value=(double)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SBYTE:
- {
- int8 m;
- TIFFReadDirEntryCheckedSbyte(tif,direntry,&m);
- *value=(double)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SHORT:
- {
- uint16 m;
- TIFFReadDirEntryCheckedShort(tif,direntry,&m);
- *value=(double)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SSHORT:
- {
- int16 m;
- TIFFReadDirEntryCheckedSshort(tif,direntry,&m);
- *value=(double)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_LONG:
- {
- uint32 m;
- TIFFReadDirEntryCheckedLong(tif,direntry,&m);
- *value=(double)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SLONG:
- {
- int32 m;
- TIFFReadDirEntryCheckedSlong(tif,direntry,&m);
- *value=(double)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_LONG8:
- {
- uint64 m;
- err=TIFFReadDirEntryCheckedLong8(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- #if defined(__WIN32__) && (_MSC_VER < 1500)
- /*
- * XXX: MSVC 6.0 does not support conversion
- * of 64-bit integers into floating point
- * values.
- */
- *value = _TIFFUInt64ToDouble(m);
- #else
- *value = (double)m;
- #endif
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SLONG8:
- {
- int64 m;
- err=TIFFReadDirEntryCheckedSlong8(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- *value=(double)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_RATIONAL:
- err=TIFFReadDirEntryCheckedRational(tif,direntry,value);
- return(err);
- case TIFF_SRATIONAL:
- err=TIFFReadDirEntryCheckedSrational(tif,direntry,value);
- return(err);
- case TIFF_FLOAT:
- {
- float m;
- TIFFReadDirEntryCheckedFloat(tif,direntry,&m);
- *value=(double)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_DOUBLE:
- err=TIFFReadDirEntryCheckedDouble(tif,direntry,value);
- return(err);
- default:
- return(TIFFReadDirEntryErrType);
- }
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
- {
- enum TIFFReadDirEntryErr err;
- if (direntry->tdir_count!=1)
- return(TIFFReadDirEntryErrCount);
- switch (direntry->tdir_type)
- {
- case TIFF_LONG:
- case TIFF_IFD:
- {
- uint32 m;
- TIFFReadDirEntryCheckedLong(tif,direntry,&m);
- *value=(uint64)m;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_LONG8:
- case TIFF_IFD8:
- err=TIFFReadDirEntryCheckedLong8(tif,direntry,value);
- return(err);
- default:
- return(TIFFReadDirEntryErrType);
- }
- }
- #define INITIAL_THRESHOLD (1024 * 1024)
- #define THRESHOLD_MULTIPLIER 10
- #define MAX_THRESHOLD (THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * THRESHOLD_MULTIPLIER * INITIAL_THRESHOLD)
- static enum TIFFReadDirEntryErr TIFFReadDirEntryDataAndRealloc(
- TIFF* tif, uint64 offset, tmsize_t size, void** pdest)
- {
- #if SIZEOF_SIZE_T == 8
- tmsize_t threshold = INITIAL_THRESHOLD;
- #endif
- tmsize_t already_read = 0;
- assert( !isMapped(tif) );
- if (!SeekOK(tif,offset))
- return(TIFFReadDirEntryErrIo);
- /* On 64 bit processes, read first a maximum of 1 MB, then 10 MB, etc */
- /* so as to avoid allocating too much memory in case the file is too */
- /* short. We could ask for the file size, but this might be */
- /* expensive with some I/O layers (think of reading a gzipped file) */
- /* Restrict to 64 bit processes, so as to avoid reallocs() */
- /* on 32 bit processes where virtual memory is scarce. */
- while( already_read < size )
- {
- void* new_dest;
- tmsize_t bytes_read;
- tmsize_t to_read = size - already_read;
- #if SIZEOF_SIZE_T == 8
- if( to_read >= threshold && threshold < MAX_THRESHOLD )
- {
- to_read = threshold;
- threshold *= THRESHOLD_MULTIPLIER;
- }
- #endif
- new_dest = (uint8*) _TIFFrealloc(
- *pdest, already_read + to_read);
- if( new_dest == NULL )
- {
- TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
- "Failed to allocate memory for %s "
- "(%ld elements of %ld bytes each)",
- "TIFFReadDirEntryArray",
- (long) 1, (long) (already_read + to_read));
- return TIFFReadDirEntryErrAlloc;
- }
- *pdest = new_dest;
- bytes_read = TIFFReadFile(tif,
- (char*)*pdest + already_read, to_read);
- already_read += bytes_read;
- if (bytes_read != to_read) {
- return TIFFReadDirEntryErrIo;
- }
- }
- return TIFFReadDirEntryErrOk;
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryArrayWithLimit(
- TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize,
- void** value, uint64 maxcount)
- {
- int typesize;
- uint32 datasize;
- void* data;
- uint64 target_count64;
- int original_datasize_clamped;
- typesize=TIFFDataWidth(direntry->tdir_type);
- target_count64 = (direntry->tdir_count > maxcount) ?
- maxcount : direntry->tdir_count;
- if ((target_count64==0)||(typesize==0))
- {
- *value=0;
- return(TIFFReadDirEntryErrOk);
- }
- (void) desttypesize;
- /* We just want to know if the original tag size is more than 4 bytes
- * (classic TIFF) or 8 bytes (BigTIFF)
- */
- original_datasize_clamped =
- ((direntry->tdir_count > 10) ? 10 : (int)direntry->tdir_count) * typesize;
- /*
- * As a sanity check, make sure we have no more than a 2GB tag array
- * in either the current data type or the dest data type. This also
- * avoids problems with overflow of tmsize_t on 32bit systems.
- */
- if ((uint64)(2147483647/typesize)<target_count64)
- return(TIFFReadDirEntryErrSizesan);
- if ((uint64)(2147483647/desttypesize)<target_count64)
- return(TIFFReadDirEntryErrSizesan);
- *count=(uint32)target_count64;
- datasize=(*count)*typesize;
- assert((tmsize_t)datasize>0);
- if( isMapped(tif) && datasize > (uint64)tif->tif_size )
- return TIFFReadDirEntryErrIo;
- if( !isMapped(tif) &&
- (((tif->tif_flags&TIFF_BIGTIFF) && datasize > 8) ||
- (!(tif->tif_flags&TIFF_BIGTIFF) && datasize > 4)) )
- {
- data = NULL;
- }
- else
- {
- data=_TIFFCheckMalloc(tif, *count, typesize, "ReadDirEntryArray");
- if (data==0)
- return(TIFFReadDirEntryErrAlloc);
- }
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- if (original_datasize_clamped<=4)
- _TIFFmemcpy(data,&direntry->tdir_offset,datasize);
- else
- {
- enum TIFFReadDirEntryErr err;
- uint32 offset = direntry->tdir_offset.toff_long;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(&offset);
- if( isMapped(tif) )
- err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data);
- else
- err=TIFFReadDirEntryDataAndRealloc(tif,(uint64)offset,(tmsize_t)datasize,&data);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(data);
- return(err);
- }
- }
- }
- else
- {
- if (original_datasize_clamped<=8)
- _TIFFmemcpy(data,&direntry->tdir_offset,datasize);
- else
- {
- enum TIFFReadDirEntryErr err;
- uint64 offset = direntry->tdir_offset.toff_long8;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(&offset);
- if( isMapped(tif) )
- err=TIFFReadDirEntryData(tif,(uint64)offset,(tmsize_t)datasize,data);
- else
- err=TIFFReadDirEntryDataAndRealloc(tif,(uint64)offset,(tmsize_t)datasize,&data);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(data);
- return(err);
- }
- }
- }
- *value=data;
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryArray(TIFF* tif, TIFFDirEntry* direntry, uint32* count, uint32 desttypesize, void** value)
- {
- return TIFFReadDirEntryArrayWithLimit(tif, direntry, count,
- desttypesize, value, ~((uint64)0));
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryByteArray(TIFF* tif, TIFFDirEntry* direntry, uint8** value)
- {
- enum TIFFReadDirEntryErr err;
- uint32 count;
- void* origdata;
- uint8* data;
- switch (direntry->tdir_type)
- {
- case TIFF_ASCII:
- case TIFF_UNDEFINED:
- case TIFF_BYTE:
- case TIFF_SBYTE:
- case TIFF_SHORT:
- case TIFF_SSHORT:
- case TIFF_LONG:
- case TIFF_SLONG:
- case TIFF_LONG8:
- case TIFF_SLONG8:
- break;
- default:
- return(TIFFReadDirEntryErrType);
- }
- err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata);
- if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
- {
- *value=0;
- return(err);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_ASCII:
- case TIFF_UNDEFINED:
- case TIFF_BYTE:
- *value=(uint8*)origdata;
- return(TIFFReadDirEntryErrOk);
- case TIFF_SBYTE:
- {
- int8* m;
- uint32 n;
- m=(int8*)origdata;
- for (n=0; n<count; n++)
- {
- err=TIFFReadDirEntryCheckRangeByteSbyte(*m);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(origdata);
- return(err);
- }
- m++;
- }
- *value=(uint8*)origdata;
- return(TIFFReadDirEntryErrOk);
- }
- }
- data=(uint8*)_TIFFmalloc(count);
- if (data==0)
- {
- _TIFFfree(origdata);
- return(TIFFReadDirEntryErrAlloc);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_SHORT:
- {
- uint16* ma;
- uint8* mb;
- uint32 n;
- ma=(uint16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort(ma);
- err=TIFFReadDirEntryCheckRangeByteShort(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint8)(*ma++);
- }
- }
- break;
- case TIFF_SSHORT:
- {
- int16* ma;
- uint8* mb;
- uint32 n;
- ma=(int16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16*)ma);
- err=TIFFReadDirEntryCheckRangeByteSshort(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint8)(*ma++);
- }
- }
- break;
- case TIFF_LONG:
- {
- uint32* ma;
- uint8* mb;
- uint32 n;
- ma=(uint32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- err=TIFFReadDirEntryCheckRangeByteLong(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint8)(*ma++);
- }
- }
- break;
- case TIFF_SLONG:
- {
- int32* ma;
- uint8* mb;
- uint32 n;
- ma=(int32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32*)ma);
- err=TIFFReadDirEntryCheckRangeByteSlong(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint8)(*ma++);
- }
- }
- break;
- case TIFF_LONG8:
- {
- uint64* ma;
- uint8* mb;
- uint32 n;
- ma=(uint64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(ma);
- err=TIFFReadDirEntryCheckRangeByteLong8(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint8)(*ma++);
- }
- }
- break;
- case TIFF_SLONG8:
- {
- int64* ma;
- uint8* mb;
- uint32 n;
- ma=(int64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64*)ma);
- err=TIFFReadDirEntryCheckRangeByteSlong8(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint8)(*ma++);
- }
- }
- break;
- }
- _TIFFfree(origdata);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(data);
- return(err);
- }
- *value=data;
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntrySbyteArray(TIFF* tif, TIFFDirEntry* direntry, int8** value)
- {
- enum TIFFReadDirEntryErr err;
- uint32 count;
- void* origdata;
- int8* data;
- switch (direntry->tdir_type)
- {
- case TIFF_UNDEFINED:
- case TIFF_BYTE:
- case TIFF_SBYTE:
- case TIFF_SHORT:
- case TIFF_SSHORT:
- case TIFF_LONG:
- case TIFF_SLONG:
- case TIFF_LONG8:
- case TIFF_SLONG8:
- break;
- default:
- return(TIFFReadDirEntryErrType);
- }
- err=TIFFReadDirEntryArray(tif,direntry,&count,1,&origdata);
- if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
- {
- *value=0;
- return(err);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_UNDEFINED:
- case TIFF_BYTE:
- {
- uint8* m;
- uint32 n;
- m=(uint8*)origdata;
- for (n=0; n<count; n++)
- {
- err=TIFFReadDirEntryCheckRangeSbyteByte(*m);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(origdata);
- return(err);
- }
- m++;
- }
- *value=(int8*)origdata;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SBYTE:
- *value=(int8*)origdata;
- return(TIFFReadDirEntryErrOk);
- }
- data=(int8*)_TIFFmalloc(count);
- if (data==0)
- {
- _TIFFfree(origdata);
- return(TIFFReadDirEntryErrAlloc);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_SHORT:
- {
- uint16* ma;
- int8* mb;
- uint32 n;
- ma=(uint16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort(ma);
- err=TIFFReadDirEntryCheckRangeSbyteShort(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(int8)(*ma++);
- }
- }
- break;
- case TIFF_SSHORT:
- {
- int16* ma;
- int8* mb;
- uint32 n;
- ma=(int16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16*)ma);
- err=TIFFReadDirEntryCheckRangeSbyteSshort(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(int8)(*ma++);
- }
- }
- break;
- case TIFF_LONG:
- {
- uint32* ma;
- int8* mb;
- uint32 n;
- ma=(uint32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- err=TIFFReadDirEntryCheckRangeSbyteLong(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(int8)(*ma++);
- }
- }
- break;
- case TIFF_SLONG:
- {
- int32* ma;
- int8* mb;
- uint32 n;
- ma=(int32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32*)ma);
- err=TIFFReadDirEntryCheckRangeSbyteSlong(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(int8)(*ma++);
- }
- }
- break;
- case TIFF_LONG8:
- {
- uint64* ma;
- int8* mb;
- uint32 n;
- ma=(uint64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(ma);
- err=TIFFReadDirEntryCheckRangeSbyteLong8(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(int8)(*ma++);
- }
- }
- break;
- case TIFF_SLONG8:
- {
- int64* ma;
- int8* mb;
- uint32 n;
- ma=(int64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64*)ma);
- err=TIFFReadDirEntryCheckRangeSbyteSlong8(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(int8)(*ma++);
- }
- }
- break;
- }
- _TIFFfree(origdata);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(data);
- return(err);
- }
- *value=data;
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryShortArray(TIFF* tif, TIFFDirEntry* direntry, uint16** value)
- {
- enum TIFFReadDirEntryErr err;
- uint32 count;
- void* origdata;
- uint16* data;
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- case TIFF_SBYTE:
- case TIFF_SHORT:
- case TIFF_SSHORT:
- case TIFF_LONG:
- case TIFF_SLONG:
- case TIFF_LONG8:
- case TIFF_SLONG8:
- break;
- default:
- return(TIFFReadDirEntryErrType);
- }
- err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata);
- if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
- {
- *value=0;
- return(err);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_SHORT:
- *value=(uint16*)origdata;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfShort(*value,count);
- return(TIFFReadDirEntryErrOk);
- case TIFF_SSHORT:
- {
- int16* m;
- uint32 n;
- m=(int16*)origdata;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16*)m);
- err=TIFFReadDirEntryCheckRangeShortSshort(*m);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(origdata);
- return(err);
- }
- m++;
- }
- *value=(uint16*)origdata;
- return(TIFFReadDirEntryErrOk);
- }
- }
- data=(uint16*)_TIFFmalloc(count*2);
- if (data==0)
- {
- _TIFFfree(origdata);
- return(TIFFReadDirEntryErrAlloc);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- {
- uint8* ma;
- uint16* mb;
- uint32 n;
- ma=(uint8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- *mb++=(uint16)(*ma++);
- }
- break;
- case TIFF_SBYTE:
- {
- int8* ma;
- uint16* mb;
- uint32 n;
- ma=(int8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- err=TIFFReadDirEntryCheckRangeShortSbyte(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint16)(*ma++);
- }
- }
- break;
- case TIFF_LONG:
- {
- uint32* ma;
- uint16* mb;
- uint32 n;
- ma=(uint32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- err=TIFFReadDirEntryCheckRangeShortLong(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint16)(*ma++);
- }
- }
- break;
- case TIFF_SLONG:
- {
- int32* ma;
- uint16* mb;
- uint32 n;
- ma=(int32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32*)ma);
- err=TIFFReadDirEntryCheckRangeShortSlong(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint16)(*ma++);
- }
- }
- break;
- case TIFF_LONG8:
- {
- uint64* ma;
- uint16* mb;
- uint32 n;
- ma=(uint64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(ma);
- err=TIFFReadDirEntryCheckRangeShortLong8(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint16)(*ma++);
- }
- }
- break;
- case TIFF_SLONG8:
- {
- int64* ma;
- uint16* mb;
- uint32 n;
- ma=(int64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64*)ma);
- err=TIFFReadDirEntryCheckRangeShortSlong8(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint16)(*ma++);
- }
- }
- break;
- }
- _TIFFfree(origdata);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(data);
- return(err);
- }
- *value=data;
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntrySshortArray(TIFF* tif, TIFFDirEntry* direntry, int16** value)
- {
- enum TIFFReadDirEntryErr err;
- uint32 count;
- void* origdata;
- int16* data;
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- case TIFF_SBYTE:
- case TIFF_SHORT:
- case TIFF_SSHORT:
- case TIFF_LONG:
- case TIFF_SLONG:
- case TIFF_LONG8:
- case TIFF_SLONG8:
- break;
- default:
- return(TIFFReadDirEntryErrType);
- }
- err=TIFFReadDirEntryArray(tif,direntry,&count,2,&origdata);
- if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
- {
- *value=0;
- return(err);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_SHORT:
- {
- uint16* m;
- uint32 n;
- m=(uint16*)origdata;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort(m);
- err=TIFFReadDirEntryCheckRangeSshortShort(*m);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(origdata);
- return(err);
- }
- m++;
- }
- *value=(int16*)origdata;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SSHORT:
- *value=(int16*)origdata;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfShort((uint16*)(*value),count);
- return(TIFFReadDirEntryErrOk);
- }
- data=(int16*)_TIFFmalloc(count*2);
- if (data==0)
- {
- _TIFFfree(origdata);
- return(TIFFReadDirEntryErrAlloc);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- {
- uint8* ma;
- int16* mb;
- uint32 n;
- ma=(uint8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- *mb++=(int16)(*ma++);
- }
- break;
- case TIFF_SBYTE:
- {
- int8* ma;
- int16* mb;
- uint32 n;
- ma=(int8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- *mb++=(int16)(*ma++);
- }
- break;
- case TIFF_LONG:
- {
- uint32* ma;
- int16* mb;
- uint32 n;
- ma=(uint32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- err=TIFFReadDirEntryCheckRangeSshortLong(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(int16)(*ma++);
- }
- }
- break;
- case TIFF_SLONG:
- {
- int32* ma;
- int16* mb;
- uint32 n;
- ma=(int32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32*)ma);
- err=TIFFReadDirEntryCheckRangeSshortSlong(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(int16)(*ma++);
- }
- }
- break;
- case TIFF_LONG8:
- {
- uint64* ma;
- int16* mb;
- uint32 n;
- ma=(uint64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(ma);
- err=TIFFReadDirEntryCheckRangeSshortLong8(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(int16)(*ma++);
- }
- }
- break;
- case TIFF_SLONG8:
- {
- int64* ma;
- int16* mb;
- uint32 n;
- ma=(int64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64*)ma);
- err=TIFFReadDirEntryCheckRangeSshortSlong8(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(int16)(*ma++);
- }
- }
- break;
- }
- _TIFFfree(origdata);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(data);
- return(err);
- }
- *value=data;
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryLongArray(TIFF* tif, TIFFDirEntry* direntry, uint32** value)
- {
- enum TIFFReadDirEntryErr err;
- uint32 count;
- void* origdata;
- uint32* data;
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- case TIFF_SBYTE:
- case TIFF_SHORT:
- case TIFF_SSHORT:
- case TIFF_LONG:
- case TIFF_SLONG:
- case TIFF_LONG8:
- case TIFF_SLONG8:
- break;
- default:
- return(TIFFReadDirEntryErrType);
- }
- err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata);
- if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
- {
- *value=0;
- return(err);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_LONG:
- *value=(uint32*)origdata;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong(*value,count);
- return(TIFFReadDirEntryErrOk);
- case TIFF_SLONG:
- {
- int32* m;
- uint32 n;
- m=(int32*)origdata;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32*)m);
- err=TIFFReadDirEntryCheckRangeLongSlong(*m);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(origdata);
- return(err);
- }
- m++;
- }
- *value=(uint32*)origdata;
- return(TIFFReadDirEntryErrOk);
- }
- }
- data=(uint32*)_TIFFmalloc(count*4);
- if (data==0)
- {
- _TIFFfree(origdata);
- return(TIFFReadDirEntryErrAlloc);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- {
- uint8* ma;
- uint32* mb;
- uint32 n;
- ma=(uint8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- *mb++=(uint32)(*ma++);
- }
- break;
- case TIFF_SBYTE:
- {
- int8* ma;
- uint32* mb;
- uint32 n;
- ma=(int8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- err=TIFFReadDirEntryCheckRangeLongSbyte(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint32)(*ma++);
- }
- }
- break;
- case TIFF_SHORT:
- {
- uint16* ma;
- uint32* mb;
- uint32 n;
- ma=(uint16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort(ma);
- *mb++=(uint32)(*ma++);
- }
- }
- break;
- case TIFF_SSHORT:
- {
- int16* ma;
- uint32* mb;
- uint32 n;
- ma=(int16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16*)ma);
- err=TIFFReadDirEntryCheckRangeLongSshort(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint32)(*ma++);
- }
- }
- break;
- case TIFF_LONG8:
- {
- uint64* ma;
- uint32* mb;
- uint32 n;
- ma=(uint64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(ma);
- err=TIFFReadDirEntryCheckRangeLongLong8(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint32)(*ma++);
- }
- }
- break;
- case TIFF_SLONG8:
- {
- int64* ma;
- uint32* mb;
- uint32 n;
- ma=(int64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64*)ma);
- err=TIFFReadDirEntryCheckRangeLongSlong8(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint32)(*ma++);
- }
- }
- break;
- }
- _TIFFfree(origdata);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(data);
- return(err);
- }
- *value=data;
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntrySlongArray(TIFF* tif, TIFFDirEntry* direntry, int32** value)
- {
- enum TIFFReadDirEntryErr err;
- uint32 count;
- void* origdata;
- int32* data;
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- case TIFF_SBYTE:
- case TIFF_SHORT:
- case TIFF_SSHORT:
- case TIFF_LONG:
- case TIFF_SLONG:
- case TIFF_LONG8:
- case TIFF_SLONG8:
- break;
- default:
- return(TIFFReadDirEntryErrType);
- }
- err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata);
- if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
- {
- *value=0;
- return(err);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_LONG:
- {
- uint32* m;
- uint32 n;
- m=(uint32*)origdata;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32*)m);
- err=TIFFReadDirEntryCheckRangeSlongLong(*m);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(origdata);
- return(err);
- }
- m++;
- }
- *value=(int32*)origdata;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SLONG:
- *value=(int32*)origdata;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong((uint32*)(*value),count);
- return(TIFFReadDirEntryErrOk);
- }
- data=(int32*)_TIFFmalloc(count*4);
- if (data==0)
- {
- _TIFFfree(origdata);
- return(TIFFReadDirEntryErrAlloc);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- {
- uint8* ma;
- int32* mb;
- uint32 n;
- ma=(uint8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- *mb++=(int32)(*ma++);
- }
- break;
- case TIFF_SBYTE:
- {
- int8* ma;
- int32* mb;
- uint32 n;
- ma=(int8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- *mb++=(int32)(*ma++);
- }
- break;
- case TIFF_SHORT:
- {
- uint16* ma;
- int32* mb;
- uint32 n;
- ma=(uint16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort(ma);
- *mb++=(int32)(*ma++);
- }
- }
- break;
- case TIFF_SSHORT:
- {
- int16* ma;
- int32* mb;
- uint32 n;
- ma=(int16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16*)ma);
- *mb++=(int32)(*ma++);
- }
- }
- break;
- case TIFF_LONG8:
- {
- uint64* ma;
- int32* mb;
- uint32 n;
- ma=(uint64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(ma);
- err=TIFFReadDirEntryCheckRangeSlongLong8(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(int32)(*ma++);
- }
- }
- break;
- case TIFF_SLONG8:
- {
- int64* ma;
- int32* mb;
- uint32 n;
- ma=(int64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64*)ma);
- err=TIFFReadDirEntryCheckRangeSlongSlong8(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(int32)(*ma++);
- }
- }
- break;
- }
- _TIFFfree(origdata);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(data);
- return(err);
- }
- *value=data;
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8ArrayWithLimit(
- TIFF* tif, TIFFDirEntry* direntry, uint64** value, uint64 maxcount)
- {
- enum TIFFReadDirEntryErr err;
- uint32 count;
- void* origdata;
- uint64* data;
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- case TIFF_SBYTE:
- case TIFF_SHORT:
- case TIFF_SSHORT:
- case TIFF_LONG:
- case TIFF_SLONG:
- case TIFF_LONG8:
- case TIFF_SLONG8:
- break;
- default:
- return(TIFFReadDirEntryErrType);
- }
- err=TIFFReadDirEntryArrayWithLimit(tif,direntry,&count,8,&origdata,maxcount);
- if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
- {
- *value=0;
- return(err);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_LONG8:
- *value=(uint64*)origdata;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong8(*value,count);
- return(TIFFReadDirEntryErrOk);
- case TIFF_SLONG8:
- {
- int64* m;
- uint32 n;
- m=(int64*)origdata;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64*)m);
- err=TIFFReadDirEntryCheckRangeLong8Slong8(*m);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(origdata);
- return(err);
- }
- m++;
- }
- *value=(uint64*)origdata;
- return(TIFFReadDirEntryErrOk);
- }
- }
- data=(uint64*)_TIFFmalloc(count*8);
- if (data==0)
- {
- _TIFFfree(origdata);
- return(TIFFReadDirEntryErrAlloc);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- {
- uint8* ma;
- uint64* mb;
- uint32 n;
- ma=(uint8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- *mb++=(uint64)(*ma++);
- }
- break;
- case TIFF_SBYTE:
- {
- int8* ma;
- uint64* mb;
- uint32 n;
- ma=(int8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- err=TIFFReadDirEntryCheckRangeLong8Sbyte(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint64)(*ma++);
- }
- }
- break;
- case TIFF_SHORT:
- {
- uint16* ma;
- uint64* mb;
- uint32 n;
- ma=(uint16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort(ma);
- *mb++=(uint64)(*ma++);
- }
- }
- break;
- case TIFF_SSHORT:
- {
- int16* ma;
- uint64* mb;
- uint32 n;
- ma=(int16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16*)ma);
- err=TIFFReadDirEntryCheckRangeLong8Sshort(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint64)(*ma++);
- }
- }
- break;
- case TIFF_LONG:
- {
- uint32* ma;
- uint64* mb;
- uint32 n;
- ma=(uint32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- *mb++=(uint64)(*ma++);
- }
- }
- break;
- case TIFF_SLONG:
- {
- int32* ma;
- uint64* mb;
- uint32 n;
- ma=(int32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32*)ma);
- err=TIFFReadDirEntryCheckRangeLong8Slong(*ma);
- if (err!=TIFFReadDirEntryErrOk)
- break;
- *mb++=(uint64)(*ma++);
- }
- }
- break;
- }
- _TIFFfree(origdata);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(data);
- return(err);
- }
- *value=data;
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryLong8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
- {
- return TIFFReadDirEntryLong8ArrayWithLimit(tif, direntry, value, ~((uint64)0));
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntrySlong8Array(TIFF* tif, TIFFDirEntry* direntry, int64** value)
- {
- enum TIFFReadDirEntryErr err;
- uint32 count;
- void* origdata;
- int64* data;
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- case TIFF_SBYTE:
- case TIFF_SHORT:
- case TIFF_SSHORT:
- case TIFF_LONG:
- case TIFF_SLONG:
- case TIFF_LONG8:
- case TIFF_SLONG8:
- break;
- default:
- return(TIFFReadDirEntryErrType);
- }
- err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
- if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
- {
- *value=0;
- return(err);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_LONG8:
- {
- uint64* m;
- uint32 n;
- m=(uint64*)origdata;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(m);
- err=TIFFReadDirEntryCheckRangeSlong8Long8(*m);
- if (err!=TIFFReadDirEntryErrOk)
- {
- _TIFFfree(origdata);
- return(err);
- }
- m++;
- }
- *value=(int64*)origdata;
- return(TIFFReadDirEntryErrOk);
- }
- case TIFF_SLONG8:
- *value=(int64*)origdata;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong8((uint64*)(*value),count);
- return(TIFFReadDirEntryErrOk);
- }
- data=(int64*)_TIFFmalloc(count*8);
- if (data==0)
- {
- _TIFFfree(origdata);
- return(TIFFReadDirEntryErrAlloc);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- {
- uint8* ma;
- int64* mb;
- uint32 n;
- ma=(uint8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- *mb++=(int64)(*ma++);
- }
- break;
- case TIFF_SBYTE:
- {
- int8* ma;
- int64* mb;
- uint32 n;
- ma=(int8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- *mb++=(int64)(*ma++);
- }
- break;
- case TIFF_SHORT:
- {
- uint16* ma;
- int64* mb;
- uint32 n;
- ma=(uint16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort(ma);
- *mb++=(int64)(*ma++);
- }
- }
- break;
- case TIFF_SSHORT:
- {
- int16* ma;
- int64* mb;
- uint32 n;
- ma=(int16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16*)ma);
- *mb++=(int64)(*ma++);
- }
- }
- break;
- case TIFF_LONG:
- {
- uint32* ma;
- int64* mb;
- uint32 n;
- ma=(uint32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- *mb++=(int64)(*ma++);
- }
- }
- break;
- case TIFF_SLONG:
- {
- int32* ma;
- int64* mb;
- uint32 n;
- ma=(int32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32*)ma);
- *mb++=(int64)(*ma++);
- }
- }
- break;
- }
- _TIFFfree(origdata);
- *value=data;
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryFloatArray(TIFF* tif, TIFFDirEntry* direntry, float** value)
- {
- enum TIFFReadDirEntryErr err;
- uint32 count;
- void* origdata;
- float* data;
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- case TIFF_SBYTE:
- case TIFF_SHORT:
- case TIFF_SSHORT:
- case TIFF_LONG:
- case TIFF_SLONG:
- case TIFF_LONG8:
- case TIFF_SLONG8:
- case TIFF_RATIONAL:
- case TIFF_SRATIONAL:
- case TIFF_FLOAT:
- case TIFF_DOUBLE:
- break;
- default:
- return(TIFFReadDirEntryErrType);
- }
- err=TIFFReadDirEntryArray(tif,direntry,&count,4,&origdata);
- if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
- {
- *value=0;
- return(err);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_FLOAT:
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong((uint32*)origdata,count);
- TIFFCvtIEEEDoubleToNative(tif,count,(float*)origdata);
- *value=(float*)origdata;
- return(TIFFReadDirEntryErrOk);
- }
- data=(float*)_TIFFmalloc(count*sizeof(float));
- if (data==0)
- {
- _TIFFfree(origdata);
- return(TIFFReadDirEntryErrAlloc);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- {
- uint8* ma;
- float* mb;
- uint32 n;
- ma=(uint8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- *mb++=(float)(*ma++);
- }
- break;
- case TIFF_SBYTE:
- {
- int8* ma;
- float* mb;
- uint32 n;
- ma=(int8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- *mb++=(float)(*ma++);
- }
- break;
- case TIFF_SHORT:
- {
- uint16* ma;
- float* mb;
- uint32 n;
- ma=(uint16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort(ma);
- *mb++=(float)(*ma++);
- }
- }
- break;
- case TIFF_SSHORT:
- {
- int16* ma;
- float* mb;
- uint32 n;
- ma=(int16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16*)ma);
- *mb++=(float)(*ma++);
- }
- }
- break;
- case TIFF_LONG:
- {
- uint32* ma;
- float* mb;
- uint32 n;
- ma=(uint32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- *mb++=(float)(*ma++);
- }
- }
- break;
- case TIFF_SLONG:
- {
- int32* ma;
- float* mb;
- uint32 n;
- ma=(int32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32*)ma);
- *mb++=(float)(*ma++);
- }
- }
- break;
- case TIFF_LONG8:
- {
- uint64* ma;
- float* mb;
- uint32 n;
- ma=(uint64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(ma);
- #if defined(__WIN32__) && (_MSC_VER < 1500)
- /*
- * XXX: MSVC 6.0 does not support
- * conversion of 64-bit integers into
- * floating point values.
- */
- *mb++ = _TIFFUInt64ToFloat(*ma++);
- #else
- *mb++ = (float)(*ma++);
- #endif
- }
- }
- break;
- case TIFF_SLONG8:
- {
- int64* ma;
- float* mb;
- uint32 n;
- ma=(int64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64*)ma);
- *mb++=(float)(*ma++);
- }
- }
- break;
- case TIFF_RATIONAL:
- {
- uint32* ma;
- uint32 maa;
- uint32 mab;
- float* mb;
- uint32 n;
- ma=(uint32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- maa=*ma++;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- mab=*ma++;
- if (mab==0)
- *mb++=0.0;
- else
- *mb++=(float)maa/(float)mab;
- }
- }
- break;
- case TIFF_SRATIONAL:
- {
- uint32* ma;
- int32 maa;
- uint32 mab;
- float* mb;
- uint32 n;
- ma=(uint32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- maa=*(int32*)ma;
- ma++;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- mab=*ma++;
- if (mab==0)
- *mb++=0.0;
- else
- *mb++=(float)maa/(float)mab;
- }
- }
- break;
- case TIFF_DOUBLE:
- {
- double* ma;
- float* mb;
- uint32 n;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong8((uint64*)origdata,count);
- TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata);
- ma=(double*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- double val = *ma++;
- if( val > FLT_MAX )
- val = FLT_MAX;
- else if( val < -FLT_MAX )
- val = -FLT_MAX;
- *mb++=(float)val;
- }
- }
- break;
- }
- _TIFFfree(origdata);
- *value=data;
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr
- TIFFReadDirEntryDoubleArray(TIFF* tif, TIFFDirEntry* direntry, double** value)
- {
- enum TIFFReadDirEntryErr err;
- uint32 count;
- void* origdata;
- double* data;
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- case TIFF_SBYTE:
- case TIFF_SHORT:
- case TIFF_SSHORT:
- case TIFF_LONG:
- case TIFF_SLONG:
- case TIFF_LONG8:
- case TIFF_SLONG8:
- case TIFF_RATIONAL:
- case TIFF_SRATIONAL:
- case TIFF_FLOAT:
- case TIFF_DOUBLE:
- break;
- default:
- return(TIFFReadDirEntryErrType);
- }
- err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
- if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
- {
- *value=0;
- return(err);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_DOUBLE:
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong8((uint64*)origdata,count);
- TIFFCvtIEEEDoubleToNative(tif,count,(double*)origdata);
- *value=(double*)origdata;
- return(TIFFReadDirEntryErrOk);
- }
- data=(double*)_TIFFmalloc(count*sizeof(double));
- if (data==0)
- {
- _TIFFfree(origdata);
- return(TIFFReadDirEntryErrAlloc);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_BYTE:
- {
- uint8* ma;
- double* mb;
- uint32 n;
- ma=(uint8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- *mb++=(double)(*ma++);
- }
- break;
- case TIFF_SBYTE:
- {
- int8* ma;
- double* mb;
- uint32 n;
- ma=(int8*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- *mb++=(double)(*ma++);
- }
- break;
- case TIFF_SHORT:
- {
- uint16* ma;
- double* mb;
- uint32 n;
- ma=(uint16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort(ma);
- *mb++=(double)(*ma++);
- }
- }
- break;
- case TIFF_SSHORT:
- {
- int16* ma;
- double* mb;
- uint32 n;
- ma=(int16*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16*)ma);
- *mb++=(double)(*ma++);
- }
- }
- break;
- case TIFF_LONG:
- {
- uint32* ma;
- double* mb;
- uint32 n;
- ma=(uint32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- *mb++=(double)(*ma++);
- }
- }
- break;
- case TIFF_SLONG:
- {
- int32* ma;
- double* mb;
- uint32 n;
- ma=(int32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32*)ma);
- *mb++=(double)(*ma++);
- }
- }
- break;
- case TIFF_LONG8:
- {
- uint64* ma;
- double* mb;
- uint32 n;
- ma=(uint64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(ma);
- #if defined(__WIN32__) && (_MSC_VER < 1500)
- /*
- * XXX: MSVC 6.0 does not support
- * conversion of 64-bit integers into
- * floating point values.
- */
- *mb++ = _TIFFUInt64ToDouble(*ma++);
- #else
- *mb++ = (double)(*ma++);
- #endif
- }
- }
- break;
- case TIFF_SLONG8:
- {
- int64* ma;
- double* mb;
- uint32 n;
- ma=(int64*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64*)ma);
- *mb++=(double)(*ma++);
- }
- }
- break;
- case TIFF_RATIONAL:
- {
- uint32* ma;
- uint32 maa;
- uint32 mab;
- double* mb;
- uint32 n;
- ma=(uint32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- maa=*ma++;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- mab=*ma++;
- if (mab==0)
- *mb++=0.0;
- else
- *mb++=(double)maa/(double)mab;
- }
- }
- break;
- case TIFF_SRATIONAL:
- {
- uint32* ma;
- int32 maa;
- uint32 mab;
- double* mb;
- uint32 n;
- ma=(uint32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- maa=*(int32*)ma;
- ma++;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- mab=*ma++;
- if (mab==0)
- *mb++=0.0;
- else
- *mb++=(double)maa/(double)mab;
- }
- }
- break;
- case TIFF_FLOAT:
- {
- float* ma;
- double* mb;
- uint32 n;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong((uint32*)origdata,count);
- TIFFCvtIEEEFloatToNative(tif,count,(float*)origdata);
- ma=(float*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- *mb++=(double)(*ma++);
- }
- break;
- }
- _TIFFfree(origdata);
- *value=data;
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryIfd8Array(TIFF* tif, TIFFDirEntry* direntry, uint64** value)
- {
- enum TIFFReadDirEntryErr err;
- uint32 count;
- void* origdata;
- uint64* data;
- switch (direntry->tdir_type)
- {
- case TIFF_LONG:
- case TIFF_LONG8:
- case TIFF_IFD:
- case TIFF_IFD8:
- break;
- default:
- return(TIFFReadDirEntryErrType);
- }
- err=TIFFReadDirEntryArray(tif,direntry,&count,8,&origdata);
- if ((err!=TIFFReadDirEntryErrOk)||(origdata==0))
- {
- *value=0;
- return(err);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_LONG8:
- case TIFF_IFD8:
- *value=(uint64*)origdata;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong8(*value,count);
- return(TIFFReadDirEntryErrOk);
- }
- data=(uint64*)_TIFFmalloc(count*8);
- if (data==0)
- {
- _TIFFfree(origdata);
- return(TIFFReadDirEntryErrAlloc);
- }
- switch (direntry->tdir_type)
- {
- case TIFF_LONG:
- case TIFF_IFD:
- {
- uint32* ma;
- uint64* mb;
- uint32 n;
- ma=(uint32*)origdata;
- mb=data;
- for (n=0; n<count; n++)
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(ma);
- *mb++=(uint64)(*ma++);
- }
- }
- break;
- }
- _TIFFfree(origdata);
- *value=data;
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value)
- {
- enum TIFFReadDirEntryErr err;
- uint16* m;
- uint16* na;
- uint16 nb;
- if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel)
- return(TIFFReadDirEntryErrCount);
- err=TIFFReadDirEntryShortArray(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk || m == NULL)
- return(err);
- na=m;
- nb=tif->tif_dir.td_samplesperpixel;
- *value=*na++;
- nb--;
- while (nb>0)
- {
- if (*na++!=*value)
- {
- err=TIFFReadDirEntryErrPsdif;
- break;
- }
- nb--;
- }
- _TIFFfree(m);
- return(err);
- }
- #if 0
- static enum TIFFReadDirEntryErr TIFFReadDirEntryPersampleDouble(TIFF* tif, TIFFDirEntry* direntry, double* value)
- {
- enum TIFFReadDirEntryErr err;
- double* m;
- double* na;
- uint16 nb;
- if (direntry->tdir_count<(uint64)tif->tif_dir.td_samplesperpixel)
- return(TIFFReadDirEntryErrCount);
- err=TIFFReadDirEntryDoubleArray(tif,direntry,&m);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- na=m;
- nb=tif->tif_dir.td_samplesperpixel;
- *value=*na++;
- nb--;
- while (nb>0)
- {
- if (*na++!=*value)
- {
- err=TIFFReadDirEntryErrPsdif;
- break;
- }
- nb--;
- }
- _TIFFfree(m);
- return(err);
- }
- #endif
- static void TIFFReadDirEntryCheckedByte(TIFF* tif, TIFFDirEntry* direntry, uint8* value)
- {
- (void) tif;
- *value=*(uint8*)(&direntry->tdir_offset);
- }
- static void TIFFReadDirEntryCheckedSbyte(TIFF* tif, TIFFDirEntry* direntry, int8* value)
- {
- (void) tif;
- *value=*(int8*)(&direntry->tdir_offset);
- }
- static void TIFFReadDirEntryCheckedShort(TIFF* tif, TIFFDirEntry* direntry, uint16* value)
- {
- *value = direntry->tdir_offset.toff_short;
- /* *value=*(uint16*)(&direntry->tdir_offset); */
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort(value);
- }
- static void TIFFReadDirEntryCheckedSshort(TIFF* tif, TIFFDirEntry* direntry, int16* value)
- {
- *value=*(int16*)(&direntry->tdir_offset);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16*)value);
- }
- static void TIFFReadDirEntryCheckedLong(TIFF* tif, TIFFDirEntry* direntry, uint32* value)
- {
- *value=*(uint32*)(&direntry->tdir_offset);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(value);
- }
- static void TIFFReadDirEntryCheckedSlong(TIFF* tif, TIFFDirEntry* direntry, int32* value)
- {
- *value=*(int32*)(&direntry->tdir_offset);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32*)value);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedLong8(TIFF* tif, TIFFDirEntry* direntry, uint64* value)
- {
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- enum TIFFReadDirEntryErr err;
- uint32 offset = direntry->tdir_offset.toff_long;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(&offset);
- err=TIFFReadDirEntryData(tif,offset,8,value);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- }
- else
- *value = direntry->tdir_offset.toff_long8;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(value);
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSlong8(TIFF* tif, TIFFDirEntry* direntry, int64* value)
- {
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- enum TIFFReadDirEntryErr err;
- uint32 offset = direntry->tdir_offset.toff_long;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(&offset);
- err=TIFFReadDirEntryData(tif,offset,8,value);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- }
- else
- *value=*(int64*)(&direntry->tdir_offset);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64*)value);
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedRational(TIFF* tif, TIFFDirEntry* direntry, double* value)
- {
- UInt64Aligned_t m;
- assert(sizeof(double)==8);
- assert(sizeof(uint64)==8);
- assert(sizeof(uint32)==4);
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- enum TIFFReadDirEntryErr err;
- uint32 offset = direntry->tdir_offset.toff_long;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(&offset);
- err=TIFFReadDirEntryData(tif,offset,8,m.i);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- }
- else
- m.l = direntry->tdir_offset.toff_long8;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong(m.i,2);
- /* Not completely sure what we should do when m.i[1]==0, but some */
- /* sanitizers do not like division by 0.0: */
- /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
- if (m.i[0]==0 || m.i[1]==0)
- *value=0.0;
- else
- *value=(double)m.i[0]/(double)m.i[1];
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedSrational(TIFF* tif, TIFFDirEntry* direntry, double* value)
- {
- UInt64Aligned_t m;
- assert(sizeof(double)==8);
- assert(sizeof(uint64)==8);
- assert(sizeof(int32)==4);
- assert(sizeof(uint32)==4);
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- enum TIFFReadDirEntryErr err;
- uint32 offset = direntry->tdir_offset.toff_long;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(&offset);
- err=TIFFReadDirEntryData(tif,offset,8,m.i);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- }
- else
- m.l=direntry->tdir_offset.toff_long8;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong(m.i,2);
- /* Not completely sure what we should do when m.i[1]==0, but some */
- /* sanitizers do not like division by 0.0: */
- /* http://bugzilla.maptools.org/show_bug.cgi?id=2644 */
- if ((int32)m.i[0]==0 || m.i[1]==0)
- *value=0.0;
- else
- *value=(double)((int32)m.i[0])/(double)m.i[1];
- return(TIFFReadDirEntryErrOk);
- }
- static void TIFFReadDirEntryCheckedFloat(TIFF* tif, TIFFDirEntry* direntry, float* value)
- {
- union
- {
- float f;
- uint32 i;
- } float_union;
- assert(sizeof(float)==4);
- assert(sizeof(uint32)==4);
- assert(sizeof(float_union)==4);
- float_union.i=*(uint32*)(&direntry->tdir_offset);
- *value=float_union.f;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32*)value);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckedDouble(TIFF* tif, TIFFDirEntry* direntry, double* value)
- {
- assert(sizeof(double)==8);
- assert(sizeof(uint64)==8);
- assert(sizeof(UInt64Aligned_t)==8);
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- enum TIFFReadDirEntryErr err;
- uint32 offset = direntry->tdir_offset.toff_long;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(&offset);
- err=TIFFReadDirEntryData(tif,offset,8,value);
- if (err!=TIFFReadDirEntryErrOk)
- return(err);
- }
- else
- {
- UInt64Aligned_t uint64_union;
- uint64_union.l=direntry->tdir_offset.toff_long8;
- *value=uint64_union.d;
- }
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64*)value);
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSbyte(int8 value)
- {
- if (value<0)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteShort(uint16 value)
- {
- if (value>0xFF)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSshort(int16 value)
- {
- if ((value<0)||(value>0xFF))
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong(uint32 value)
- {
- if (value>0xFF)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong(int32 value)
- {
- if ((value<0)||(value>0xFF))
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteLong8(uint64 value)
- {
- if (value>0xFF)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeByteSlong8(int64 value)
- {
- if ((value<0)||(value>0xFF))
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteByte(uint8 value)
- {
- if (value>0x7F)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteShort(uint16 value)
- {
- if (value>0x7F)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSshort(int16 value)
- {
- if ((value<-0x80)||(value>0x7F))
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong(uint32 value)
- {
- if (value>0x7F)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong(int32 value)
- {
- if ((value<-0x80)||(value>0x7F))
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteLong8(uint64 value)
- {
- if (value>0x7F)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSbyteSlong8(int64 value)
- {
- if ((value<-0x80)||(value>0x7F))
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSbyte(int8 value)
- {
- if (value<0)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSshort(int16 value)
- {
- if (value<0)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong(uint32 value)
- {
- if (value>0xFFFF)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong(int32 value)
- {
- if ((value<0)||(value>0xFFFF))
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortLong8(uint64 value)
- {
- if (value>0xFFFF)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeShortSlong8(int64 value)
- {
- if ((value<0)||(value>0xFFFF))
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortShort(uint16 value)
- {
- if (value>0x7FFF)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong(uint32 value)
- {
- if (value>0x7FFF)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong(int32 value)
- {
- if ((value<-0x8000)||(value>0x7FFF))
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortLong8(uint64 value)
- {
- if (value>0x7FFF)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeSshortSlong8(int64 value)
- {
- if ((value<-0x8000)||(value>0x7FFF))
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSbyte(int8 value)
- {
- if (value<0)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSshort(int16 value)
- {
- if (value<0)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr TIFFReadDirEntryCheckRangeLongSlong(int32 value)
- {
- if (value<0)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr
- TIFFReadDirEntryCheckRangeLongLong8(uint64 value)
- {
- if (value > TIFF_UINT32_MAX)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr
- TIFFReadDirEntryCheckRangeLongSlong8(int64 value)
- {
- if ((value < 0) || (value > (int64) TIFF_UINT32_MAX))
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr
- TIFFReadDirEntryCheckRangeSlongLong(uint32 value)
- {
- if (value > 0x7FFFFFFFUL)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- /* Check that the 8-byte unsigned value can fit in a 4-byte unsigned range */
- static enum TIFFReadDirEntryErr
- TIFFReadDirEntryCheckRangeSlongLong8(uint64 value)
- {
- if (value > 0x7FFFFFFF)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- /* Check that the 8-byte signed value can fit in a 4-byte signed range */
- static enum TIFFReadDirEntryErr
- TIFFReadDirEntryCheckRangeSlongSlong8(int64 value)
- {
- if ((value < 0-((int64) 0x7FFFFFFF+1)) || (value > 0x7FFFFFFF))
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr
- TIFFReadDirEntryCheckRangeLong8Sbyte(int8 value)
- {
- if (value < 0)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr
- TIFFReadDirEntryCheckRangeLong8Sshort(int16 value)
- {
- if (value < 0)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr
- TIFFReadDirEntryCheckRangeLong8Slong(int32 value)
- {
- if (value < 0)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr
- TIFFReadDirEntryCheckRangeLong8Slong8(int64 value)
- {
- if (value < 0)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr
- TIFFReadDirEntryCheckRangeSlong8Long8(uint64 value)
- {
- if (value > TIFF_INT64_MAX)
- return(TIFFReadDirEntryErrRange);
- else
- return(TIFFReadDirEntryErrOk);
- }
- static enum TIFFReadDirEntryErr
- TIFFReadDirEntryData(TIFF* tif, uint64 offset, tmsize_t size, void* dest)
- {
- assert(size>0);
- if (!isMapped(tif)) {
- if (!SeekOK(tif,offset))
- return(TIFFReadDirEntryErrIo);
- if (!ReadOK(tif,dest,size))
- return(TIFFReadDirEntryErrIo);
- } else {
- size_t ma,mb;
- ma=(size_t)offset;
- if( (uint64)ma!=offset ||
- ma > (~(size_t)0) - (size_t)size )
- {
- return TIFFReadDirEntryErrIo;
- }
- mb=ma+size;
- if (mb > (uint64)tif->tif_size)
- return(TIFFReadDirEntryErrIo);
- _TIFFmemcpy(dest,tif->tif_base+ma,size);
- }
- return(TIFFReadDirEntryErrOk);
- }
- static void TIFFReadDirEntryOutputErr(TIFF* tif, enum TIFFReadDirEntryErr err, const char* module, const char* tagname, int recover)
- {
- if (!recover) {
- switch (err) {
- case TIFFReadDirEntryErrCount:
- TIFFErrorExt(tif->tif_clientdata, module,
- "Incorrect count for \"%s\"",
- tagname);
- break;
- case TIFFReadDirEntryErrType:
- TIFFErrorExt(tif->tif_clientdata, module,
- "Incompatible type for \"%s\"",
- tagname);
- break;
- case TIFFReadDirEntryErrIo:
- TIFFErrorExt(tif->tif_clientdata, module,
- "IO error during reading of \"%s\"",
- tagname);
- break;
- case TIFFReadDirEntryErrRange:
- TIFFErrorExt(tif->tif_clientdata, module,
- "Incorrect value for \"%s\"",
- tagname);
- break;
- case TIFFReadDirEntryErrPsdif:
- TIFFErrorExt(tif->tif_clientdata, module,
- "Cannot handle different values per sample for \"%s\"",
- tagname);
- break;
- case TIFFReadDirEntryErrSizesan:
- TIFFErrorExt(tif->tif_clientdata, module,
- "Sanity check on size of \"%s\" value failed",
- tagname);
- break;
- case TIFFReadDirEntryErrAlloc:
- TIFFErrorExt(tif->tif_clientdata, module,
- "Out of memory reading of \"%s\"",
- tagname);
- break;
- default:
- assert(0); /* we should never get here */
- break;
- }
- } else {
- switch (err) {
- case TIFFReadDirEntryErrCount:
- TIFFWarningExt(tif->tif_clientdata, module,
- "Incorrect count for \"%s\"; tag ignored",
- tagname);
- break;
- case TIFFReadDirEntryErrType:
- TIFFWarningExt(tif->tif_clientdata, module,
- "Incompatible type for \"%s\"; tag ignored",
- tagname);
- break;
- case TIFFReadDirEntryErrIo:
- TIFFWarningExt(tif->tif_clientdata, module,
- "IO error during reading of \"%s\"; tag ignored",
- tagname);
- break;
- case TIFFReadDirEntryErrRange:
- TIFFWarningExt(tif->tif_clientdata, module,
- "Incorrect value for \"%s\"; tag ignored",
- tagname);
- break;
- case TIFFReadDirEntryErrPsdif:
- TIFFWarningExt(tif->tif_clientdata, module,
- "Cannot handle different values per sample for \"%s\"; tag ignored",
- tagname);
- break;
- case TIFFReadDirEntryErrSizesan:
- TIFFWarningExt(tif->tif_clientdata, module,
- "Sanity check on size of \"%s\" value failed; tag ignored",
- tagname);
- break;
- case TIFFReadDirEntryErrAlloc:
- TIFFWarningExt(tif->tif_clientdata, module,
- "Out of memory reading of \"%s\"; tag ignored",
- tagname);
- break;
- default:
- assert(0); /* we should never get here */
- break;
- }
- }
- }
- /*
- * Return the maximum number of color channels specified for a given photometric
- * type. 0 is returned if photometric type isn't supported or no default value
- * is defined by the specification.
- */
- static int _TIFFGetMaxColorChannels( uint16 photometric )
- {
- switch (photometric) {
- case PHOTOMETRIC_PALETTE:
- case PHOTOMETRIC_MINISWHITE:
- case PHOTOMETRIC_MINISBLACK:
- return 1;
- case PHOTOMETRIC_YCBCR:
- case PHOTOMETRIC_RGB:
- case PHOTOMETRIC_CIELAB:
- case PHOTOMETRIC_LOGLUV:
- case PHOTOMETRIC_ITULAB:
- case PHOTOMETRIC_ICCLAB:
- return 3;
- case PHOTOMETRIC_SEPARATED:
- case PHOTOMETRIC_MASK:
- return 4;
- case PHOTOMETRIC_LOGL:
- case PHOTOMETRIC_CFA:
- default:
- return 0;
- }
- }
- static int ByteCountLooksBad(TIFF* tif)
- {
- /*
- * Assume we have wrong StripByteCount value (in case
- * of single strip) in following cases:
- * - it is equal to zero along with StripOffset;
- * - it is larger than file itself (in case of uncompressed
- * image);
- * - it is smaller than the size of the bytes per row
- * multiplied on the number of rows. The last case should
- * not be checked in the case of writing new image,
- * because we may do not know the exact strip size
- * until the whole image will be written and directory
- * dumped out.
- */
- uint64 bytecount = TIFFGetStrileByteCount(tif, 0);
- uint64 offset = TIFFGetStrileOffset(tif, 0);
- uint64 filesize;
- if( offset == 0 )
- return 0;
- if (bytecount == 0)
- return 1;
- if ( tif->tif_dir.td_compression != COMPRESSION_NONE )
- return 0;
- filesize = TIFFGetFileSize(tif);
- if( offset <= filesize && bytecount > filesize - offset )
- return 1;
- if( tif->tif_mode == O_RDONLY )
- {
- uint64 scanlinesize = TIFFScanlineSize64(tif);
- if( tif->tif_dir.td_imagelength > 0 &&
- scanlinesize > TIFF_UINT64_MAX / tif->tif_dir.td_imagelength )
- {
- return 1;
- }
- if( bytecount < scanlinesize * tif->tif_dir.td_imagelength)
- return 1;
- }
- return 0;
- }
- /*
- * Read the next TIFF directory from a file and convert it to the internal
- * format. We read directories sequentially.
- */
- int
- TIFFReadDirectory(TIFF* tif)
- {
- static const char module[] = "TIFFReadDirectory";
- TIFFDirEntry* dir;
- uint16 dircount;
- TIFFDirEntry* dp;
- uint16 di;
- const TIFFField* fip;
- uint32 fii=FAILED_FII;
- toff_t nextdiroff;
- int bitspersample_read = FALSE;
- int color_channels;
- tif->tif_diroff=tif->tif_nextdiroff;
- if (!TIFFCheckDirOffset(tif,tif->tif_nextdiroff))
- return 0; /* last offset or bad offset (IFD looping) */
- (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */
- tif->tif_curdir++;
- nextdiroff = tif->tif_nextdiroff;
- dircount=TIFFFetchDirectory(tif,nextdiroff,&dir,&tif->tif_nextdiroff);
- if (!dircount)
- {
- TIFFErrorExt(tif->tif_clientdata,module,
- "Failed to read directory at offset " TIFF_UINT64_FORMAT,nextdiroff);
- return 0;
- }
- TIFFReadDirectoryCheckOrder(tif,dir,dircount);
- /*
- * Mark duplicates of any tag to be ignored (bugzilla 1994)
- * to avoid certain pathological problems.
- */
- {
- TIFFDirEntry* ma;
- uint16 mb;
- for (ma=dir, mb=0; mb<dircount; ma++, mb++)
- {
- TIFFDirEntry* na;
- uint16 nb;
- for (na=ma+1, nb=mb+1; nb<dircount; na++, nb++)
- {
- if (ma->tdir_tag == na->tdir_tag) {
- na->tdir_ignore = TRUE;
- }
- }
- }
- }
-
- tif->tif_flags &= ~TIFF_BEENWRITING; /* reset before new dir */
- tif->tif_flags &= ~TIFF_BUF4WRITE; /* reset before new dir */
- tif->tif_flags &= ~TIFF_CHOPPEDUPARRAYS;
- /* free any old stuff and reinit */
- TIFFFreeDirectory(tif);
- TIFFDefaultDirectory(tif);
- /*
- * Electronic Arts writes gray-scale TIFF files
- * without a PlanarConfiguration directory entry.
- * Thus we setup a default value here, even though
- * the TIFF spec says there is no default value.
- */
- TIFFSetField(tif,TIFFTAG_PLANARCONFIG,PLANARCONFIG_CONTIG);
- /*
- * Setup default value and then make a pass over
- * the fields to check type and tag information,
- * and to extract info required to size data
- * structures. A second pass is made afterwards
- * to read in everything not taken in the first pass.
- * But we must process the Compression tag first
- * in order to merge in codec-private tag definitions (otherwise
- * we may get complaints about unknown tags). However, the
- * Compression tag may be dependent on the SamplesPerPixel
- * tag value because older TIFF specs permitted Compression
- * to be written as a SamplesPerPixel-count tag entry.
- * Thus if we don't first figure out the correct SamplesPerPixel
- * tag value then we may end up ignoring the Compression tag
- * value because it has an incorrect count value (if the
- * true value of SamplesPerPixel is not 1).
- */
- dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_SAMPLESPERPIXEL);
- if (dp)
- {
- if (!TIFFFetchNormalTag(tif,dp,0))
- goto bad;
- dp->tdir_ignore = TRUE;
- }
- dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_COMPRESSION);
- if (dp)
- {
- /*
- * The 5.0 spec says the Compression tag has one value, while
- * earlier specs say it has one value per sample. Because of
- * this, we accept the tag if one value is supplied with either
- * count.
- */
- uint16 value;
- enum TIFFReadDirEntryErr err;
- err=TIFFReadDirEntryShort(tif,dp,&value);
- if (err==TIFFReadDirEntryErrCount)
- err=TIFFReadDirEntryPersampleShort(tif,dp,&value);
- if (err!=TIFFReadDirEntryErrOk)
- {
- TIFFReadDirEntryOutputErr(tif,err,module,"Compression",0);
- goto bad;
- }
- if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,value))
- goto bad;
- dp->tdir_ignore = TRUE;
- }
- else
- {
- if (!TIFFSetField(tif,TIFFTAG_COMPRESSION,COMPRESSION_NONE))
- goto bad;
- }
- /*
- * First real pass over the directory.
- */
- for (di=0, dp=dir; di<dircount; di++, dp++)
- {
- if (!dp->tdir_ignore)
- {
- TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
- if (fii == FAILED_FII)
- {
- TIFFWarningExt(tif->tif_clientdata, module,
- "Unknown field with tag %d (0x%x) encountered",
- dp->tdir_tag,dp->tdir_tag);
- /* the following knowingly leaks the
- anonymous field structure */
- if (!_TIFFMergeFields(tif,
- _TIFFCreateAnonField(tif,
- dp->tdir_tag,
- (TIFFDataType) dp->tdir_type),
- 1)) {
- TIFFWarningExt(tif->tif_clientdata,
- module,
- "Registering anonymous field with tag %d (0x%x) failed",
- dp->tdir_tag,
- dp->tdir_tag);
- dp->tdir_ignore = TRUE;
- } else {
- TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
- assert(fii != FAILED_FII);
- }
- }
- }
- if (!dp->tdir_ignore)
- {
- fip=tif->tif_fields[fii];
- if (fip->field_bit==FIELD_IGNORE)
- dp->tdir_ignore = TRUE;
- else
- {
- switch (dp->tdir_tag)
- {
- case TIFFTAG_STRIPOFFSETS:
- case TIFFTAG_STRIPBYTECOUNTS:
- case TIFFTAG_TILEOFFSETS:
- case TIFFTAG_TILEBYTECOUNTS:
- TIFFSetFieldBit(tif,fip->field_bit);
- break;
- case TIFFTAG_IMAGEWIDTH:
- case TIFFTAG_IMAGELENGTH:
- case TIFFTAG_IMAGEDEPTH:
- case TIFFTAG_TILELENGTH:
- case TIFFTAG_TILEWIDTH:
- case TIFFTAG_TILEDEPTH:
- case TIFFTAG_PLANARCONFIG:
- case TIFFTAG_ROWSPERSTRIP:
- case TIFFTAG_EXTRASAMPLES:
- if (!TIFFFetchNormalTag(tif,dp,0))
- goto bad;
- dp->tdir_ignore = TRUE;
- break;
- default:
- if( !_TIFFCheckFieldIsValidForCodec(tif, dp->tdir_tag) )
- dp->tdir_ignore = TRUE;
- break;
- }
- }
- }
- }
- /*
- * XXX: OJPEG hack.
- * If a) compression is OJPEG, b) planarconfig tag says it's separate,
- * c) strip offsets/bytecounts tag are both present and
- * d) both contain exactly one value, then we consistently find
- * that the buggy implementation of the buggy compression scheme
- * matches contig planarconfig best. So we 'fix-up' the tag here
- */
- if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG)&&
- (tif->tif_dir.td_planarconfig==PLANARCONFIG_SEPARATE))
- {
- if (!_TIFFFillStriles(tif))
- goto bad;
- dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,TIFFTAG_STRIPOFFSETS);
- if ((dp!=0)&&(dp->tdir_count==1))
- {
- dp=TIFFReadDirectoryFindEntry(tif,dir,dircount,
- TIFFTAG_STRIPBYTECOUNTS);
- if ((dp!=0)&&(dp->tdir_count==1))
- {
- tif->tif_dir.td_planarconfig=PLANARCONFIG_CONTIG;
- TIFFWarningExt(tif->tif_clientdata,module,
- "Planarconfig tag value assumed incorrect, "
- "assuming data is contig instead of chunky");
- }
- }
- }
- /*
- * Allocate directory structure and setup defaults.
- */
- if (!TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS))
- {
- MissingRequired(tif,"ImageLength");
- goto bad;
- }
- /*
- * Setup appropriate structures (by strip or by tile)
- */
- if (!TIFFFieldSet(tif, FIELD_TILEDIMENSIONS)) {
- tif->tif_dir.td_nstrips = TIFFNumberOfStrips(tif);
- tif->tif_dir.td_tilewidth = tif->tif_dir.td_imagewidth;
- tif->tif_dir.td_tilelength = tif->tif_dir.td_rowsperstrip;
- tif->tif_dir.td_tiledepth = tif->tif_dir.td_imagedepth;
- tif->tif_flags &= ~TIFF_ISTILED;
- } else {
- tif->tif_dir.td_nstrips = TIFFNumberOfTiles(tif);
- tif->tif_flags |= TIFF_ISTILED;
- }
- if (!tif->tif_dir.td_nstrips) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Cannot handle zero number of %s",
- isTiled(tif) ? "tiles" : "strips");
- goto bad;
- }
- tif->tif_dir.td_stripsperimage = tif->tif_dir.td_nstrips;
- if (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE)
- tif->tif_dir.td_stripsperimage /= tif->tif_dir.td_samplesperpixel;
- if (!TIFFFieldSet(tif, FIELD_STRIPOFFSETS)) {
- #ifdef OJPEG_SUPPORT
- if ((tif->tif_dir.td_compression==COMPRESSION_OJPEG) &&
- (isTiled(tif)==0) &&
- (tif->tif_dir.td_nstrips==1)) {
- /*
- * XXX: OJPEG hack.
- * If a) compression is OJPEG, b) it's not a tiled TIFF,
- * and c) the number of strips is 1,
- * then we tolerate the absence of stripoffsets tag,
- * because, presumably, all required data is in the
- * JpegInterchangeFormat stream.
- */
- TIFFSetFieldBit(tif, FIELD_STRIPOFFSETS);
- } else
- #endif
- {
- MissingRequired(tif,
- isTiled(tif) ? "TileOffsets" : "StripOffsets");
- goto bad;
- }
- }
- /*
- * Second pass: extract other information.
- */
- for (di=0, dp=dir; di<dircount; di++, dp++)
- {
- if (!dp->tdir_ignore) {
- switch (dp->tdir_tag)
- {
- case TIFFTAG_MINSAMPLEVALUE:
- case TIFFTAG_MAXSAMPLEVALUE:
- case TIFFTAG_BITSPERSAMPLE:
- case TIFFTAG_DATATYPE:
- case TIFFTAG_SAMPLEFORMAT:
- /*
- * The MinSampleValue, MaxSampleValue, BitsPerSample
- * DataType and SampleFormat tags are supposed to be
- * written as one value/sample, but some vendors
- * incorrectly write one value only -- so we accept
- * that as well (yuck). Other vendors write correct
- * value for NumberOfSamples, but incorrect one for
- * BitsPerSample and friends, and we will read this
- * too.
- */
- {
- uint16 value;
- enum TIFFReadDirEntryErr err;
- err=TIFFReadDirEntryShort(tif,dp,&value);
- if (err==TIFFReadDirEntryErrCount)
- err=TIFFReadDirEntryPersampleShort(tif,dp,&value);
- if (err!=TIFFReadDirEntryErrOk)
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
- goto bad;
- }
- if (!TIFFSetField(tif,dp->tdir_tag,value))
- goto bad;
- if( dp->tdir_tag == TIFFTAG_BITSPERSAMPLE )
- bitspersample_read = TRUE;
- }
- break;
- case TIFFTAG_SMINSAMPLEVALUE:
- case TIFFTAG_SMAXSAMPLEVALUE:
- {
- double *data = NULL;
- enum TIFFReadDirEntryErr err;
- uint32 saved_flags;
- int m;
- if (dp->tdir_count != (uint64)tif->tif_dir.td_samplesperpixel)
- err = TIFFReadDirEntryErrCount;
- else
- err = TIFFReadDirEntryDoubleArray(tif, dp, &data);
- if (err!=TIFFReadDirEntryErrOk)
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
- goto bad;
- }
- saved_flags = tif->tif_flags;
- tif->tif_flags |= TIFF_PERSAMPLE;
- m = TIFFSetField(tif,dp->tdir_tag,data);
- tif->tif_flags = saved_flags;
- _TIFFfree(data);
- if (!m)
- goto bad;
- }
- break;
- case TIFFTAG_STRIPOFFSETS:
- case TIFFTAG_TILEOFFSETS:
- switch( dp->tdir_type )
- {
- case TIFF_SHORT:
- case TIFF_LONG:
- case TIFF_LONG8:
- break;
- default:
- /* Warn except if directory typically created with TIFFDeferStrileArrayWriting() */
- if( !(tif->tif_mode == O_RDWR &&
- dp->tdir_count == 0 &&
- dp->tdir_type == 0 &&
- dp->tdir_offset.toff_long8 == 0) )
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFWarningExt(tif->tif_clientdata,module,
- "Invalid data type for tag %s",
- fip ? fip->field_name : "unknown tagname");
- }
- break;
- }
- _TIFFmemcpy( &(tif->tif_dir.td_stripoffset_entry),
- dp, sizeof(TIFFDirEntry) );
- break;
- case TIFFTAG_STRIPBYTECOUNTS:
- case TIFFTAG_TILEBYTECOUNTS:
- switch( dp->tdir_type )
- {
- case TIFF_SHORT:
- case TIFF_LONG:
- case TIFF_LONG8:
- break;
- default:
- /* Warn except if directory typically created with TIFFDeferStrileArrayWriting() */
- if( !(tif->tif_mode == O_RDWR &&
- dp->tdir_count == 0 &&
- dp->tdir_type == 0 &&
- dp->tdir_offset.toff_long8 == 0) )
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFWarningExt(tif->tif_clientdata,module,
- "Invalid data type for tag %s",
- fip ? fip->field_name : "unknown tagname");
- }
- break;
- }
- _TIFFmemcpy( &(tif->tif_dir.td_stripbytecount_entry),
- dp, sizeof(TIFFDirEntry) );
- break;
- case TIFFTAG_COLORMAP:
- case TIFFTAG_TRANSFERFUNCTION:
- {
- enum TIFFReadDirEntryErr err;
- uint32 countpersample;
- uint32 countrequired;
- uint32 incrementpersample;
- uint16* value=NULL;
- /* It would be dangerous to instantiate those tag values */
- /* since if td_bitspersample has not yet been read (due to */
- /* unordered tags), it could be read afterwards with a */
- /* values greater than the default one (1), which may cause */
- /* crashes in user code */
- if( !bitspersample_read )
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFWarningExt(tif->tif_clientdata,module,
- "Ignoring %s since BitsPerSample tag not found",
- fip ? fip->field_name : "unknown tagname");
- continue;
- }
- /* ColorMap or TransferFunction for high bit */
- /* depths do not make much sense and could be */
- /* used as a denial of service vector */
- if (tif->tif_dir.td_bitspersample > 24)
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFWarningExt(tif->tif_clientdata,module,
- "Ignoring %s because BitsPerSample=%d>24",
- fip ? fip->field_name : "unknown tagname",
- tif->tif_dir.td_bitspersample);
- continue;
- }
- countpersample=(1U<<tif->tif_dir.td_bitspersample);
- if ((dp->tdir_tag==TIFFTAG_TRANSFERFUNCTION)&&(dp->tdir_count==(uint64)countpersample))
- {
- countrequired=countpersample;
- incrementpersample=0;
- }
- else
- {
- countrequired=3*countpersample;
- incrementpersample=countpersample;
- }
- if (dp->tdir_count!=(uint64)countrequired)
- err=TIFFReadDirEntryErrCount;
- else
- err=TIFFReadDirEntryShortArray(tif,dp,&value);
- if (err!=TIFFReadDirEntryErrOk)
- {
- fip = TIFFFieldWithTag(tif,dp->tdir_tag);
- TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",1);
- }
- else
- {
- TIFFSetField(tif,dp->tdir_tag,value,value+incrementpersample,value+2*incrementpersample);
- _TIFFfree(value);
- }
- }
- break;
- /* BEGIN REV 4.0 COMPATIBILITY */
- case TIFFTAG_OSUBFILETYPE:
- {
- uint16 valueo;
- uint32 value;
- if (TIFFReadDirEntryShort(tif,dp,&valueo)==TIFFReadDirEntryErrOk)
- {
- switch (valueo)
- {
- case OFILETYPE_REDUCEDIMAGE: value=FILETYPE_REDUCEDIMAGE; break;
- case OFILETYPE_PAGE: value=FILETYPE_PAGE; break;
- default: value=0; break;
- }
- if (value!=0)
- TIFFSetField(tif,TIFFTAG_SUBFILETYPE,value);
- }
- }
- break;
- /* END REV 4.0 COMPATIBILITY */
- default:
- (void) TIFFFetchNormalTag(tif, dp, TRUE);
- break;
- }
- } /* -- if (!dp->tdir_ignore) */
- } /* -- for-loop -- */
- if( tif->tif_mode == O_RDWR &&
- tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 &&
- tif->tif_dir.td_stripoffset_entry.tdir_count == 0 &&
- tif->tif_dir.td_stripoffset_entry.tdir_type == 0 &&
- tif->tif_dir.td_stripoffset_entry.tdir_offset.toff_long8 == 0 &&
- tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 &&
- tif->tif_dir.td_stripbytecount_entry.tdir_count == 0 &&
- tif->tif_dir.td_stripbytecount_entry.tdir_type == 0 &&
- tif->tif_dir.td_stripbytecount_entry.tdir_offset.toff_long8 == 0 )
- {
- /* Directory typically created with TIFFDeferStrileArrayWriting() */
- TIFFSetupStrips(tif);
- }
- else if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) )
- {
- if( tif->tif_dir.td_stripoffset_entry.tdir_tag != 0 )
- {
- if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripoffset_entry),
- tif->tif_dir.td_nstrips,
- &tif->tif_dir.td_stripoffset_p))
- {
- goto bad;
- }
- }
- if( tif->tif_dir.td_stripbytecount_entry.tdir_tag != 0 )
- {
- if (!TIFFFetchStripThing(tif,&(tif->tif_dir.td_stripbytecount_entry),
- tif->tif_dir.td_nstrips,
- &tif->tif_dir.td_stripbytecount_p))
- {
- goto bad;
- }
- }
- }
- /*
- * OJPEG hack:
- * - If a) compression is OJPEG, and b) photometric tag is missing,
- * then we consistently find that photometric should be YCbCr
- * - If a) compression is OJPEG, and b) photometric tag says it's RGB,
- * then we consistently find that the buggy implementation of the
- * buggy compression scheme matches photometric YCbCr instead.
- * - If a) compression is OJPEG, and b) bitspersample tag is missing,
- * then we consistently find bitspersample should be 8.
- * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
- * and c) photometric is RGB or YCbCr, then we consistently find
- * samplesperpixel should be 3
- * - If a) compression is OJPEG, b) samplesperpixel tag is missing,
- * and c) photometric is MINISWHITE or MINISBLACK, then we consistently
- * find samplesperpixel should be 3
- */
- if (tif->tif_dir.td_compression==COMPRESSION_OJPEG)
- {
- if (!TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
- {
- TIFFWarningExt(tif->tif_clientdata, module,
- "Photometric tag is missing, assuming data is YCbCr");
- if (!TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,PHOTOMETRIC_YCBCR))
- goto bad;
- }
- else if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB)
- {
- tif->tif_dir.td_photometric=PHOTOMETRIC_YCBCR;
- TIFFWarningExt(tif->tif_clientdata, module,
- "Photometric tag value assumed incorrect, "
- "assuming data is YCbCr instead of RGB");
- }
- if (!TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
- {
- TIFFWarningExt(tif->tif_clientdata,module,
- "BitsPerSample tag is missing, assuming 8 bits per sample");
- if (!TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE,8))
- goto bad;
- }
- if (!TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
- {
- if (tif->tif_dir.td_photometric==PHOTOMETRIC_RGB)
- {
- TIFFWarningExt(tif->tif_clientdata,module,
- "SamplesPerPixel tag is missing, "
- "assuming correct SamplesPerPixel value is 3");
- if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
- goto bad;
- }
- if (tif->tif_dir.td_photometric==PHOTOMETRIC_YCBCR)
- {
- TIFFWarningExt(tif->tif_clientdata,module,
- "SamplesPerPixel tag is missing, "
- "applying correct SamplesPerPixel value of 3");
- if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,3))
- goto bad;
- }
- else if ((tif->tif_dir.td_photometric==PHOTOMETRIC_MINISWHITE)
- || (tif->tif_dir.td_photometric==PHOTOMETRIC_MINISBLACK))
- {
- /*
- * SamplesPerPixel tag is missing, but is not required
- * by spec. Assume correct SamplesPerPixel value of 1.
- */
- if (!TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL,1))
- goto bad;
- }
- }
- }
- /*
- * Make sure all non-color channels are extrasamples.
- * If it's not the case, define them as such.
- */
- color_channels = _TIFFGetMaxColorChannels(tif->tif_dir.td_photometric);
- if (color_channels && tif->tif_dir.td_samplesperpixel - tif->tif_dir.td_extrasamples > color_channels) {
- uint16 old_extrasamples;
- uint16 *new_sampleinfo;
- TIFFWarningExt(tif->tif_clientdata,module, "Sum of Photometric type-related "
- "color channels and ExtraSamples doesn't match SamplesPerPixel. "
- "Defining non-color channels as ExtraSamples.");
- old_extrasamples = tif->tif_dir.td_extrasamples;
- tif->tif_dir.td_extrasamples = (uint16) (tif->tif_dir.td_samplesperpixel - color_channels);
- // sampleinfo should contain information relative to these new extra samples
- new_sampleinfo = (uint16*) _TIFFcalloc(tif->tif_dir.td_extrasamples, sizeof(uint16));
- if (!new_sampleinfo) {
- TIFFErrorExt(tif->tif_clientdata, module, "Failed to allocate memory for "
- "temporary new sampleinfo array (%d 16 bit elements)",
- tif->tif_dir.td_extrasamples);
- goto bad;
- }
- memcpy(new_sampleinfo, tif->tif_dir.td_sampleinfo, old_extrasamples * sizeof(uint16));
- _TIFFsetShortArray(&tif->tif_dir.td_sampleinfo, new_sampleinfo, tif->tif_dir.td_extrasamples);
- _TIFFfree(new_sampleinfo);
- }
- /*
- * Verify Palette image has a Colormap.
- */
- if (tif->tif_dir.td_photometric == PHOTOMETRIC_PALETTE &&
- !TIFFFieldSet(tif, FIELD_COLORMAP)) {
- if ( tif->tif_dir.td_bitspersample>=8 && tif->tif_dir.td_samplesperpixel==3)
- tif->tif_dir.td_photometric = PHOTOMETRIC_RGB;
- else if (tif->tif_dir.td_bitspersample>=8)
- tif->tif_dir.td_photometric = PHOTOMETRIC_MINISBLACK;
- else {
- MissingRequired(tif, "Colormap");
- goto bad;
- }
- }
- /*
- * OJPEG hack:
- * We do no further messing with strip/tile offsets/bytecounts in OJPEG
- * TIFFs
- */
- if (tif->tif_dir.td_compression!=COMPRESSION_OJPEG)
- {
- /*
- * Attempt to deal with a missing StripByteCounts tag.
- */
- if (!TIFFFieldSet(tif, FIELD_STRIPBYTECOUNTS)) {
- /*
- * Some manufacturers violate the spec by not giving
- * the size of the strips. In this case, assume there
- * is one uncompressed strip of data.
- */
- if ((tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
- tif->tif_dir.td_nstrips > 1) ||
- (tif->tif_dir.td_planarconfig == PLANARCONFIG_SEPARATE &&
- tif->tif_dir.td_nstrips != (uint32)tif->tif_dir.td_samplesperpixel)) {
- MissingRequired(tif, "StripByteCounts");
- goto bad;
- }
- TIFFWarningExt(tif->tif_clientdata, module,
- "TIFF directory is missing required "
- "\"StripByteCounts\" field, calculating from imagelength");
- if (EstimateStripByteCounts(tif, dir, dircount) < 0)
- goto bad;
- } else if (tif->tif_dir.td_nstrips == 1
- && !(tif->tif_flags&TIFF_ISTILED)
- && ByteCountLooksBad(tif)) {
- /*
- * XXX: Plexus (and others) sometimes give a value of
- * zero for a tag when they don't know what the
- * correct value is! Try and handle the simple case
- * of estimating the size of a one strip image.
- */
- TIFFWarningExt(tif->tif_clientdata, module,
- "Bogus \"StripByteCounts\" field, ignoring and calculating from imagelength");
- if(EstimateStripByteCounts(tif, dir, dircount) < 0)
- goto bad;
- } else if (!(tif->tif_flags&TIFF_DEFERSTRILELOAD)
- && tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG
- && tif->tif_dir.td_nstrips > 2
- && tif->tif_dir.td_compression == COMPRESSION_NONE
- && TIFFGetStrileByteCount(tif, 0) != TIFFGetStrileByteCount(tif, 1)
- && TIFFGetStrileByteCount(tif, 0) != 0
- && TIFFGetStrileByteCount(tif, 1) != 0 ) {
- /*
- * XXX: Some vendors fill StripByteCount array with
- * absolutely wrong values (it can be equal to
- * StripOffset array, for example). Catch this case
- * here.
- *
- * We avoid this check if deferring strile loading
- * as it would always force us to load the strip/tile
- * information.
- */
- TIFFWarningExt(tif->tif_clientdata, module,
- "Wrong \"StripByteCounts\" field, ignoring and calculating from imagelength");
- if (EstimateStripByteCounts(tif, dir, dircount) < 0)
- goto bad;
- }
- }
- if (dir)
- {
- _TIFFfree(dir);
- dir=NULL;
- }
- if (!TIFFFieldSet(tif, FIELD_MAXSAMPLEVALUE))
- {
- if (tif->tif_dir.td_bitspersample>=16)
- tif->tif_dir.td_maxsamplevalue=0xFFFF;
- else
- tif->tif_dir.td_maxsamplevalue = (uint16)((1L<<tif->tif_dir.td_bitspersample)-1);
- }
- #ifdef STRIPBYTECOUNTSORTED_UNUSED
- /*
- * XXX: We can optimize checking for the strip bounds using the sorted
- * bytecounts array. See also comments for TIFFAppendToStrip()
- * function in tif_write.c.
- */
- if (!(tif->tif_flags&TIFF_DEFERSTRILELOAD) && tif->tif_dir.td_nstrips > 1) {
- uint32 strip;
- tif->tif_dir.td_stripbytecountsorted = 1;
- for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
- if (TIFFGetStrileOffset(tif, strip - 1) >
- TIFFGetStrileOffset(tif, strip)) {
- tif->tif_dir.td_stripbytecountsorted = 0;
- break;
- }
- }
- }
- #endif
- /*
- * An opportunity for compression mode dependent tag fixup
- */
- (*tif->tif_fixuptags)(tif);
- /*
- * Some manufacturers make life difficult by writing
- * large amounts of uncompressed data as a single strip.
- * This is contrary to the recommendations of the spec.
- * The following makes an attempt at breaking such images
- * into strips closer to the recommended 8k bytes. A
- * side effect, however, is that the RowsPerStrip tag
- * value may be changed.
- */
- if ((tif->tif_dir.td_planarconfig==PLANARCONFIG_CONTIG)&&
- (tif->tif_dir.td_nstrips==1)&&
- (tif->tif_dir.td_compression==COMPRESSION_NONE)&&
- ((tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED))==TIFF_STRIPCHOP))
- {
- ChopUpSingleUncompressedStrip(tif);
- }
- /* There are also uncompressed striped files with strips larger than */
- /* 2 GB, which make them unfriendly with a lot of code. If possible, */
- /* try to expose smaller "virtual" strips. */
- if( tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG &&
- tif->tif_dir.td_compression == COMPRESSION_NONE &&
- (tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP &&
- TIFFStripSize64(tif) > 0x7FFFFFFFUL )
- {
- TryChopUpUncompressedBigTiff(tif);
- }
- /*
- * Clear the dirty directory flag.
- */
- tif->tif_flags &= ~TIFF_DIRTYDIRECT;
- tif->tif_flags &= ~TIFF_DIRTYSTRIP;
- /*
- * Reinitialize i/o since we are starting on a new directory.
- */
- tif->tif_row = (uint32) -1;
- tif->tif_curstrip = (uint32) -1;
- tif->tif_col = (uint32) -1;
- tif->tif_curtile = (uint32) -1;
- tif->tif_tilesize = (tmsize_t) -1;
- tif->tif_scanlinesize = TIFFScanlineSize(tif);
- if (!tif->tif_scanlinesize) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Cannot handle zero scanline size");
- return (0);
- }
- if (isTiled(tif)) {
- tif->tif_tilesize = TIFFTileSize(tif);
- if (!tif->tif_tilesize) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Cannot handle zero tile size");
- return (0);
- }
- } else {
- if (!TIFFStripSize(tif)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Cannot handle zero strip size");
- return (0);
- }
- }
- return (1);
- bad:
- if (dir)
- _TIFFfree(dir);
- return (0);
- }
- static void
- TIFFReadDirectoryCheckOrder(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
- {
- static const char module[] = "TIFFReadDirectoryCheckOrder";
- uint16 m;
- uint16 n;
- TIFFDirEntry* o;
- m=0;
- for (n=0, o=dir; n<dircount; n++, o++)
- {
- if (o->tdir_tag<m)
- {
- TIFFWarningExt(tif->tif_clientdata,module,
- "Invalid TIFF directory; tags are not sorted in ascending order");
- break;
- }
- m=o->tdir_tag+1;
- }
- }
- static TIFFDirEntry*
- TIFFReadDirectoryFindEntry(TIFF* tif, TIFFDirEntry* dir, uint16 dircount, uint16 tagid)
- {
- TIFFDirEntry* m;
- uint16 n;
- (void) tif;
- for (m=dir, n=0; n<dircount; m++, n++)
- {
- if (m->tdir_tag==tagid)
- return(m);
- }
- return(0);
- }
- static void
- TIFFReadDirectoryFindFieldInfo(TIFF* tif, uint16 tagid, uint32* fii)
- {
- int32 ma,mb,mc;
- ma=-1;
- mc=(int32)tif->tif_nfields;
- while (1)
- {
- if (ma+1==mc)
- {
- *fii = FAILED_FII;
- return;
- }
- mb=(ma+mc)/2;
- if (tif->tif_fields[mb]->field_tag==(uint32)tagid)
- break;
- if (tif->tif_fields[mb]->field_tag<(uint32)tagid)
- ma=mb;
- else
- mc=mb;
- }
- while (1)
- {
- if (mb==0)
- break;
- if (tif->tif_fields[mb-1]->field_tag!=(uint32)tagid)
- break;
- mb--;
- }
- *fii=mb;
- }
- /*
- * Read custom directory from the arbitrary offset.
- * The code is very similar to TIFFReadDirectory().
- */
- int
- TIFFReadCustomDirectory(TIFF* tif, toff_t diroff,
- const TIFFFieldArray* infoarray)
- {
- static const char module[] = "TIFFReadCustomDirectory";
- TIFFDirEntry* dir;
- uint16 dircount;
- TIFFDirEntry* dp;
- uint16 di;
- const TIFFField* fip;
- uint32 fii;
- (*tif->tif_cleanup)(tif); /* cleanup any previous compression state */
- _TIFFSetupFields(tif, infoarray);
- dircount=TIFFFetchDirectory(tif,diroff,&dir,NULL);
- if (!dircount)
- {
- TIFFErrorExt(tif->tif_clientdata,module,
- "Failed to read custom directory at offset " TIFF_UINT64_FORMAT,diroff);
- return 0;
- }
- TIFFFreeDirectory(tif);
- _TIFFmemset(&tif->tif_dir, 0, sizeof(TIFFDirectory));
- TIFFReadDirectoryCheckOrder(tif,dir,dircount);
- for (di=0, dp=dir; di<dircount; di++, dp++)
- {
- TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
- if (fii == FAILED_FII)
- {
- TIFFWarningExt(tif->tif_clientdata, module,
- "Unknown field with tag %d (0x%x) encountered",
- dp->tdir_tag, dp->tdir_tag);
- if (!_TIFFMergeFields(tif, _TIFFCreateAnonField(tif,
- dp->tdir_tag,
- (TIFFDataType) dp->tdir_type),
- 1)) {
- TIFFWarningExt(tif->tif_clientdata, module,
- "Registering anonymous field with tag %d (0x%x) failed",
- dp->tdir_tag, dp->tdir_tag);
- dp->tdir_ignore = TRUE;
- } else {
- TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
- assert( fii != FAILED_FII );
- }
- }
- if (!dp->tdir_ignore)
- {
- fip=tif->tif_fields[fii];
- if (fip->field_bit==FIELD_IGNORE)
- dp->tdir_ignore = TRUE;
- else
- {
- /* check data type */
- while ((fip->field_type!=TIFF_ANY)&&(fip->field_type!=dp->tdir_type))
- {
- fii++;
- if ((fii==tif->tif_nfields)||
- (tif->tif_fields[fii]->field_tag!=(uint32)dp->tdir_tag))
- {
- fii=0xFFFF;
- break;
- }
- fip=tif->tif_fields[fii];
- }
- if (fii==0xFFFF)
- {
- TIFFWarningExt(tif->tif_clientdata, module,
- "Wrong data type %d for \"%s\"; tag ignored",
- dp->tdir_type,fip->field_name);
- dp->tdir_ignore = TRUE;
- }
- else
- {
- /* check count if known in advance */
- if ((fip->field_readcount!=TIFF_VARIABLE)&&
- (fip->field_readcount!=TIFF_VARIABLE2))
- {
- uint32 expected;
- if (fip->field_readcount==TIFF_SPP)
- expected=(uint32)tif->tif_dir.td_samplesperpixel;
- else
- expected=(uint32)fip->field_readcount;
- if (!CheckDirCount(tif,dp,expected))
- dp->tdir_ignore = TRUE;
- }
- }
- }
- if (!dp->tdir_ignore) {
- switch (dp->tdir_tag)
- {
- case EXIFTAG_SUBJECTDISTANCE:
- (void)TIFFFetchSubjectDistance(tif, dp);
- break;
- default:
- (void)TIFFFetchNormalTag(tif, dp, TRUE);
- break;
- }
- } /*-- if (!dp->tdir_ignore) */
- }
- }
- if (dir)
- _TIFFfree(dir);
- return 1;
- }
- /*
- * EXIF is important special case of custom IFD, so we have a special
- * function to read it.
- */
- int
- TIFFReadEXIFDirectory(TIFF* tif, toff_t diroff)
- {
- const TIFFFieldArray* exifFieldArray;
- exifFieldArray = _TIFFGetExifFields();
- return TIFFReadCustomDirectory(tif, diroff, exifFieldArray);
- }
- /*
- *--: EXIF-GPS custom directory reading as another special case of custom IFD.
- */
- int
- TIFFReadGPSDirectory(TIFF* tif, toff_t diroff)
- {
- const TIFFFieldArray* gpsFieldArray;
- gpsFieldArray = _TIFFGetGpsFields();
- return TIFFReadCustomDirectory(tif, diroff, gpsFieldArray);
- }
- static int
- EstimateStripByteCounts(TIFF* tif, TIFFDirEntry* dir, uint16 dircount)
- {
- static const char module[] = "EstimateStripByteCounts";
- TIFFDirEntry *dp;
- TIFFDirectory *td = &tif->tif_dir;
- uint32 strip;
- /* Do not try to load stripbytecount as we will compute it */
- if( !_TIFFFillStrilesInternal( tif, 0 ) )
- return -1;
- if (td->td_stripbytecount_p)
- _TIFFfree(td->td_stripbytecount_p);
- td->td_stripbytecount_p = (uint64*)
- _TIFFCheckMalloc(tif, td->td_nstrips, sizeof (uint64),
- "for \"StripByteCounts\" array");
- if( td->td_stripbytecount_p == NULL )
- return -1;
- if (td->td_compression != COMPRESSION_NONE) {
- uint64 space;
- uint64 filesize;
- uint16 n;
- filesize = TIFFGetFileSize(tif);
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- space=sizeof(TIFFHeaderClassic)+2+dircount*12+4;
- else
- space=sizeof(TIFFHeaderBig)+8+dircount*20+8;
- /* calculate amount of space used by indirect values */
- for (dp = dir, n = dircount; n > 0; n--, dp++)
- {
- uint32 typewidth;
- uint64 datasize;
- typewidth = TIFFDataWidth((TIFFDataType) dp->tdir_type);
- if (typewidth == 0) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Cannot determine size of unknown tag type %d",
- dp->tdir_type);
- return -1;
- }
- if( dp->tdir_count > TIFF_UINT64_MAX / typewidth )
- return -1;
- datasize=(uint64)typewidth*dp->tdir_count;
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- if (datasize<=4)
- datasize=0;
- }
- else
- {
- if (datasize<=8)
- datasize=0;
- }
- if( space > TIFF_UINT64_MAX - datasize )
- return -1;
- space+=datasize;
- }
- if( filesize < space )
- /* we should perhaps return in error ? */
- space = filesize;
- else
- space = filesize - space;
- if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
- space /= td->td_samplesperpixel;
- for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount_p[strip] = space;
- /*
- * This gross hack handles the case were the offset to
- * the last strip is past the place where we think the strip
- * should begin. Since a strip of data must be contiguous,
- * it's safe to assume that we've overestimated the amount
- * of data in the strip and trim this number back accordingly.
- */
- strip--;
- if (td->td_stripoffset_p[strip] > TIFF_UINT64_MAX - td->td_stripbytecount_p[strip])
- return -1;
- if (td->td_stripoffset_p[strip]+td->td_stripbytecount_p[strip] > filesize) {
- if( td->td_stripoffset_p[strip] >= filesize ) {
- /* Not sure what we should in that case... */
- td->td_stripbytecount_p[strip] = 0;
- } else {
- td->td_stripbytecount_p[strip] = filesize - td->td_stripoffset_p[strip];
- }
- }
- } else if (isTiled(tif)) {
- uint64 bytespertile = TIFFTileSize64(tif);
- for (strip = 0; strip < td->td_nstrips; strip++)
- td->td_stripbytecount_p[strip] = bytespertile;
- } else {
- uint64 rowbytes = TIFFScanlineSize64(tif);
- uint32 rowsperstrip = td->td_imagelength/td->td_stripsperimage;
- for (strip = 0; strip < td->td_nstrips; strip++)
- {
- if( rowbytes > 0 && rowsperstrip > TIFF_UINT64_MAX / rowbytes )
- return -1;
- td->td_stripbytecount_p[strip] = rowbytes * rowsperstrip;
- }
- }
- TIFFSetFieldBit(tif, FIELD_STRIPBYTECOUNTS);
- if (!TIFFFieldSet(tif, FIELD_ROWSPERSTRIP))
- td->td_rowsperstrip = td->td_imagelength;
- return 1;
- }
- static void
- MissingRequired(TIFF* tif, const char* tagname)
- {
- static const char module[] = "MissingRequired";
- TIFFErrorExt(tif->tif_clientdata, module,
- "TIFF directory is missing required \"%s\" field",
- tagname);
- }
- /*
- * Check the directory offset against the list of already seen directory
- * offsets. This is a trick to prevent IFD looping. The one can create TIFF
- * file with looped directory pointers. We will maintain a list of already
- * seen directories and check every IFD offset against that list.
- */
- static int
- TIFFCheckDirOffset(TIFF* tif, uint64 diroff)
- {
- uint16 n;
- if (diroff == 0) /* no more directories */
- return 0;
- if (tif->tif_dirnumber == 65535) {
- TIFFErrorExt(tif->tif_clientdata, "TIFFCheckDirOffset",
- "Cannot handle more than 65535 TIFF directories");
- return 0;
- }
- for (n = 0; n < tif->tif_dirnumber && tif->tif_dirlist; n++) {
- if (tif->tif_dirlist[n] == diroff)
- return 0;
- }
- tif->tif_dirnumber++;
- if (tif->tif_dirlist == NULL || tif->tif_dirnumber > tif->tif_dirlistsize) {
- uint64* new_dirlist;
- /*
- * XXX: Reduce memory allocation granularity of the dirlist
- * array.
- */
- new_dirlist = (uint64*)_TIFFCheckRealloc(tif, tif->tif_dirlist,
- tif->tif_dirnumber, 2 * sizeof(uint64), "for IFD list");
- if (!new_dirlist)
- return 0;
- if( tif->tif_dirnumber >= 32768 )
- tif->tif_dirlistsize = 65535;
- else
- tif->tif_dirlistsize = 2 * tif->tif_dirnumber;
- tif->tif_dirlist = new_dirlist;
- }
- tif->tif_dirlist[tif->tif_dirnumber - 1] = diroff;
- return 1;
- }
- /*
- * Check the count field of a directory entry against a known value. The
- * caller is expected to skip/ignore the tag if there is a mismatch.
- */
- static int
- CheckDirCount(TIFF* tif, TIFFDirEntry* dir, uint32 count)
- {
- if ((uint64)count > dir->tdir_count) {
- const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag);
- TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
- "incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag ignored",
- fip ? fip->field_name : "unknown tagname",
- dir->tdir_count, count);
- return (0);
- } else if ((uint64)count < dir->tdir_count) {
- const TIFFField* fip = TIFFFieldWithTag(tif, dir->tdir_tag);
- TIFFWarningExt(tif->tif_clientdata, tif->tif_name,
- "incorrect count for field \"%s\" (" TIFF_UINT64_FORMAT ", expecting %u); tag trimmed",
- fip ? fip->field_name : "unknown tagname",
- dir->tdir_count, count);
- dir->tdir_count = count;
- return (1);
- }
- return (1);
- }
- /*
- * Read IFD structure from the specified offset. If the pointer to
- * nextdiroff variable has been specified, read it too. Function returns a
- * number of fields in the directory or 0 if failed.
- */
- static uint16
- TIFFFetchDirectory(TIFF* tif, uint64 diroff, TIFFDirEntry** pdir,
- uint64 *nextdiroff)
- {
- static const char module[] = "TIFFFetchDirectory";
- void* origdir;
- uint16 dircount16;
- uint32 dirsize;
- TIFFDirEntry* dir;
- uint8* ma;
- TIFFDirEntry* mb;
- uint16 n;
- assert(pdir);
- tif->tif_diroff = diroff;
- if (nextdiroff)
- *nextdiroff = 0;
- if (!isMapped(tif)) {
- if (!SeekOK(tif, tif->tif_diroff)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "%s: Seek error accessing TIFF directory",
- tif->tif_name);
- return 0;
- }
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- if (!ReadOK(tif, &dircount16, sizeof (uint16))) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "%s: Can not read TIFF directory count",
- tif->tif_name);
- return 0;
- }
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabShort(&dircount16);
- if (dircount16>4096)
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Sanity check on directory count failed, this is probably not a valid IFD offset");
- return 0;
- }
- dirsize = 12;
- } else {
- uint64 dircount64;
- if (!ReadOK(tif, &dircount64, sizeof (uint64))) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "%s: Can not read TIFF directory count",
- tif->tif_name);
- return 0;
- }
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabLong8(&dircount64);
- if (dircount64>4096)
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Sanity check on directory count failed, this is probably not a valid IFD offset");
- return 0;
- }
- dircount16 = (uint16)dircount64;
- dirsize = 20;
- }
- origdir = _TIFFCheckMalloc(tif, dircount16,
- dirsize, "to read TIFF directory");
- if (origdir == NULL)
- return 0;
- if (!ReadOK(tif, origdir, (tmsize_t)(dircount16*dirsize))) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "%.100s: Can not read TIFF directory",
- tif->tif_name);
- _TIFFfree(origdir);
- return 0;
- }
- /*
- * Read offset to next directory for sequential scans if
- * needed.
- */
- if (nextdiroff)
- {
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- uint32 nextdiroff32;
- if (!ReadOK(tif, &nextdiroff32, sizeof(uint32)))
- nextdiroff32 = 0;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(&nextdiroff32);
- *nextdiroff=nextdiroff32;
- } else {
- if (!ReadOK(tif, nextdiroff, sizeof(uint64)))
- *nextdiroff = 0;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(nextdiroff);
- }
- }
- } else {
- tmsize_t m;
- tmsize_t off;
- if (tif->tif_diroff > (uint64)TIFF_INT64_MAX)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Can not read TIFF directory count");
- return(0);
- }
- off = (tmsize_t) tif->tif_diroff;
- /*
- * Check for integer overflow when validating the dir_off,
- * otherwise a very high offset may cause an OOB read and
- * crash the client. Make two comparisons instead of
- *
- * off + sizeof(uint16) > tif->tif_size
- *
- * to avoid overflow.
- */
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- m=off+sizeof(uint16);
- if ((m<off)||(m<(tmsize_t)sizeof(uint16))||(m>tif->tif_size)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Can not read TIFF directory count");
- return 0;
- } else {
- _TIFFmemcpy(&dircount16, tif->tif_base + off,
- sizeof(uint16));
- }
- off += sizeof (uint16);
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabShort(&dircount16);
- if (dircount16>4096)
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Sanity check on directory count failed, this is probably not a valid IFD offset");
- return 0;
- }
- dirsize = 12;
- }
- else
- {
- uint64 dircount64;
- m=off+sizeof(uint64);
- if ((m<off)||(m<(tmsize_t)sizeof(uint64))||(m>tif->tif_size)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Can not read TIFF directory count");
- return 0;
- } else {
- _TIFFmemcpy(&dircount64, tif->tif_base + off,
- sizeof(uint64));
- }
- off += sizeof (uint64);
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabLong8(&dircount64);
- if (dircount64>4096)
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Sanity check on directory count failed, this is probably not a valid IFD offset");
- return 0;
- }
- dircount16 = (uint16)dircount64;
- dirsize = 20;
- }
- if (dircount16 == 0 )
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Sanity check on directory count failed, zero tag directories not supported");
- return 0;
- }
- origdir = _TIFFCheckMalloc(tif, dircount16,
- dirsize,
- "to read TIFF directory");
- if (origdir == NULL)
- return 0;
- m=off+dircount16*dirsize;
- if ((m<off)||(m<(tmsize_t)(dircount16*dirsize))||(m>tif->tif_size)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Can not read TIFF directory");
- _TIFFfree(origdir);
- return 0;
- } else {
- _TIFFmemcpy(origdir, tif->tif_base + off,
- dircount16 * dirsize);
- }
- if (nextdiroff) {
- off += dircount16 * dirsize;
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- uint32 nextdiroff32;
- m=off+sizeof(uint32);
- if ((m<off)||(m<(tmsize_t)sizeof(uint32))||(m>tif->tif_size))
- nextdiroff32 = 0;
- else
- _TIFFmemcpy(&nextdiroff32, tif->tif_base + off,
- sizeof (uint32));
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(&nextdiroff32);
- *nextdiroff = nextdiroff32;
- }
- else
- {
- m=off+sizeof(uint64);
- if ((m<off)||(m<(tmsize_t)sizeof(uint64))||(m>tif->tif_size))
- *nextdiroff = 0;
- else
- _TIFFmemcpy(nextdiroff, tif->tif_base + off,
- sizeof (uint64));
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(nextdiroff);
- }
- }
- }
- dir = (TIFFDirEntry*)_TIFFCheckMalloc(tif, dircount16,
- sizeof(TIFFDirEntry),
- "to read TIFF directory");
- if (dir==0)
- {
- _TIFFfree(origdir);
- return 0;
- }
- ma=(uint8*)origdir;
- mb=dir;
- for (n=0; n<dircount16; n++)
- {
- mb->tdir_ignore = FALSE;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16*)ma);
- mb->tdir_tag=*(uint16*)ma;
- ma+=sizeof(uint16);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16*)ma);
- mb->tdir_type=*(uint16*)ma;
- ma+=sizeof(uint16);
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32*)ma);
- mb->tdir_count=(uint64)(*(uint32*)ma);
- ma+=sizeof(uint32);
- mb->tdir_offset.toff_long8=0;
- *(uint32*)(&mb->tdir_offset)=*(uint32*)ma;
- ma+=sizeof(uint32);
- }
- else
- {
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64*)ma);
- mb->tdir_count=TIFFReadUInt64(ma);
- ma+=sizeof(uint64);
- mb->tdir_offset.toff_long8=TIFFReadUInt64(ma);
- ma+=sizeof(uint64);
- }
- mb++;
- }
- _TIFFfree(origdir);
- *pdir = dir;
- return dircount16;
- }
- /*
- * Fetch a tag that is not handled by special case code.
- */
- static int
- TIFFFetchNormalTag(TIFF* tif, TIFFDirEntry* dp, int recover)
- {
- static const char module[] = "TIFFFetchNormalTag";
- enum TIFFReadDirEntryErr err;
- uint32 fii;
- const TIFFField* fip = NULL;
- TIFFReadDirectoryFindFieldInfo(tif,dp->tdir_tag,&fii);
- if( fii == FAILED_FII )
- {
- TIFFErrorExt(tif->tif_clientdata, "TIFFFetchNormalTag",
- "No definition found for tag %d",
- dp->tdir_tag);
- return 0;
- }
- fip=tif->tif_fields[fii];
- assert(fip != NULL); /* should not happen */
- assert(fip->set_field_type!=TIFF_SETGET_OTHER); /* if so, we shouldn't arrive here but deal with this in specialized code */
- assert(fip->set_field_type!=TIFF_SETGET_INT); /* if so, we shouldn't arrive here as this is only the case for pseudo-tags */
- err=TIFFReadDirEntryErrOk;
- switch (fip->set_field_type)
- {
- case TIFF_SETGET_UNDEFINED:
- break;
- case TIFF_SETGET_ASCII:
- {
- uint8* data;
- assert(fip->field_passcount==0);
- err=TIFFReadDirEntryByteArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- uint32 mb = 0;
- int n;
- if (data != NULL)
- {
- uint8* ma = data;
- while (mb<(uint32)dp->tdir_count)
- {
- if (*ma==0)
- break;
- ma++;
- mb++;
- }
- }
- if (mb+1<(uint32)dp->tdir_count)
- TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" contains null byte in value; value incorrectly truncated during reading due to implementation limitations",fip->field_name);
- else if (mb+1>(uint32)dp->tdir_count)
- {
- uint8* o;
- TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte",fip->field_name);
- if ((uint32)dp->tdir_count+1!=dp->tdir_count+1)
- o=NULL;
- else
- o=_TIFFmalloc((uint32)dp->tdir_count+1);
- if (o==NULL)
- {
- if (data!=NULL)
- _TIFFfree(data);
- return(0);
- }
- _TIFFmemcpy(o,data,(uint32)dp->tdir_count);
- o[(uint32)dp->tdir_count]=0;
- if (data!=0)
- _TIFFfree(data);
- data=o;
- }
- n=TIFFSetField(tif,dp->tdir_tag,data);
- if (data!=0)
- _TIFFfree(data);
- if (!n)
- return(0);
- }
- }
- break;
- case TIFF_SETGET_UINT8:
- {
- uint8 data=0;
- assert(fip->field_readcount==1);
- assert(fip->field_passcount==0);
- err=TIFFReadDirEntryByte(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- if (!TIFFSetField(tif,dp->tdir_tag,data))
- return(0);
- }
- }
- break;
- case TIFF_SETGET_UINT16:
- {
- uint16 data;
- assert(fip->field_readcount==1);
- assert(fip->field_passcount==0);
- err=TIFFReadDirEntryShort(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- if (!TIFFSetField(tif,dp->tdir_tag,data))
- return(0);
- }
- }
- break;
- case TIFF_SETGET_UINT32:
- {
- uint32 data;
- assert(fip->field_readcount==1);
- assert(fip->field_passcount==0);
- err=TIFFReadDirEntryLong(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- if (!TIFFSetField(tif,dp->tdir_tag,data))
- return(0);
- }
- }
- break;
- case TIFF_SETGET_UINT64:
- {
- uint64 data;
- assert(fip->field_readcount==1);
- assert(fip->field_passcount==0);
- err=TIFFReadDirEntryLong8(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- if (!TIFFSetField(tif,dp->tdir_tag,data))
- return(0);
- }
- }
- break;
- case TIFF_SETGET_FLOAT:
- {
- float data;
- assert(fip->field_readcount==1);
- assert(fip->field_passcount==0);
- err=TIFFReadDirEntryFloat(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- if (!TIFFSetField(tif,dp->tdir_tag,data))
- return(0);
- }
- }
- break;
- case TIFF_SETGET_DOUBLE:
- {
- double data;
- assert(fip->field_readcount==1);
- assert(fip->field_passcount==0);
- err=TIFFReadDirEntryDouble(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- if (!TIFFSetField(tif,dp->tdir_tag,data))
- return(0);
- }
- }
- break;
- case TIFF_SETGET_IFD8:
- {
- uint64 data;
- assert(fip->field_readcount==1);
- assert(fip->field_passcount==0);
- err=TIFFReadDirEntryIfd8(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- if (!TIFFSetField(tif,dp->tdir_tag,data))
- return(0);
- }
- }
- break;
- case TIFF_SETGET_UINT16_PAIR:
- {
- uint16* data;
- assert(fip->field_readcount==2);
- assert(fip->field_passcount==0);
- if (dp->tdir_count!=2) {
- TIFFWarningExt(tif->tif_clientdata,module,
- "incorrect count for field \"%s\", expected 2, got %d",
- fip->field_name,(int)dp->tdir_count);
- return(0);
- }
- err=TIFFReadDirEntryShortArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- assert(data); /* avoid CLang static Analyzer false positive */
- m=TIFFSetField(tif,dp->tdir_tag,data[0],data[1]);
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- break;
- case TIFF_SETGET_C0_UINT8:
- {
- uint8* data;
- assert(fip->field_readcount>=1);
- assert(fip->field_passcount==0);
- if (dp->tdir_count!=(uint64)fip->field_readcount) {
- TIFFWarningExt(tif->tif_clientdata,module,
- "incorrect count for field \"%s\", expected %d, got %d",
- fip->field_name,(int) fip->field_readcount, (int)dp->tdir_count);
- return 0;
- }
- else
- {
- err=TIFFReadDirEntryByteArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- }
- break;
- case TIFF_SETGET_C0_UINT16:
- {
- uint16* data;
- assert(fip->field_readcount>=1);
- assert(fip->field_passcount==0);
- if (dp->tdir_count!=(uint64)fip->field_readcount)
- /* corrupt file */;
- else
- {
- err=TIFFReadDirEntryShortArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- }
- break;
- case TIFF_SETGET_C0_UINT32:
- {
- uint32* data;
- assert(fip->field_readcount>=1);
- assert(fip->field_passcount==0);
- if (dp->tdir_count!=(uint64)fip->field_readcount)
- /* corrupt file */;
- else
- {
- err=TIFFReadDirEntryLongArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- }
- break;
- case TIFF_SETGET_C0_FLOAT:
- {
- float* data;
- assert(fip->field_readcount>=1);
- assert(fip->field_passcount==0);
- if (dp->tdir_count!=(uint64)fip->field_readcount)
- /* corrupt file */;
- else
- {
- err=TIFFReadDirEntryFloatArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- }
- break;
- /*--: Rational2Double: Extend for Double Arrays and Rational-Arrays read into Double-Arrays. */
- case TIFF_SETGET_C0_DOUBLE:
- {
- double* data;
- assert(fip->field_readcount>=1);
- assert(fip->field_passcount==0);
- if (dp->tdir_count!=(uint64)fip->field_readcount)
- /* corrupt file */;
- else
- {
- err=TIFFReadDirEntryDoubleArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- }
- break;
- case TIFF_SETGET_C16_ASCII:
- {
- uint8* data;
- assert(fip->field_readcount==TIFF_VARIABLE);
- assert(fip->field_passcount==1);
- if (dp->tdir_count>0xFFFF)
- err=TIFFReadDirEntryErrCount;
- else
- {
- err=TIFFReadDirEntryByteArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- if( data != 0 && dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' )
- {
- TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name);
- data[dp->tdir_count-1] = '\0';
- }
- m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- }
- break;
- case TIFF_SETGET_C16_UINT8:
- {
- uint8* data;
- assert(fip->field_readcount==TIFF_VARIABLE);
- assert(fip->field_passcount==1);
- if (dp->tdir_count>0xFFFF)
- err=TIFFReadDirEntryErrCount;
- else
- {
- err=TIFFReadDirEntryByteArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- }
- break;
- case TIFF_SETGET_C16_UINT16:
- {
- uint16* data;
- assert(fip->field_readcount==TIFF_VARIABLE);
- assert(fip->field_passcount==1);
- if (dp->tdir_count>0xFFFF)
- err=TIFFReadDirEntryErrCount;
- else
- {
- err=TIFFReadDirEntryShortArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- }
- break;
- case TIFF_SETGET_C16_UINT32:
- {
- uint32* data;
- assert(fip->field_readcount==TIFF_VARIABLE);
- assert(fip->field_passcount==1);
- if (dp->tdir_count>0xFFFF)
- err=TIFFReadDirEntryErrCount;
- else
- {
- err=TIFFReadDirEntryLongArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- }
- break;
- case TIFF_SETGET_C16_UINT64:
- {
- uint64* data;
- assert(fip->field_readcount==TIFF_VARIABLE);
- assert(fip->field_passcount==1);
- if (dp->tdir_count>0xFFFF)
- err=TIFFReadDirEntryErrCount;
- else
- {
- err=TIFFReadDirEntryLong8Array(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- }
- break;
- case TIFF_SETGET_C16_FLOAT:
- {
- float* data;
- assert(fip->field_readcount==TIFF_VARIABLE);
- assert(fip->field_passcount==1);
- if (dp->tdir_count>0xFFFF)
- err=TIFFReadDirEntryErrCount;
- else
- {
- err=TIFFReadDirEntryFloatArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- }
- break;
- case TIFF_SETGET_C16_DOUBLE:
- {
- double* data;
- assert(fip->field_readcount==TIFF_VARIABLE);
- assert(fip->field_passcount==1);
- if (dp->tdir_count>0xFFFF)
- err=TIFFReadDirEntryErrCount;
- else
- {
- err=TIFFReadDirEntryDoubleArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- }
- break;
- case TIFF_SETGET_C16_IFD8:
- {
- uint64* data;
- assert(fip->field_readcount==TIFF_VARIABLE);
- assert(fip->field_passcount==1);
- if (dp->tdir_count>0xFFFF)
- err=TIFFReadDirEntryErrCount;
- else
- {
- err=TIFFReadDirEntryIfd8Array(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint16)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- }
- break;
- case TIFF_SETGET_C32_ASCII:
- {
- uint8* data;
- assert(fip->field_readcount==TIFF_VARIABLE2);
- assert(fip->field_passcount==1);
- err=TIFFReadDirEntryByteArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- if( data != 0 && dp->tdir_count > 0 && data[dp->tdir_count-1] != '\0' )
- {
- TIFFWarningExt(tif->tif_clientdata,module,"ASCII value for tag \"%s\" does not end in null byte. Forcing it to be null",fip->field_name);
- data[dp->tdir_count-1] = '\0';
- }
- m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- break;
- case TIFF_SETGET_C32_UINT8:
- {
- uint8* data;
- assert(fip->field_readcount==TIFF_VARIABLE2);
- assert(fip->field_passcount==1);
- err=TIFFReadDirEntryByteArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- break;
- case TIFF_SETGET_C32_SINT8:
- {
- int8* data = NULL;
- assert(fip->field_readcount==TIFF_VARIABLE2);
- assert(fip->field_passcount==1);
- err=TIFFReadDirEntrySbyteArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- break;
- case TIFF_SETGET_C32_UINT16:
- {
- uint16* data;
- assert(fip->field_readcount==TIFF_VARIABLE2);
- assert(fip->field_passcount==1);
- err=TIFFReadDirEntryShortArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- break;
- case TIFF_SETGET_C32_SINT16:
- {
- int16* data = NULL;
- assert(fip->field_readcount==TIFF_VARIABLE2);
- assert(fip->field_passcount==1);
- err=TIFFReadDirEntrySshortArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- break;
- case TIFF_SETGET_C32_UINT32:
- {
- uint32* data;
- assert(fip->field_readcount==TIFF_VARIABLE2);
- assert(fip->field_passcount==1);
- err=TIFFReadDirEntryLongArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- break;
- case TIFF_SETGET_C32_SINT32:
- {
- int32* data = NULL;
- assert(fip->field_readcount==TIFF_VARIABLE2);
- assert(fip->field_passcount==1);
- err=TIFFReadDirEntrySlongArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- break;
- case TIFF_SETGET_C32_UINT64:
- {
- uint64* data;
- assert(fip->field_readcount==TIFF_VARIABLE2);
- assert(fip->field_passcount==1);
- err=TIFFReadDirEntryLong8Array(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- break;
- case TIFF_SETGET_C32_SINT64:
- {
- int64* data = NULL;
- assert(fip->field_readcount==TIFF_VARIABLE2);
- assert(fip->field_passcount==1);
- err=TIFFReadDirEntrySlong8Array(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- break;
- case TIFF_SETGET_C32_FLOAT:
- {
- float* data;
- assert(fip->field_readcount==TIFF_VARIABLE2);
- assert(fip->field_passcount==1);
- err=TIFFReadDirEntryFloatArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- break;
- case TIFF_SETGET_C32_DOUBLE:
- {
- double* data;
- assert(fip->field_readcount==TIFF_VARIABLE2);
- assert(fip->field_passcount==1);
- err=TIFFReadDirEntryDoubleArray(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- break;
- case TIFF_SETGET_C32_IFD8:
- {
- uint64* data;
- assert(fip->field_readcount==TIFF_VARIABLE2);
- assert(fip->field_passcount==1);
- err=TIFFReadDirEntryIfd8Array(tif,dp,&data);
- if (err==TIFFReadDirEntryErrOk)
- {
- int m;
- m=TIFFSetField(tif,dp->tdir_tag,(uint32)(dp->tdir_count),data);
- if (data!=0)
- _TIFFfree(data);
- if (!m)
- return(0);
- }
- }
- break;
- default:
- assert(0); /* we should never get here */
- break;
- }
- if (err!=TIFFReadDirEntryErrOk)
- {
- TIFFReadDirEntryOutputErr(tif,err,module,fip->field_name,recover);
- return(0);
- }
- return(1);
- }
- /*
- * Fetch a set of offsets or lengths.
- * While this routine says "strips", in fact it's also used for tiles.
- */
- static int
- TIFFFetchStripThing(TIFF* tif, TIFFDirEntry* dir, uint32 nstrips, uint64** lpp)
- {
- static const char module[] = "TIFFFetchStripThing";
- enum TIFFReadDirEntryErr err;
- uint64* data;
- err=TIFFReadDirEntryLong8ArrayWithLimit(tif,dir,&data,nstrips);
- if (err!=TIFFReadDirEntryErrOk)
- {
- const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag);
- TIFFReadDirEntryOutputErr(tif,err,module,fip ? fip->field_name : "unknown tagname",0);
- return(0);
- }
- if (dir->tdir_count<(uint64)nstrips)
- {
- uint64* resizeddata;
- const TIFFField* fip = TIFFFieldWithTag(tif,dir->tdir_tag);
- const char* pszMax = getenv("LIBTIFF_STRILE_ARRAY_MAX_RESIZE_COUNT");
- uint32 max_nstrips = 1000000;
- if( pszMax )
- max_nstrips = (uint32) atoi(pszMax);
- TIFFReadDirEntryOutputErr(tif,TIFFReadDirEntryErrCount,
- module,
- fip ? fip->field_name : "unknown tagname",
- ( nstrips <= max_nstrips ) );
- if( nstrips > max_nstrips )
- {
- _TIFFfree(data);
- return(0);
- }
- resizeddata=(uint64*)_TIFFCheckMalloc(tif,nstrips,sizeof(uint64),"for strip array");
- if (resizeddata==0) {
- _TIFFfree(data);
- return(0);
- }
- _TIFFmemcpy(resizeddata,data,(uint32)dir->tdir_count*sizeof(uint64));
- _TIFFmemset(resizeddata+(uint32)dir->tdir_count,0,(nstrips-(uint32)dir->tdir_count)*sizeof(uint64));
- _TIFFfree(data);
- data=resizeddata;
- }
- *lpp=data;
- return(1);
- }
- /*
- * Fetch and set the SubjectDistance EXIF tag.
- */
- static int
- TIFFFetchSubjectDistance(TIFF* tif, TIFFDirEntry* dir)
- {
- static const char module[] = "TIFFFetchSubjectDistance";
- enum TIFFReadDirEntryErr err;
- UInt64Aligned_t m;
- m.l=0;
- assert(sizeof(double)==8);
- assert(sizeof(uint64)==8);
- assert(sizeof(uint32)==4);
- if (dir->tdir_count!=1)
- err=TIFFReadDirEntryErrCount;
- else if (dir->tdir_type!=TIFF_RATIONAL)
- err=TIFFReadDirEntryErrType;
- else
- {
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- uint32 offset;
- offset=*(uint32*)(&dir->tdir_offset);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(&offset);
- err=TIFFReadDirEntryData(tif,offset,8,m.i);
- }
- else
- {
- m.l=dir->tdir_offset.toff_long8;
- err=TIFFReadDirEntryErrOk;
- }
- }
- if (err==TIFFReadDirEntryErrOk)
- {
- double n;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong(m.i,2);
- if (m.i[0]==0)
- n=0.0;
- else if (m.i[0]==0xFFFFFFFF || m.i[1]==0)
- /*
- * XXX: Numerator 0xFFFFFFFF means that we have infinite
- * distance. Indicate that with a negative floating point
- * SubjectDistance value.
- */
- n=-1.0;
- else
- n=(double)m.i[0]/(double)m.i[1];
- return(TIFFSetField(tif,dir->tdir_tag,n));
- }
- else
- {
- TIFFReadDirEntryOutputErr(tif,err,module,"SubjectDistance",TRUE);
- return(0);
- }
- }
- static void allocChoppedUpStripArrays(TIFF* tif, uint32 nstrips,
- uint64 stripbytes, uint32 rowsperstrip)
- {
- TIFFDirectory *td = &tif->tif_dir;
- uint64 bytecount;
- uint64 offset;
- uint64 last_offset;
- uint64 last_bytecount;
- uint32 i;
- uint64 *newcounts;
- uint64 *newoffsets;
- offset = TIFFGetStrileOffset(tif, 0);
- last_offset = TIFFGetStrileOffset(tif, td->td_nstrips-1);
- last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips-1);
- if( last_offset > TIFF_UINT64_MAX - last_bytecount ||
- last_offset + last_bytecount < offset )
- {
- return;
- }
- bytecount = last_offset + last_bytecount - offset;
- newcounts = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
- "for chopped \"StripByteCounts\" array");
- newoffsets = (uint64*) _TIFFCheckMalloc(tif, nstrips, sizeof (uint64),
- "for chopped \"StripOffsets\" array");
- if (newcounts == NULL || newoffsets == NULL) {
- /*
- * Unable to allocate new strip information, give up and use
- * the original one strip information.
- */
- if (newcounts != NULL)
- _TIFFfree(newcounts);
- if (newoffsets != NULL)
- _TIFFfree(newoffsets);
- return;
- }
- /*
- * Fill the strip information arrays with new bytecounts and offsets
- * that reflect the broken-up format.
- */
- for (i = 0; i < nstrips; i++)
- {
- if (stripbytes > bytecount)
- stripbytes = bytecount;
- newcounts[i] = stripbytes;
- newoffsets[i] = stripbytes ? offset : 0;
- offset += stripbytes;
- bytecount -= stripbytes;
- }
- /*
- * Replace old single strip info with multi-strip info.
- */
- td->td_stripsperimage = td->td_nstrips = nstrips;
- TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
- _TIFFfree(td->td_stripbytecount_p);
- _TIFFfree(td->td_stripoffset_p);
- td->td_stripbytecount_p = newcounts;
- td->td_stripoffset_p = newoffsets;
- #ifdef STRIPBYTECOUNTSORTED_UNUSED
- td->td_stripbytecountsorted = 1;
- #endif
- tif->tif_flags |= TIFF_CHOPPEDUPARRAYS;
- }
- /*
- * Replace a single strip (tile) of uncompressed data by multiple strips
- * (tiles), each approximately STRIP_SIZE_DEFAULT bytes. This is useful for
- * dealing with large images or for dealing with machines with a limited
- * amount memory.
- */
- static void
- ChopUpSingleUncompressedStrip(TIFF* tif)
- {
- register TIFFDirectory *td = &tif->tif_dir;
- uint64 bytecount;
- uint64 offset;
- uint32 rowblock;
- uint64 rowblockbytes;
- uint64 stripbytes;
- uint32 nstrips;
- uint32 rowsperstrip;
- bytecount = TIFFGetStrileByteCount(tif, 0);
- /* On a newly created file, just re-opened to be filled, we */
- /* don't want strip chop to trigger as it is going to cause issues */
- /* later ( StripOffsets and StripByteCounts improperly filled) . */
- if( bytecount == 0 && tif->tif_mode != O_RDONLY )
- return;
- offset = TIFFGetStrileByteCount(tif, 0);
- assert(td->td_planarconfig == PLANARCONFIG_CONTIG);
- if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
- (!isUpSampled(tif)))
- rowblock = td->td_ycbcrsubsampling[1];
- else
- rowblock = 1;
- rowblockbytes = TIFFVTileSize64(tif, rowblock);
- /*
- * Make the rows hold at least one scanline, but fill specified amount
- * of data if possible.
- */
- if (rowblockbytes > STRIP_SIZE_DEFAULT) {
- stripbytes = rowblockbytes;
- rowsperstrip = rowblock;
- } else if (rowblockbytes > 0 ) {
- uint32 rowblocksperstrip;
- rowblocksperstrip = (uint32) (STRIP_SIZE_DEFAULT / rowblockbytes);
- rowsperstrip = rowblocksperstrip * rowblock;
- stripbytes = rowblocksperstrip * rowblockbytes;
- }
- else
- return;
- /*
- * never increase the number of rows per strip
- */
- if (rowsperstrip >= td->td_rowsperstrip)
- return;
- nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
- if( nstrips == 0 )
- return;
- /* If we are going to allocate a lot of memory, make sure that the */
- /* file is as big as needed */
- if( tif->tif_mode == O_RDONLY &&
- nstrips > 1000000 &&
- (offset >= TIFFGetFileSize(tif) ||
- stripbytes > (TIFFGetFileSize(tif) - offset) / (nstrips - 1)) )
- {
- return;
- }
- allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
- }
- /*
- * Replace a file with contiguous strips > 2 GB of uncompressed data by
- * multiple smaller strips. This is useful for
- * dealing with large images or for dealing with machines with a limited
- * amount memory.
- */
- static void TryChopUpUncompressedBigTiff( TIFF* tif )
- {
- TIFFDirectory *td = &tif->tif_dir;
- uint32 rowblock;
- uint64 rowblockbytes;
- uint32 i;
- uint64 stripsize;
- uint32 rowblocksperstrip;
- uint32 rowsperstrip;
- uint64 stripbytes;
- uint32 nstrips;
- stripsize = TIFFStripSize64(tif);
- assert( tif->tif_dir.td_planarconfig == PLANARCONFIG_CONTIG );
- assert( tif->tif_dir.td_compression == COMPRESSION_NONE );
- assert( (tif->tif_flags&(TIFF_STRIPCHOP|TIFF_ISTILED)) == TIFF_STRIPCHOP );
- assert( stripsize > 0x7FFFFFFFUL );
- /* On a newly created file, just re-opened to be filled, we */
- /* don't want strip chop to trigger as it is going to cause issues */
- /* later ( StripOffsets and StripByteCounts improperly filled) . */
- if( TIFFGetStrileByteCount(tif, 0) == 0 && tif->tif_mode != O_RDONLY )
- return;
- if ((td->td_photometric == PHOTOMETRIC_YCBCR)&&
- (!isUpSampled(tif)))
- rowblock = td->td_ycbcrsubsampling[1];
- else
- rowblock = 1;
- rowblockbytes = TIFFVStripSize64(tif, rowblock);
- if( rowblockbytes == 0 || rowblockbytes > 0x7FFFFFFFUL )
- {
- /* In case of file with gigantic width */
- return;
- }
- /* Check that the strips are contiguous and of the expected size */
- for( i = 0; i < td->td_nstrips; i++ )
- {
- if( i == td->td_nstrips - 1 )
- {
- if( TIFFGetStrileByteCount(tif, i) < TIFFVStripSize64(
- tif, td->td_imagelength - i * td->td_rowsperstrip ) )
- {
- return;
- }
- }
- else
- {
- if( TIFFGetStrileByteCount(tif, i) != stripsize )
- {
- return;
- }
- if( i > 0 && TIFFGetStrileOffset(tif, i) !=
- TIFFGetStrileOffset(tif, i-1) + TIFFGetStrileByteCount(tif, i-1) )
- {
- return;
- }
- }
- }
- /* Aim for 512 MB strips (that will still be manageable by 32 bit builds */
- rowblocksperstrip = (uint32) (512 * 1024 * 1024 / rowblockbytes);
- if( rowblocksperstrip == 0 )
- rowblocksperstrip = 1;
- rowsperstrip = rowblocksperstrip * rowblock;
- stripbytes = rowblocksperstrip * rowblockbytes;
- assert( stripbytes <= 0x7FFFFFFFUL );
- nstrips = TIFFhowmany_32(td->td_imagelength, rowsperstrip);
- if( nstrips == 0 )
- return;
- /* If we are going to allocate a lot of memory, make sure that the */
- /* file is as big as needed */
- if( tif->tif_mode == O_RDONLY &&
- nstrips > 1000000 )
- {
- uint64 last_offset = TIFFGetStrileOffset(tif, td->td_nstrips-1);
- uint64 filesize = TIFFGetFileSize(tif);
- uint64 last_bytecount = TIFFGetStrileByteCount(tif, td->td_nstrips-1);
- if( last_offset > filesize ||
- last_bytecount > filesize - last_offset )
- {
- return;
- }
- }
- allocChoppedUpStripArrays(tif, nstrips, stripbytes, rowsperstrip);
- }
- TIFF_NOSANITIZE_UNSIGNED_INT_OVERFLOW
- static uint64 _TIFFUnsanitizedAddUInt64AndInt(uint64 a, int b)
- {
- return a + b;
- }
- /* Read the value of [Strip|Tile]Offset or [Strip|Tile]ByteCount around
- * strip/tile of number strile. Also fetch the neighbouring values using a
- * 4096 byte page size.
- */
- static
- int _TIFFPartialReadStripArray( TIFF* tif, TIFFDirEntry* dirent,
- int strile, uint64* panVals )
- {
- static const char module[] = "_TIFFPartialReadStripArray";
- #define IO_CACHE_PAGE_SIZE 4096
- size_t sizeofval;
- const int bSwab = (tif->tif_flags & TIFF_SWAB) != 0;
- int sizeofvalint;
- uint64 nBaseOffset;
- uint64 nOffset;
- uint64 nOffsetStartPage;
- uint64 nOffsetEndPage;
- tmsize_t nToRead;
- tmsize_t nRead;
- uint64 nLastStripOffset;
- int iStartBefore;
- int i;
- const uint32 arraySize = tif->tif_dir.td_stripoffsetbyteallocsize;
- unsigned char buffer[2 * IO_CACHE_PAGE_SIZE];
- assert( dirent->tdir_count > 4 );
- if( dirent->tdir_type == TIFF_SHORT )
- {
- sizeofval = sizeof(uint16);
- }
- else if( dirent->tdir_type == TIFF_LONG )
- {
- sizeofval = sizeof(uint32);
- }
- else if( dirent->tdir_type == TIFF_LONG8 )
- {
- sizeofval = sizeof(uint64);
- }
- else if( dirent->tdir_type == TIFF_SLONG8 )
- {
- /* Non conformant but used by some images as in */
- /* https://github.com/OSGeo/gdal/issues/2165 */
- sizeofval = sizeof(int64);
- }
- else
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Invalid type for [Strip|Tile][Offset/ByteCount] tag");
- panVals[strile] = 0;
- return 0;
- }
- sizeofvalint = (int)(sizeofval);
- if( tif->tif_flags&TIFF_BIGTIFF )
- {
- uint64 offset = dirent->tdir_offset.toff_long8;
- if( bSwab )
- TIFFSwabLong8(&offset);
- nBaseOffset = offset;
- }
- else
- {
- uint32 offset = dirent->tdir_offset.toff_long;
- if( bSwab )
- TIFFSwabLong(&offset);
- nBaseOffset = offset;
- }
- /* To avoid later unsigned integer overflows */
- if( nBaseOffset > (uint64)TIFF_INT64_MAX )
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Cannot read offset/size for strile %d", strile);
- panVals[strile] = 0;
- return 0;
- }
- nOffset = nBaseOffset + sizeofval * strile;
- nOffsetStartPage =
- (nOffset / IO_CACHE_PAGE_SIZE) * IO_CACHE_PAGE_SIZE;
- nOffsetEndPage = nOffsetStartPage + IO_CACHE_PAGE_SIZE;
- if( nOffset + sizeofval > nOffsetEndPage )
- nOffsetEndPage += IO_CACHE_PAGE_SIZE;
- #undef IO_CACHE_PAGE_SIZE
- nLastStripOffset = nBaseOffset + arraySize * sizeofval;
- if( nLastStripOffset < nOffsetEndPage )
- nOffsetEndPage = nLastStripOffset;
- if( nOffsetStartPage >= nOffsetEndPage )
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Cannot read offset/size for strile %d", strile);
- panVals[strile] = 0;
- return 0;
- }
- if (!SeekOK(tif,nOffsetStartPage))
- {
- panVals[strile] = 0;
- return 0;
- }
- nToRead = (tmsize_t)(nOffsetEndPage - nOffsetStartPage);
- nRead = TIFFReadFile(tif, buffer, nToRead);
- if( nRead < nToRead )
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Cannot read offset/size for strile around ~%d", strile);
- return 0;
- }
- iStartBefore = -(int)((nOffset - nOffsetStartPage) / sizeofval);
- if( strile + iStartBefore < 0 )
- iStartBefore = -strile;
- for( i = iStartBefore;
- (uint32)(strile + i) < arraySize &&
- _TIFFUnsanitizedAddUInt64AndInt(nOffset, (i + 1) * sizeofvalint) <= nOffsetEndPage;
- ++i )
- {
- if( dirent->tdir_type == TIFF_SHORT )
- {
- uint16 val;
- memcpy(&val,
- buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
- sizeof(val));
- if( bSwab )
- TIFFSwabShort(&val);
- panVals[strile + i] = val;
- }
- else if( dirent->tdir_type == TIFF_LONG )
- {
- uint32 val;
- memcpy(&val,
- buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
- sizeof(val));
- if( bSwab )
- TIFFSwabLong(&val);
- panVals[strile + i] = val;
- }
- else if( dirent->tdir_type == TIFF_LONG8 )
- {
- uint64 val;
- memcpy(&val,
- buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
- sizeof(val));
- if( bSwab )
- TIFFSwabLong8(&val);
- panVals[strile + i] = val;
- }
- else /* if( dirent->tdir_type == TIFF_SLONG8 ) */
- {
- /* Non conformant data type */
- int64 val;
- memcpy(&val,
- buffer + (nOffset - nOffsetStartPage) + i * sizeofvalint,
- sizeof(val));
- if( bSwab )
- TIFFSwabLong8((uint64*) &val);
- panVals[strile + i] = (uint64) val;
- }
- }
- return 1;
- }
- static int _TIFFFetchStrileValue(TIFF* tif,
- uint32 strile,
- TIFFDirEntry* dirent,
- uint64** parray)
- {
- static const char module[] = "_TIFFFetchStrileValue";
- TIFFDirectory *td = &tif->tif_dir;
- if( strile >= dirent->tdir_count )
- {
- return 0;
- }
- if( strile >= td->td_stripoffsetbyteallocsize )
- {
- uint32 nStripArrayAllocBefore = td->td_stripoffsetbyteallocsize;
- uint32 nStripArrayAllocNew;
- uint64 nArraySize64;
- size_t nArraySize;
- uint64* offsetArray;
- uint64* bytecountArray;
- if( strile > 1000000 )
- {
- uint64 filesize = TIFFGetFileSize(tif);
- /* Avoid excessive memory allocation attempt */
- /* For such a big blockid we need at least a TIFF_LONG per strile */
- /* for the offset array. */
- if( strile > filesize / sizeof(uint32) )
- {
- TIFFErrorExt(tif->tif_clientdata, module, "File too short");
- return 0;
- }
- }
- if( td->td_stripoffsetbyteallocsize == 0 &&
- td->td_nstrips < 1024 * 1024 )
- {
- nStripArrayAllocNew = td->td_nstrips;
- }
- else
- {
- #define TIFF_MAX(a,b) (((a)>(b)) ? (a) : (b))
- #define TIFF_MIN(a,b) (((a)<(b)) ? (a) : (b))
- nStripArrayAllocNew = TIFF_MAX(strile + 1, 1024U * 512U );
- if( nStripArrayAllocNew < 0xFFFFFFFFU / 2 )
- nStripArrayAllocNew *= 2;
- nStripArrayAllocNew = TIFF_MIN(nStripArrayAllocNew, td->td_nstrips);
- }
- assert( strile < nStripArrayAllocNew );
- nArraySize64 = (uint64)sizeof(uint64) * nStripArrayAllocNew;
- nArraySize = (size_t)(nArraySize64);
- #if SIZEOF_SIZE_T == 4
- if( nArraySize != nArraySize64 )
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Cannot allocate strip offset and bytecount arrays");
- return 0;
- }
- #endif
- offsetArray = (uint64*)(
- _TIFFrealloc( td->td_stripoffset_p, nArraySize ) );
- bytecountArray = (uint64*)(
- _TIFFrealloc( td->td_stripbytecount_p, nArraySize ) );
- if( offsetArray )
- td->td_stripoffset_p = offsetArray;
- if( bytecountArray )
- td->td_stripbytecount_p = bytecountArray;
- if( offsetArray && bytecountArray )
- {
- td->td_stripoffsetbyteallocsize = nStripArrayAllocNew;
- /* Initialize new entries to ~0 / -1 */
- memset(td->td_stripoffset_p + nStripArrayAllocBefore,
- 0xFF,
- (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * sizeof(uint64) );
- memset(td->td_stripbytecount_p + nStripArrayAllocBefore,
- 0xFF,
- (td->td_stripoffsetbyteallocsize - nStripArrayAllocBefore) * sizeof(uint64) );
- }
- else
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Cannot allocate strip offset and bytecount arrays");
- _TIFFfree(td->td_stripoffset_p);
- td->td_stripoffset_p = NULL;
- _TIFFfree(td->td_stripbytecount_p);
- td->td_stripbytecount_p = NULL;
- td->td_stripoffsetbyteallocsize = 0;
- }
- }
- if( *parray == NULL || strile >= td->td_stripoffsetbyteallocsize )
- return 0;
- if( ~((*parray)[strile]) == 0 )
- {
- if( !_TIFFPartialReadStripArray( tif, dirent, strile, *parray ) )
- {
- (*parray)[strile] = 0;
- return 0;
- }
- }
- return 1;
- }
- static uint64 _TIFFGetStrileOffsetOrByteCountValue(TIFF *tif, uint32 strile,
- TIFFDirEntry* dirent,
- uint64** parray,
- int *pbErr)
- {
- TIFFDirectory *td = &tif->tif_dir;
- if( pbErr )
- *pbErr = 0;
- if( (tif->tif_flags&TIFF_DEFERSTRILELOAD) && !(tif->tif_flags&TIFF_CHOPPEDUPARRAYS) )
- {
- if( !(tif->tif_flags&TIFF_LAZYSTRILELOAD) ||
- /* If the values may fit in the toff_long/toff_long8 member */
- /* then use _TIFFFillStriles to simplify _TIFFFetchStrileValue */
- dirent->tdir_count <= 4 )
- {
- if( !_TIFFFillStriles(tif) )
- {
- if( pbErr )
- *pbErr = 1;
- /* Do not return, as we want this function to always */
- /* return the same value if called several times with */
- /* the same arguments */
- }
- }
- else
- {
- if( !_TIFFFetchStrileValue(tif, strile, dirent, parray) )
- {
- if( pbErr )
- *pbErr = 1;
- return 0;
- }
- }
- }
- if( *parray == NULL || strile >= td->td_nstrips )
- {
- if( pbErr )
- *pbErr = 1;
- return 0;
- }
- return (*parray)[strile];
- }
- /* Return the value of the TileOffsets/StripOffsets array for the specified tile/strile */
- uint64 TIFFGetStrileOffset(TIFF *tif, uint32 strile)
- {
- return TIFFGetStrileOffsetWithErr(tif, strile, NULL);
- }
- /* Return the value of the TileOffsets/StripOffsets array for the specified tile/strile */
- uint64 TIFFGetStrileOffsetWithErr(TIFF *tif, uint32 strile, int *pbErr)
- {
- TIFFDirectory *td = &tif->tif_dir;
- return _TIFFGetStrileOffsetOrByteCountValue(tif, strile,
- &(td->td_stripoffset_entry),
- &(td->td_stripoffset_p), pbErr);
- }
- /* Return the value of the TileByteCounts/StripByteCounts array for the specified tile/strile */
- uint64 TIFFGetStrileByteCount(TIFF *tif, uint32 strile)
- {
- return TIFFGetStrileByteCountWithErr(tif, strile, NULL);
- }
- /* Return the value of the TileByteCounts/StripByteCounts array for the specified tile/strile */
- uint64 TIFFGetStrileByteCountWithErr(TIFF *tif, uint32 strile, int *pbErr)
- {
- TIFFDirectory *td = &tif->tif_dir;
- return _TIFFGetStrileOffsetOrByteCountValue(tif, strile,
- &(td->td_stripbytecount_entry),
- &(td->td_stripbytecount_p), pbErr);
- }
- int _TIFFFillStriles( TIFF *tif )
- {
- return _TIFFFillStrilesInternal( tif, 1 );
- }
- static int _TIFFFillStrilesInternal( TIFF *tif, int loadStripByteCount )
- {
- register TIFFDirectory *td = &tif->tif_dir;
- int return_value = 1;
- /* Do not do anything if TIFF_DEFERSTRILELOAD is not set */
- if( !(tif->tif_flags&TIFF_DEFERSTRILELOAD) || (tif->tif_flags&TIFF_CHOPPEDUPARRAYS) != 0 )
- return 1;
- if( tif->tif_flags&TIFF_LAZYSTRILELOAD )
- {
- /* In case of lazy loading, reload completely the arrays */
- _TIFFfree(td->td_stripoffset_p);
- _TIFFfree(td->td_stripbytecount_p);
- td->td_stripoffset_p = NULL;
- td->td_stripbytecount_p = NULL;
- td->td_stripoffsetbyteallocsize = 0;
- tif->tif_flags &= ~TIFF_LAZYSTRILELOAD;
- }
- /* If stripoffset array is already loaded, exit with success */
- if( td->td_stripoffset_p != NULL )
- return 1;
- /* If tdir_count was canceled, then we already got there, but in error */
- if( td->td_stripoffset_entry.tdir_count == 0 )
- return 0;
- if (!TIFFFetchStripThing(tif,&(td->td_stripoffset_entry),
- td->td_nstrips,&td->td_stripoffset_p))
- {
- return_value = 0;
- }
- if (loadStripByteCount &&
- !TIFFFetchStripThing(tif,&(td->td_stripbytecount_entry),
- td->td_nstrips,&td->td_stripbytecount_p))
- {
- return_value = 0;
- }
- _TIFFmemset( &(td->td_stripoffset_entry), 0, sizeof(TIFFDirEntry));
- _TIFFmemset( &(td->td_stripbytecount_entry), 0, sizeof(TIFFDirEntry));
- #ifdef STRIPBYTECOUNTSORTED_UNUSED
- if (tif->tif_dir.td_nstrips > 1 && return_value == 1 ) {
- uint32 strip;
- tif->tif_dir.td_stripbytecountsorted = 1;
- for (strip = 1; strip < tif->tif_dir.td_nstrips; strip++) {
- if (tif->tif_dir.td_stripoffset_p[strip - 1] >
- tif->tif_dir.td_stripoffset_p[strip]) {
- tif->tif_dir.td_stripbytecountsorted = 0;
- break;
- }
- }
- }
- #endif
- return return_value;
- }
- /* vim: set ts=8 sts=8 sw=8 noet: */
- /*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
|