1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739 |
- /*
- * 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 Write Support Routines.
- */
- #include "tiffiop.h"
- #include <float.h> /*--: for Rational2Double */
- #include <math.h> /*--: for Rational2Double */
- #ifdef HAVE_IEEEFP
- #define TIFFCvtNativeToIEEEFloat(tif, n, fp)
- #define TIFFCvtNativeToIEEEDouble(tif, n, dp)
- #else
- extern void TIFFCvtNativeToIEEEFloat(TIFF* tif, uint32_t n, float* fp);
- extern void TIFFCvtNativeToIEEEDouble(TIFF* tif, uint32_t n, double* dp);
- #endif
- static int TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff);
- static int TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value);
- #if 0
- static int TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value);
- #endif
- static int TIFFWriteDirectoryTagAscii(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, char* value);
- static int TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value);
- #ifdef notdef
- static int TIFFWriteDirectoryTagByte(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint8_t value);
- #endif
- static int TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value);
- #if 0
- static int TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint8_t value);
- #endif
- #ifdef notdef
- static int TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int8_t value);
- #endif
- static int TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int8_t* value);
- #if 0
- static int TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int8_t value);
- #endif
- static int TIFFWriteDirectoryTagShort(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t value);
- static int TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint16_t* value);
- static int TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t value);
- #ifdef notdef
- static int TIFFWriteDirectoryTagSshort(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int16_t value);
- #endif
- static int TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int16_t* value);
- #if 0
- static int TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int16_t value);
- #endif
- static int TIFFWriteDirectoryTagLong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t value);
- static int TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value);
- #if 0
- static int TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t value);
- #endif
- #ifdef notdef
- static int TIFFWriteDirectoryTagSlong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int32_t value);
- #endif
- static int TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int32_t* value);
- #if 0
- static int TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int32_t value);
- #endif
- #ifdef notdef
- static int TIFFWriteDirectoryTagLong8(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint64_t value);
- #endif
- static int TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value);
- #ifdef notdef
- static int TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int64_t value);
- #endif
- static int TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int64_t* value);
- static int TIFFWriteDirectoryTagRational(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value);
- static int TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value);
- static int TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value);
- #ifdef notdef
- static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, float value);
- #endif
- static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value);
- #if 0
- static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, float value);
- #endif
- #ifdef notdef
- static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value);
- #endif
- static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value);
- #if 0
- static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value);
- #endif
- static int TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value);
- #ifdef notdef
- static int TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value);
- #endif
- static int TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t value);
- static int TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value);
- static int TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value);
- #ifdef notdef
- static int TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value);
- #endif
- static int TIFFWriteDirectoryTagColormap(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir);
- static int TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir);
- static int TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir);
- static int TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, char* value);
- static int TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value);
- #ifdef notdef
- static int TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint8_t value);
- #endif
- static int TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value);
- #ifdef notdef
- static int TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int8_t value);
- #endif
- static int TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int8_t* value);
- static int TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t value);
- static int TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint16_t* value);
- #ifdef notdef
- static int TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int16_t value);
- #endif
- static int TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int16_t* value);
- static int TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t value);
- static int TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value);
- #ifdef notdef
- static int TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int32_t value);
- #endif
- static int TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int32_t* value);
- #ifdef notdef
- static int TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint64_t value);
- #endif
- static int TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value);
- #ifdef notdef
- static int TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int64_t value);
- #endif
- static int TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int64_t* value);
- static int TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value);
- static int TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value);
- static int TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value);
- /*--: Rational2Double: New functions to support true double-precision for custom rational tag types. */
- static int TIFFWriteDirectoryTagRationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value);
- static int TIFFWriteDirectoryTagSrationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value);
- static int TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value);
- static int TIFFWriteDirectoryTagCheckedSrationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value);
- static void DoubleToRational(double value, uint32_t *num, uint32_t *denom);
- static void DoubleToSrational(double value, int32_t *num, int32_t *denom);
- #if 0
- static void DoubleToRational_direct(double value, unsigned long *num, unsigned long *denom);
- static void DoubleToSrational_direct(double value, long *num, long *denom);
- #endif
- #ifdef notdef
- static int TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, float value);
- #endif
- static int TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value);
- #ifdef notdef
- static int TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value);
- #endif
- static int TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value);
- static int TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value);
- static int TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value);
- static int TIFFWriteDirectoryTagData(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t datatype, uint32_t count, uint32_t datalength, void* data);
- static int TIFFLinkDirectory(TIFF*);
- /*
- * Write the contents of the current directory
- * to the specified file. This routine doesn't
- * handle overwriting a directory with auxiliary
- * storage that's been changed.
- */
- int
- TIFFWriteDirectory(TIFF* tif)
- {
- return TIFFWriteDirectorySec(tif,TRUE,TRUE,NULL);
- }
- /*
- * This is an advanced writing function that must be used in a particular
- * sequence, and generally together with TIFFForceStrileArrayWriting(),
- * to make its intended effect. Its aim is to modify the location
- * where the [Strip/Tile][Offsets/ByteCounts] arrays are located in the file.
- * More precisely, when TIFFWriteCheck() will be called, the tag entries for
- * those arrays will be written with type = count = offset = 0 as a temporary
- * value.
- *
- * Its effect is only valid for the current directory, and before
- * TIFFWriteDirectory() is first called, and will be reset when
- * changing directory.
- *
- * The typical sequence of calls is:
- * TIFFOpen()
- * [ TIFFCreateDirectory(tif) ]
- * Set fields with calls to TIFFSetField(tif, ...)
- * TIFFDeferStrileArrayWriting(tif)
- * TIFFWriteCheck(tif, ...)
- * TIFFWriteDirectory(tif)
- * ... potentially create other directories and come back to the above directory
- * TIFFForceStrileArrayWriting(tif): emit the arrays at the end of file
- *
- * Returns 1 in case of success, 0 otherwise.
- */
- int TIFFDeferStrileArrayWriting(TIFF* tif)
- {
- static const char module[] = "TIFFDeferStrileArrayWriting";
- if (tif->tif_mode == O_RDONLY)
- {
- TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
- "File opened in read-only mode");
- return 0;
- }
- if( tif->tif_diroff != 0 )
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Directory has already been written");
- return 0;
- }
- tif->tif_dir.td_deferstrilearraywriting = TRUE;
- return 1;
- }
- /*
- * Similar to TIFFWriteDirectory(), writes the directory out
- * but leaves all data structures in memory so that it can be
- * written again. This will make a partially written TIFF file
- * readable before it is successfully completed/closed.
- */
- int
- TIFFCheckpointDirectory(TIFF* tif)
- {
- int rc;
- /* Setup the strips arrays, if they haven't already been. */
- if (tif->tif_dir.td_stripoffset_p == NULL)
- (void) TIFFSetupStrips(tif);
- rc = TIFFWriteDirectorySec(tif,TRUE,FALSE,NULL);
- (void) TIFFSetWriteOffset(tif, TIFFSeekFile(tif, 0, SEEK_END));
- return rc;
- }
- int
- TIFFWriteCustomDirectory(TIFF* tif, uint64_t* pdiroff)
- {
- return TIFFWriteDirectorySec(tif,FALSE,FALSE,pdiroff);
- }
- /*
- * Similar to TIFFWriteDirectory(), but if the directory has already
- * been written once, it is relocated to the end of the file, in case it
- * has changed in size. Note that this will result in the loss of the
- * previously used directory space.
- */
- int
- TIFFRewriteDirectory( TIFF *tif )
- {
- static const char module[] = "TIFFRewriteDirectory";
- /* We don't need to do anything special if it hasn't been written. */
- if( tif->tif_diroff == 0 )
- return TIFFWriteDirectory( tif );
- /*
- * Find and zero the pointer to this directory, so that TIFFLinkDirectory
- * will cause it to be added after this directories current pre-link.
- */
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- if (tif->tif_header.classic.tiff_diroff == tif->tif_diroff)
- {
- tif->tif_header.classic.tiff_diroff = 0;
- tif->tif_diroff = 0;
- TIFFSeekFile(tif,4,SEEK_SET);
- if (!WriteOK(tif, &(tif->tif_header.classic.tiff_diroff),4))
- {
- TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
- "Error updating TIFF header");
- return (0);
- }
- }
- else
- {
- uint32_t nextdir;
- nextdir = tif->tif_header.classic.tiff_diroff;
- while(1) {
- uint16_t dircount;
- uint32_t nextnextdir;
- if (!SeekOK(tif, nextdir) ||
- !ReadOK(tif, &dircount, 2)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error fetching directory count");
- return (0);
- }
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabShort(&dircount);
- (void) TIFFSeekFile(tif,
- nextdir+2+dircount*12, SEEK_SET);
- if (!ReadOK(tif, &nextnextdir, 4)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error fetching directory link");
- return (0);
- }
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabLong(&nextnextdir);
- if (nextnextdir==tif->tif_diroff)
- {
- uint32_t m;
- m=0;
- (void) TIFFSeekFile(tif,
- nextdir+2+dircount*12, SEEK_SET);
- if (!WriteOK(tif, &m, 4)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error writing directory link");
- return (0);
- }
- tif->tif_diroff=0;
- break;
- }
- nextdir=nextnextdir;
- }
- }
- }
- else
- {
- if (tif->tif_header.big.tiff_diroff == tif->tif_diroff)
- {
- tif->tif_header.big.tiff_diroff = 0;
- tif->tif_diroff = 0;
- TIFFSeekFile(tif,8,SEEK_SET);
- if (!WriteOK(tif, &(tif->tif_header.big.tiff_diroff),8))
- {
- TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
- "Error updating TIFF header");
- return (0);
- }
- }
- else
- {
- uint64_t nextdir;
- nextdir = tif->tif_header.big.tiff_diroff;
- while(1) {
- uint64_t dircount64;
- uint16_t dircount;
- uint64_t nextnextdir;
- if (!SeekOK(tif, nextdir) ||
- !ReadOK(tif, &dircount64, 8)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error fetching directory count");
- return (0);
- }
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabLong8(&dircount64);
- if (dircount64>0xFFFF)
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Sanity check on tag count failed, likely corrupt TIFF");
- return (0);
- }
- dircount=(uint16_t)dircount64;
- (void) TIFFSeekFile(tif,
- nextdir+8+dircount*20, SEEK_SET);
- if (!ReadOK(tif, &nextnextdir, 8)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error fetching directory link");
- return (0);
- }
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabLong8(&nextnextdir);
- if (nextnextdir==tif->tif_diroff)
- {
- uint64_t m;
- m=0;
- (void) TIFFSeekFile(tif,
- nextdir+8+dircount*20, SEEK_SET);
- if (!WriteOK(tif, &m, 8)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error writing directory link");
- return (0);
- }
- tif->tif_diroff=0;
- break;
- }
- nextdir=nextnextdir;
- }
- }
- }
- /*
- * Now use TIFFWriteDirectory() normally.
- */
- return TIFFWriteDirectory( tif );
- }
- static int
- TIFFWriteDirectorySec(TIFF* tif, int isimage, int imagedone, uint64_t* pdiroff)
- {
- static const char module[] = "TIFFWriteDirectorySec";
- uint32_t ndir;
- TIFFDirEntry* dir;
- uint32_t dirsize;
- void* dirmem;
- uint32_t m;
- if (tif->tif_mode == O_RDONLY)
- return (1);
- _TIFFFillStriles( tif );
-
- /*
- * Clear write state so that subsequent images with
- * different characteristics get the right buffers
- * setup for them.
- */
- if (imagedone)
- {
- if (tif->tif_flags & TIFF_POSTENCODE)
- {
- tif->tif_flags &= ~TIFF_POSTENCODE;
- if (!(*tif->tif_postencode)(tif))
- {
- TIFFErrorExt(tif->tif_clientdata,module,
- "Error post-encoding before directory write");
- return (0);
- }
- }
- (*tif->tif_close)(tif); /* shutdown encoder */
- /*
- * Flush any data that might have been written
- * by the compression close+cleanup routines. But
- * be careful not to write stuff if we didn't add data
- * in the previous steps as the "rawcc" data may well be
- * a previously read tile/strip in mixed read/write mode.
- */
- if (tif->tif_rawcc > 0
- && (tif->tif_flags & TIFF_BEENWRITING) != 0 )
- {
- if( !TIFFFlushData1(tif) )
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error flushing data before directory write");
- return (0);
- }
- }
- if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata)
- {
- _TIFFfree(tif->tif_rawdata);
- tif->tif_rawdata = NULL;
- tif->tif_rawcc = 0;
- tif->tif_rawdatasize = 0;
- tif->tif_rawdataoff = 0;
- tif->tif_rawdataloaded = 0;
- }
- tif->tif_flags &= ~(TIFF_BEENWRITING|TIFF_BUFFERSETUP);
- }
- dir=NULL;
- dirmem=NULL;
- dirsize=0;
- while (1)
- {
- ndir=0;
- if (isimage)
- {
- if (TIFFFieldSet(tif,FIELD_IMAGEDIMENSIONS))
- {
- if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGEWIDTH,tif->tif_dir.td_imagewidth))
- goto bad;
- if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_IMAGELENGTH,tif->tif_dir.td_imagelength))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_TILEDIMENSIONS))
- {
- if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILEWIDTH,tif->tif_dir.td_tilewidth))
- goto bad;
- if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_TILELENGTH,tif->tif_dir.td_tilelength))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_RESOLUTION))
- {
- if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XRESOLUTION,tif->tif_dir.td_xresolution))
- goto bad;
- if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YRESOLUTION,tif->tif_dir.td_yresolution))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_POSITION))
- {
- if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_XPOSITION,tif->tif_dir.td_xposition))
- goto bad;
- if (!TIFFWriteDirectoryTagRational(tif,&ndir,dir,TIFFTAG_YPOSITION,tif->tif_dir.td_yposition))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_SUBFILETYPE))
- {
- if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_SUBFILETYPE,tif->tif_dir.td_subfiletype))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_BITSPERSAMPLE))
- {
- if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_BITSPERSAMPLE,tif->tif_dir.td_bitspersample))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_COMPRESSION))
- {
- if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_COMPRESSION,tif->tif_dir.td_compression))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_PHOTOMETRIC))
- {
- if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PHOTOMETRIC,tif->tif_dir.td_photometric))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_THRESHHOLDING))
- {
- if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_THRESHHOLDING,tif->tif_dir.td_threshholding))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_FILLORDER))
- {
- if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_FILLORDER,tif->tif_dir.td_fillorder))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_ORIENTATION))
- {
- if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_ORIENTATION,tif->tif_dir.td_orientation))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_SAMPLESPERPIXEL))
- {
- if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_SAMPLESPERPIXEL,tif->tif_dir.td_samplesperpixel))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_ROWSPERSTRIP))
- {
- if (!TIFFWriteDirectoryTagShortLong(tif,&ndir,dir,TIFFTAG_ROWSPERSTRIP,tif->tif_dir.td_rowsperstrip))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_MINSAMPLEVALUE))
- {
- if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MINSAMPLEVALUE,tif->tif_dir.td_minsamplevalue))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_MAXSAMPLEVALUE))
- {
- if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_MAXSAMPLEVALUE,tif->tif_dir.td_maxsamplevalue))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_PLANARCONFIG))
- {
- if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_PLANARCONFIG,tif->tif_dir.td_planarconfig))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_RESOLUTIONUNIT))
- {
- if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_RESOLUTIONUNIT,tif->tif_dir.td_resolutionunit))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_PAGENUMBER))
- {
- if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_PAGENUMBER,2,&tif->tif_dir.td_pagenumber[0]))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_STRIPBYTECOUNTS))
- {
- if (!isTiled(tif))
- {
- if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount_p))
- goto bad;
- }
- else
- {
- if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEBYTECOUNTS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripbytecount_p))
- goto bad;
- }
- }
- if (TIFFFieldSet(tif,FIELD_STRIPOFFSETS))
- {
- if (!isTiled(tif))
- {
- /* td_stripoffset_p might be NULL in an odd OJPEG case. See
- * tif_dirread.c around line 3634.
- * 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.
- * We can get here when using tiffset on such a file.
- * See http://bugzilla.maptools.org/show_bug.cgi?id=2500
- */
- if (tif->tif_dir.td_stripoffset_p != NULL &&
- !TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_STRIPOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset_p))
- goto bad;
- }
- else
- {
- if (!TIFFWriteDirectoryTagLongLong8Array(tif,&ndir,dir,TIFFTAG_TILEOFFSETS,tif->tif_dir.td_nstrips,tif->tif_dir.td_stripoffset_p))
- goto bad;
- }
- }
- if (TIFFFieldSet(tif,FIELD_COLORMAP))
- {
- if (!TIFFWriteDirectoryTagColormap(tif,&ndir,dir))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_EXTRASAMPLES))
- {
- if (tif->tif_dir.td_extrasamples)
- {
- uint16_t na;
- uint16_t* nb;
- TIFFGetFieldDefaulted(tif,TIFFTAG_EXTRASAMPLES,&na,&nb);
- if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_EXTRASAMPLES,na,nb))
- goto bad;
- }
- }
- if (TIFFFieldSet(tif,FIELD_SAMPLEFORMAT))
- {
- if (!TIFFWriteDirectoryTagShortPerSample(tif,&ndir,dir,TIFFTAG_SAMPLEFORMAT,tif->tif_dir.td_sampleformat))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_SMINSAMPLEVALUE))
- {
- if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMINSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_sminsamplevalue))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_SMAXSAMPLEVALUE))
- {
- if (!TIFFWriteDirectoryTagSampleformatArray(tif,&ndir,dir,TIFFTAG_SMAXSAMPLEVALUE,tif->tif_dir.td_samplesperpixel,tif->tif_dir.td_smaxsamplevalue))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_IMAGEDEPTH))
- {
- if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_IMAGEDEPTH,tif->tif_dir.td_imagedepth))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_TILEDEPTH))
- {
- if (!TIFFWriteDirectoryTagLong(tif,&ndir,dir,TIFFTAG_TILEDEPTH,tif->tif_dir.td_tiledepth))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_HALFTONEHINTS))
- {
- if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_HALFTONEHINTS,2,&tif->tif_dir.td_halftonehints[0]))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_YCBCRSUBSAMPLING))
- {
- if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,TIFFTAG_YCBCRSUBSAMPLING,2,&tif->tif_dir.td_ycbcrsubsampling[0]))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_YCBCRPOSITIONING))
- {
- if (!TIFFWriteDirectoryTagShort(tif,&ndir,dir,TIFFTAG_YCBCRPOSITIONING,tif->tif_dir.td_ycbcrpositioning))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_REFBLACKWHITE))
- {
- if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,TIFFTAG_REFERENCEBLACKWHITE,6,tif->tif_dir.td_refblackwhite))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_TRANSFERFUNCTION))
- {
- if (!TIFFWriteDirectoryTagTransferfunction(tif,&ndir,dir))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_INKNAMES))
- {
- if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,TIFFTAG_INKNAMES,tif->tif_dir.td_inknameslen,tif->tif_dir.td_inknames))
- goto bad;
- }
- if (TIFFFieldSet(tif,FIELD_SUBIFD))
- {
- if (!TIFFWriteDirectoryTagSubifd(tif,&ndir,dir))
- goto bad;
- }
- {
- uint32_t n;
- for (n=0; n<tif->tif_nfields; n++) {
- const TIFFField* o;
- o = tif->tif_fields[n];
- if ((o->field_bit>=FIELD_CODEC)&&(TIFFFieldSet(tif,o->field_bit)))
- {
- switch (o->get_field_type)
- {
- case TIFF_SETGET_ASCII:
- {
- uint32_t pa;
- char* pb;
- assert(o->field_type==TIFF_ASCII);
- assert(o->field_readcount==TIFF_VARIABLE);
- assert(o->field_passcount==0);
- TIFFGetField(tif,o->field_tag,&pb);
- pa=(uint32_t)(strlen(pb));
- if (!TIFFWriteDirectoryTagAscii(tif, &ndir, dir, (uint16_t)o->field_tag, pa, pb))
- goto bad;
- }
- break;
- case TIFF_SETGET_UINT16:
- {
- uint16_t p;
- assert(o->field_type==TIFF_SHORT);
- assert(o->field_readcount==1);
- assert(o->field_passcount==0);
- TIFFGetField(tif,o->field_tag,&p);
- if (!TIFFWriteDirectoryTagShort(tif, &ndir, dir, (uint16_t)o->field_tag, p))
- goto bad;
- }
- break;
- case TIFF_SETGET_UINT32:
- {
- uint32_t p;
- assert(o->field_type==TIFF_LONG);
- assert(o->field_readcount==1);
- assert(o->field_passcount==0);
- TIFFGetField(tif,o->field_tag,&p);
- if (!TIFFWriteDirectoryTagLong(tif, &ndir, dir, (uint16_t)o->field_tag, p))
- goto bad;
- }
- break;
- case TIFF_SETGET_C32_UINT8:
- {
- uint32_t pa;
- void* pb;
- assert(o->field_type==TIFF_UNDEFINED);
- assert(o->field_readcount==TIFF_VARIABLE2);
- assert(o->field_passcount==1);
- TIFFGetField(tif,o->field_tag,&pa,&pb);
- if (!TIFFWriteDirectoryTagUndefinedArray(tif, &ndir, dir, (uint16_t)o->field_tag, pa, pb))
- goto bad;
- }
- break;
- default:
- TIFFErrorExt(tif->tif_clientdata,module,
- "Cannot write tag %"PRIu32" (%s)",
- TIFFFieldTag(o),
- o->field_name ? o->field_name : "unknown");
- goto bad;
- }
- }
- }
- }
- }
- for (m=0; m<(uint32_t)(tif->tif_dir.td_customValueCount); m++)
- {
- uint16_t tag = (uint16_t)tif->tif_dir.td_customValues[m].info->field_tag;
- uint32_t count = tif->tif_dir.td_customValues[m].count;
- switch (tif->tif_dir.td_customValues[m].info->field_type)
- {
- case TIFF_ASCII:
- if (!TIFFWriteDirectoryTagAscii(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- break;
- case TIFF_UNDEFINED:
- if (!TIFFWriteDirectoryTagUndefinedArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- break;
- case TIFF_BYTE:
- if (!TIFFWriteDirectoryTagByteArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- break;
- case TIFF_SBYTE:
- if (!TIFFWriteDirectoryTagSbyteArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- break;
- case TIFF_SHORT:
- if (!TIFFWriteDirectoryTagShortArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- break;
- case TIFF_SSHORT:
- if (!TIFFWriteDirectoryTagSshortArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- break;
- case TIFF_LONG:
- if (!TIFFWriteDirectoryTagLongArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- break;
- case TIFF_SLONG:
- if (!TIFFWriteDirectoryTagSlongArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- break;
- case TIFF_LONG8:
- if (!TIFFWriteDirectoryTagLong8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- break;
- case TIFF_SLONG8:
- if (!TIFFWriteDirectoryTagSlong8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- break;
- case TIFF_RATIONAL:
- {
- /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */
- int tv_size;
- tv_size = _TIFFSetGetFieldSize(tif->tif_dir.td_customValues[m].info->set_field_type);
- if (tv_size == 8) {
- if (!TIFFWriteDirectoryTagRationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- } else {
- /*-- default should be tv_size == 4 */
- if (!TIFFWriteDirectoryTagRationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */
- if (tv_size != 4) {
- TIFFErrorExt(0,"TIFFLib: _TIFFWriteDirectorySec()", "Rational2Double: .set_field_type in not 4 but %d", tv_size);
- }
- }
- }
- break;
- case TIFF_SRATIONAL:
- {
- /*-- Rational2Double: For Rationals evaluate "set_field_type" to determine internal storage size. */
- int tv_size;
- tv_size = _TIFFSetGetFieldSize(tif->tif_dir.td_customValues[m].info->set_field_type);
- if (tv_size == 8) {
- if (!TIFFWriteDirectoryTagSrationalDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- } else {
- /*-- default should be tv_size == 4 */
- if (!TIFFWriteDirectoryTagSrationalArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- /*-- ToDo: After Testing, this should be removed and tv_size==4 should be set as default. */
- if (tv_size != 4) {
- TIFFErrorExt(0,"TIFFLib: _TIFFWriteDirectorySec()", "Rational2Double: .set_field_type in not 4 but %d", tv_size);
- }
- }
- }
- break;
- case TIFF_FLOAT:
- if (!TIFFWriteDirectoryTagFloatArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- break;
- case TIFF_DOUBLE:
- if (!TIFFWriteDirectoryTagDoubleArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- break;
- case TIFF_IFD:
- if (!TIFFWriteDirectoryTagIfdArray(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- break;
- case TIFF_IFD8:
- if (!TIFFWriteDirectoryTagIfdIfd8Array(tif,&ndir,dir,tag,count,tif->tif_dir.td_customValues[m].value))
- goto bad;
- break;
- default:
- assert(0); /* we should never get here */
- break;
- }
- }
- if (dir!=NULL)
- break;
- dir=_TIFFmalloc(ndir*sizeof(TIFFDirEntry));
- if (dir==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- goto bad;
- }
- if (isimage)
- {
- if ((tif->tif_diroff==0)&&(!TIFFLinkDirectory(tif)))
- goto bad;
- }
- else
- tif->tif_diroff=(TIFFSeekFile(tif,0,SEEK_END)+1)&(~((toff_t)1));
- if (pdiroff!=NULL)
- *pdiroff=tif->tif_diroff;
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- dirsize=2+ndir*12+4;
- else
- dirsize=8+ndir*20+8;
- tif->tif_dataoff=tif->tif_diroff+dirsize;
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- tif->tif_dataoff=(uint32_t)tif->tif_dataoff;
- if ((tif->tif_dataoff<tif->tif_diroff)||(tif->tif_dataoff<(uint64_t)dirsize))
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
- goto bad;
- }
- if (tif->tif_dataoff&1)
- tif->tif_dataoff++;
- if (isimage)
- tif->tif_curdir++;
- }
- if (isimage)
- {
- if (TIFFFieldSet(tif,FIELD_SUBIFD)&&(tif->tif_subifdoff==0))
- {
- uint32_t na;
- TIFFDirEntry* nb;
- for (na=0, nb=dir; ; na++, nb++)
- {
- if( na == ndir )
- {
- TIFFErrorExt(tif->tif_clientdata,module,
- "Cannot find SubIFD tag");
- goto bad;
- }
- if (nb->tdir_tag==TIFFTAG_SUBIFD)
- break;
- }
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- tif->tif_subifdoff=tif->tif_diroff+2+na*12+8;
- else
- tif->tif_subifdoff=tif->tif_diroff+8+na*20+12;
- }
- }
- dirmem=_TIFFmalloc(dirsize);
- if (dirmem==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- goto bad;
- }
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- uint8_t* n;
- uint32_t nTmp;
- TIFFDirEntry* o;
- n=dirmem;
- *(uint16_t*)n=(uint16_t)ndir;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16_t*)n);
- n+=2;
- o=dir;
- for (m=0; m<ndir; m++)
- {
- *(uint16_t*)n=o->tdir_tag;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16_t*)n);
- n+=2;
- *(uint16_t*)n=o->tdir_type;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16_t*)n);
- n+=2;
- nTmp = (uint32_t)o->tdir_count;
- _TIFFmemcpy(n,&nTmp,4);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32_t*)n);
- n+=4;
- /* This is correct. The data has been */
- /* swabbed previously in TIFFWriteDirectoryTagData */
- _TIFFmemcpy(n,&o->tdir_offset,4);
- n+=4;
- o++;
- }
- nTmp = (uint32_t)tif->tif_nextdiroff;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(&nTmp);
- _TIFFmemcpy(n,&nTmp,4);
- }
- else
- {
- uint8_t* n;
- TIFFDirEntry* o;
- n=dirmem;
- *(uint64_t*)n=ndir;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64_t*)n);
- n+=8;
- o=dir;
- for (m=0; m<ndir; m++)
- {
- *(uint16_t*)n=o->tdir_tag;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16_t*)n);
- n+=2;
- *(uint16_t*)n=o->tdir_type;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16_t*)n);
- n+=2;
- _TIFFmemcpy(n,&o->tdir_count,8);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64_t*)n);
- n+=8;
- _TIFFmemcpy(n,&o->tdir_offset,8);
- n+=8;
- o++;
- }
- _TIFFmemcpy(n,&tif->tif_nextdiroff,8);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64_t*)n);
- }
- _TIFFfree(dir);
- dir=NULL;
- if (!SeekOK(tif,tif->tif_diroff))
- {
- TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
- goto bad;
- }
- if (!WriteOK(tif,dirmem,(tmsize_t)dirsize))
- {
- TIFFErrorExt(tif->tif_clientdata,module,"IO error writing directory");
- goto bad;
- }
- _TIFFfree(dirmem);
- if (imagedone)
- {
- TIFFFreeDirectory(tif);
- tif->tif_flags &= ~TIFF_DIRTYDIRECT;
- tif->tif_flags &= ~TIFF_DIRTYSTRIP;
- (*tif->tif_cleanup)(tif);
- /*
- * Reset directory-related state for subsequent
- * directories.
- */
- TIFFCreateDirectory(tif);
- }
- return(1);
- bad:
- if (dir!=NULL)
- _TIFFfree(dir);
- if (dirmem!=NULL)
- _TIFFfree(dirmem);
- return(0);
- }
- static int8_t TIFFClampDoubleToInt8(double val )
- {
- if( val > 127 )
- return 127;
- if( val < -128 || val != val )
- return -128;
- return (int8_t)val;
- }
- static int16_t TIFFClampDoubleToInt16(double val )
- {
- if( val > 32767 )
- return 32767;
- if( val < -32768 || val != val )
- return -32768;
- return (int16_t)val;
- }
- static int32_t TIFFClampDoubleToInt32(double val )
- {
- if( val > 0x7FFFFFFF )
- return 0x7FFFFFFF;
- if( val < -0x7FFFFFFF-1 || val != val )
- return -0x7FFFFFFF-1;
- return (int32_t)val;
- }
- static uint8_t TIFFClampDoubleToUInt8(double val )
- {
- if( val < 0 )
- return 0;
- if( val > 255 || val != val )
- return 255;
- return (uint8_t)val;
- }
- static uint16_t TIFFClampDoubleToUInt16(double val )
- {
- if( val < 0 )
- return 0;
- if( val > 65535 || val != val )
- return 65535;
- return (uint16_t)val;
- }
- static uint32_t TIFFClampDoubleToUInt32(double val )
- {
- if( val < 0 )
- return 0;
- if( val > 0xFFFFFFFFU || val != val )
- return 0xFFFFFFFFU;
- return (uint32_t)val;
- }
- static int
- TIFFWriteDirectoryTagSampleformatArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value)
- {
- static const char module[] = "TIFFWriteDirectoryTagSampleformatArray";
- void* conv;
- uint32_t i;
- int ok;
- conv = _TIFFmalloc(count*sizeof(double));
- if (conv == NULL)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "Out of memory");
- return (0);
- }
- switch (tif->tif_dir.td_sampleformat)
- {
- case SAMPLEFORMAT_IEEEFP:
- if (tif->tif_dir.td_bitspersample<=32)
- {
- for (i = 0; i < count; ++i)
- ((float*)conv)[i] = _TIFFClampDoubleToFloat(value[i]);
- ok = TIFFWriteDirectoryTagFloatArray(tif,ndir,dir,tag,count,(float*)conv);
- }
- else
- {
- ok = TIFFWriteDirectoryTagDoubleArray(tif,ndir,dir,tag,count,value);
- }
- break;
- case SAMPLEFORMAT_INT:
- if (tif->tif_dir.td_bitspersample<=8)
- {
- for (i = 0; i < count; ++i)
- ((int8_t*)conv)[i] = TIFFClampDoubleToInt8(value[i]);
- ok = TIFFWriteDirectoryTagSbyteArray(tif,ndir,dir,tag,count,(int8_t*)conv);
- }
- else if (tif->tif_dir.td_bitspersample<=16)
- {
- for (i = 0; i < count; ++i)
- ((int16_t*)conv)[i] = TIFFClampDoubleToInt16(value[i]);
- ok = TIFFWriteDirectoryTagSshortArray(tif,ndir,dir,tag,count,(int16_t*)conv);
- }
- else
- {
- for (i = 0; i < count; ++i)
- ((int32_t*)conv)[i] = TIFFClampDoubleToInt32(value[i]);
- ok = TIFFWriteDirectoryTagSlongArray(tif,ndir,dir,tag,count,(int32_t*)conv);
- }
- break;
- case SAMPLEFORMAT_UINT:
- if (tif->tif_dir.td_bitspersample<=8)
- {
- for (i = 0; i < count; ++i)
- ((uint8_t*)conv)[i] = TIFFClampDoubleToUInt8(value[i]);
- ok = TIFFWriteDirectoryTagByteArray(tif,ndir,dir,tag,count,(uint8_t*)conv);
- }
- else if (tif->tif_dir.td_bitspersample<=16)
- {
- for (i = 0; i < count; ++i)
- ((uint16_t*)conv)[i] = TIFFClampDoubleToUInt16(value[i]);
- ok = TIFFWriteDirectoryTagShortArray(tif,ndir,dir,tag,count,(uint16_t*)conv);
- }
- else
- {
- for (i = 0; i < count; ++i)
- ((uint32_t*)conv)[i] = TIFFClampDoubleToUInt32(value[i]);
- ok = TIFFWriteDirectoryTagLongArray(tif,ndir,dir,tag,count,(uint32_t*)conv);
- }
- break;
- default:
- ok = 0;
- }
- _TIFFfree(conv);
- return (ok);
- }
- #if 0
- static int
- TIFFWriteDirectoryTagSampleformatPerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value)
- {
- switch (tif->tif_dir.td_sampleformat)
- {
- case SAMPLEFORMAT_IEEEFP:
- if (tif->tif_dir.td_bitspersample<=32)
- return(TIFFWriteDirectoryTagFloatPerSample(tif,ndir,dir,tag,(float)value));
- else
- return(TIFFWriteDirectoryTagDoublePerSample(tif,ndir,dir,tag,value));
- case SAMPLEFORMAT_INT:
- if (tif->tif_dir.td_bitspersample<=8)
- return(TIFFWriteDirectoryTagSbytePerSample(tif,ndir,dir,tag,(int8_t)value));
- else if (tif->tif_dir.td_bitspersample<=16)
- return(TIFFWriteDirectoryTagSshortPerSample(tif,ndir,dir,tag,(int16_t)value));
- else
- return(TIFFWriteDirectoryTagSlongPerSample(tif,ndir,dir,tag,(int32_t)value));
- case SAMPLEFORMAT_UINT:
- if (tif->tif_dir.td_bitspersample<=8)
- return(TIFFWriteDirectoryTagBytePerSample(tif,ndir,dir,tag,(uint8_t)value));
- else if (tif->tif_dir.td_bitspersample<=16)
- return(TIFFWriteDirectoryTagShortPerSample(tif,ndir,dir,tag,(uint16_t)value));
- else
- return(TIFFWriteDirectoryTagLongPerSample(tif,ndir,dir,tag,(uint32_t)value));
- default:
- return(1);
- }
- }
- #endif
- static int
- TIFFWriteDirectoryTagAscii(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, char* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedAscii(tif,ndir,dir,tag,count,value));
- }
- static int
- TIFFWriteDirectoryTagUndefinedArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedUndefinedArray(tif,ndir,dir,tag,count,value));
- }
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagByte(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint8_t value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedByte(tif,ndir,dir,tag,value));
- }
- #endif
- static int
- TIFFWriteDirectoryTagByteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,count,value));
- }
- #if 0
- static int
- TIFFWriteDirectoryTagBytePerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint8_t value)
- {
- static const char module[] = "TIFFWriteDirectoryTagBytePerSample";
- uint8_t* m;
- uint8_t* na;
- uint16_t nb;
- int o;
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint8_t));
- if (m==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
- *na=value;
- o=TIFFWriteDirectoryTagCheckedByteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
- _TIFFfree(m);
- return(o);
- }
- #endif
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagSbyte(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int8_t value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedSbyte(tif,ndir,dir,tag,value));
- }
- #endif
- static int
- TIFFWriteDirectoryTagSbyteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int8_t* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,count,value));
- }
- #if 0
- static int
- TIFFWriteDirectoryTagSbytePerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int8_t value)
- {
- static const char module[] = "TIFFWriteDirectoryTagSbytePerSample";
- int8_t* m;
- int8_t* na;
- uint16_t nb;
- int o;
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int8_t));
- if (m==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
- *na=value;
- o=TIFFWriteDirectoryTagCheckedSbyteArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
- _TIFFfree(m);
- return(o);
- }
- #endif
- static int
- TIFFWriteDirectoryTagShort(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,value));
- }
- static int
- TIFFWriteDirectoryTagShortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint16_t* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,value));
- }
- static int
- TIFFWriteDirectoryTagShortPerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t value)
- {
- static const char module[] = "TIFFWriteDirectoryTagShortPerSample";
- uint16_t* m;
- uint16_t* na;
- uint16_t nb;
- int o;
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint16_t));
- if (m==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
- *na=value;
- o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
- _TIFFfree(m);
- return(o);
- }
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagSshort(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int16_t value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedSshort(tif,ndir,dir,tag,value));
- }
- #endif
- static int
- TIFFWriteDirectoryTagSshortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int16_t* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,count,value));
- }
- #if 0
- static int
- TIFFWriteDirectoryTagSshortPerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int16_t value)
- {
- static const char module[] = "TIFFWriteDirectoryTagSshortPerSample";
- int16_t* m;
- int16_t* na;
- uint16_t nb;
- int o;
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int16_t));
- if (m==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
- *na=value;
- o=TIFFWriteDirectoryTagCheckedSshortArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
- _TIFFfree(m);
- return(o);
- }
- #endif
- static int
- TIFFWriteDirectoryTagLong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
- }
- static int
- TIFFWriteDirectoryTagLongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,value));
- }
- #if 0
- static int
- TIFFWriteDirectoryTagLongPerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t value)
- {
- static const char module[] = "TIFFWriteDirectoryTagLongPerSample";
- uint32_t* m;
- uint32_t* na;
- uint16_t nb;
- int o;
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(uint32_t));
- if (m==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
- *na=value;
- o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
- _TIFFfree(m);
- return(o);
- }
- #endif
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagSlong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int32_t value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedSlong(tif,ndir,dir,tag,value));
- }
- #endif
- static int
- TIFFWriteDirectoryTagSlongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int32_t* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,count,value));
- }
- #if 0
- static int
- TIFFWriteDirectoryTagSlongPerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int32_t value)
- {
- static const char module[] = "TIFFWriteDirectoryTagSlongPerSample";
- int32_t* m;
- int32_t* na;
- uint16_t nb;
- int o;
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(int32_t));
- if (m==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
- *na=value;
- o=TIFFWriteDirectoryTagCheckedSlongArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
- _TIFFfree(m);
- return(o);
- }
- #endif
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagLong8(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint64_t value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedLong8(tif,ndir,dir,tag,value));
- }
- #endif
- static int
- TIFFWriteDirectoryTagLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value));
- }
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagSlong8(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int64_t value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedSlong8(tif,ndir,dir,tag,value));
- }
- #endif
- static int
- TIFFWriteDirectoryTagSlong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int64_t* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedSlong8Array(tif,ndir,dir,tag,count,value));
- }
- static int
- TIFFWriteDirectoryTagRational(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedRational(tif,ndir,dir,tag,value));
- }
- static int
- TIFFWriteDirectoryTagRationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedRationalArray(tif,ndir,dir,tag,count,value));
- }
- static int
- TIFFWriteDirectoryTagSrationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedSrationalArray(tif,ndir,dir,tag,count,value));
- }
- /*-- Rational2Double: additional write functions */
- static int
- TIFFWriteDirectoryTagRationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedRationalDoubleArray(tif,ndir,dir,tag,count,value));
- }
- static int
- TIFFWriteDirectoryTagSrationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedSrationalDoubleArray(tif,ndir,dir,tag,count,value));
- }
- #ifdef notdef
- static int TIFFWriteDirectoryTagFloat(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, float value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedFloat(tif,ndir,dir,tag,value));
- }
- #endif
- static int TIFFWriteDirectoryTagFloatArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,count,value));
- }
- #if 0
- static int TIFFWriteDirectoryTagFloatPerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, float value)
- {
- static const char module[] = "TIFFWriteDirectoryTagFloatPerSample";
- float* m;
- float* na;
- uint16_t nb;
- int o;
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(float));
- if (m==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
- *na=value;
- o=TIFFWriteDirectoryTagCheckedFloatArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
- _TIFFfree(m);
- return(o);
- }
- #endif
- #ifdef notdef
- static int TIFFWriteDirectoryTagDouble(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedDouble(tif,ndir,dir,tag,value));
- }
- #endif
- static int TIFFWriteDirectoryTagDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,count,value));
- }
- #if 0
- static int TIFFWriteDirectoryTagDoublePerSample(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value)
- {
- static const char module[] = "TIFFWriteDirectoryTagDoublePerSample";
- double* m;
- double* na;
- uint16_t nb;
- int o;
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- m=_TIFFmalloc(tif->tif_dir.td_samplesperpixel*sizeof(double));
- if (m==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (na=m, nb=0; nb<tif->tif_dir.td_samplesperpixel; na++, nb++)
- *na=value;
- o=TIFFWriteDirectoryTagCheckedDoubleArray(tif,ndir,dir,tag,tif->tif_dir.td_samplesperpixel,m);
- _TIFFfree(m);
- return(o);
- }
- #endif
- static int
- TIFFWriteDirectoryTagIfdArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,value));
- }
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagIfd8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- return(TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,tag,count,value));
- }
- #endif
- static int
- TIFFWriteDirectoryTagShortLong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t value)
- {
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- if (value<=0xFFFF)
- return(TIFFWriteDirectoryTagCheckedShort(tif,ndir,dir,tag,(uint16_t)value));
- else
- return(TIFFWriteDirectoryTagCheckedLong(tif,ndir,dir,tag,value));
- }
- static int _WriteAsType(TIFF* tif, uint64_t strile_size, uint64_t uncompressed_threshold)
- {
- const uint16_t compression = tif->tif_dir.td_compression;
- if ( compression == COMPRESSION_NONE )
- {
- return strile_size > uncompressed_threshold;
- }
- else if ( compression == COMPRESSION_JPEG ||
- compression == COMPRESSION_LZW ||
- compression == COMPRESSION_ADOBE_DEFLATE ||
- compression == COMPRESSION_LZMA ||
- compression == COMPRESSION_LERC ||
- compression == COMPRESSION_ZSTD ||
- compression == COMPRESSION_WEBP )
- {
- /* For a few select compression types, we assume that in the worst */
- /* case the compressed size will be 10 times the uncompressed size */
- /* This is overly pessismistic ! */
- return strile_size >= uncompressed_threshold / 10;
- }
- return 1;
- }
- static int WriteAsLong8(TIFF* tif, uint64_t strile_size)
- {
- return _WriteAsType(tif, strile_size, 0xFFFFFFFFU);
- }
- static int WriteAsLong4(TIFF* tif, uint64_t strile_size)
- {
- return _WriteAsType(tif, strile_size, 0xFFFFU);
- }
- /************************************************************************/
- /* TIFFWriteDirectoryTagLongLong8Array() */
- /* */
- /* Write out LONG8 array and write a SHORT/LONG/LONG8 depending */
- /* on strile size and Classic/BigTIFF mode. */
- /************************************************************************/
- static int
- TIFFWriteDirectoryTagLongLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value)
- {
- static const char module[] = "TIFFWriteDirectoryTagLongLong8Array";
- int o;
- int write_aslong4;
- /* is this just a counting pass? */
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- if( tif->tif_dir.td_deferstrilearraywriting )
- {
- return TIFFWriteDirectoryTagData(tif, ndir, dir, tag, TIFF_NOTYPE, 0, 0, NULL);
- }
- if( tif->tif_flags&TIFF_BIGTIFF )
- {
- int write_aslong8 = 1;
- /* In the case of ByteCounts array, we may be able to write them on */
- /* LONG if the strip/tilesize is not too big. */
- /* Also do that for count > 1 in the case someone would want to create */
- /* a single-strip file with a growing height, in which case using */
- /* LONG8 will be safer. */
- if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS )
- {
- write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
- }
- else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS )
- {
- write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
- }
- if( write_aslong8 )
- {
- return TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,
- tag,count,value);
- }
- }
- write_aslong4 = 1;
- if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS )
- {
- write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
- }
- else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS )
- {
- write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
- }
- if( write_aslong4 )
- {
- /*
- ** For classic tiff we want to verify everything is in range for LONG
- ** and convert to long format.
- */
- uint32_t* p = _TIFFmalloc(count * sizeof(uint32_t));
- uint32_t* q;
- uint64_t* ma;
- uint32_t mb;
- if (p==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
- {
- if (*ma>0xFFFFFFFF)
- {
- TIFFErrorExt(tif->tif_clientdata,module,
- "Attempt to write value larger than 0xFFFFFFFF in LONG array.");
- _TIFFfree(p);
- return(0);
- }
- *q= (uint32_t)(*ma);
- }
- o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
- _TIFFfree(p);
- }
- else
- {
- uint16_t* p = _TIFFmalloc(count * sizeof(uint16_t));
- uint16_t* q;
- uint64_t* ma;
- uint32_t mb;
- if (p==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
- {
- if (*ma>0xFFFF)
- {
- /* Should not happen normally given the check we did before */
- TIFFErrorExt(tif->tif_clientdata,module,
- "Attempt to write value larger than 0xFFFF in SHORT array.");
- _TIFFfree(p);
- return(0);
- }
- *q= (uint16_t)(*ma);
- }
- o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,p);
- _TIFFfree(p);
- }
- return(o);
- }
- /************************************************************************/
- /* TIFFWriteDirectoryTagIfdIfd8Array() */
- /* */
- /* Write either IFD8 or IFD array depending on file type. */
- /************************************************************************/
- static int
- TIFFWriteDirectoryTagIfdIfd8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value)
- {
- static const char module[] = "TIFFWriteDirectoryTagIfdIfd8Array";
- uint64_t* ma;
- uint32_t mb;
- uint32_t* p;
- uint32_t* q;
- int o;
- /* is this just a counting pass? */
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- /* We always write IFD8 for BigTIFF, no checking needed. */
- if( tif->tif_flags&TIFF_BIGTIFF )
- return TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,
- tag,count,value);
- /*
- ** For classic tiff we want to verify everything is in range for IFD
- ** and convert to long format.
- */
- p = _TIFFmalloc(count*sizeof(uint32_t));
- if (p==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (q=p, ma=value, mb=0; mb<count; ma++, mb++, q++)
- {
- if (*ma>0xFFFFFFFF)
- {
- TIFFErrorExt(tif->tif_clientdata,module,
- "Attempt to write value larger than 0xFFFFFFFF in Classic TIFF file.");
- _TIFFfree(p);
- return(0);
- }
- *q= (uint32_t)(*ma);
- }
- o=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,tag,count,p);
- _TIFFfree(p);
- return(o);
- }
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagShortLongLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value)
- {
- static const char module[] = "TIFFWriteDirectoryTagShortLongLong8Array";
- uint64_t* ma;
- uint32_t mb;
- uint8_t n;
- int o;
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- n=0;
- for (ma=value, mb=0; mb<count; ma++, mb++)
- {
- if ((n==0)&&(*ma>0xFFFF))
- n=1;
- if ((n==1)&&(*ma>0xFFFFFFFF))
- {
- n=2;
- break;
- }
- }
- if (n==0)
- {
- uint16_t* p;
- uint16_t* q;
- p=_TIFFmalloc(count*sizeof(uint16_t));
- if (p==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
- *q=(uint16_t)(*ma);
- o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,tag,count,p);
- _TIFFfree(p);
- }
- else if (n==1)
- {
- uint32_t* p;
- uint32_t* q;
- p=_TIFFmalloc(count*sizeof(uint32_t));
- if (p==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (ma=value, mb=0, q=p; mb<count; ma++, mb++, q++)
- *q=(uint32_t)(*ma);
- o=TIFFWriteDirectoryTagCheckedLongArray(tif,ndir,dir,tag,count,p);
- _TIFFfree(p);
- }
- else
- {
- assert(n==2);
- o=TIFFWriteDirectoryTagCheckedLong8Array(tif,ndir,dir,tag,count,value);
- }
- return(o);
- }
- #endif
- static int
- TIFFWriteDirectoryTagColormap(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir)
- {
- static const char module[] = "TIFFWriteDirectoryTagColormap";
- uint32_t m;
- uint16_t* n;
- int o;
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- m=(1<<tif->tif_dir.td_bitspersample);
- n=_TIFFmalloc(3*m*sizeof(uint16_t));
- if (n==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- _TIFFmemcpy(&n[0],tif->tif_dir.td_colormap[0],m*sizeof(uint16_t));
- _TIFFmemcpy(&n[m],tif->tif_dir.td_colormap[1],m*sizeof(uint16_t));
- _TIFFmemcpy(&n[2*m],tif->tif_dir.td_colormap[2],m*sizeof(uint16_t));
- o=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_COLORMAP,3*m,n);
- _TIFFfree(n);
- return(o);
- }
- static int
- TIFFWriteDirectoryTagTransferfunction(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir)
- {
- static const char module[] = "TIFFWriteDirectoryTagTransferfunction";
- uint32_t m;
- uint16_t n;
- uint16_t* o;
- int p;
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- m=(1<<tif->tif_dir.td_bitspersample);
- n=tif->tif_dir.td_samplesperpixel-tif->tif_dir.td_extrasamples;
- /*
- * Check if the table can be written as a single column,
- * or if it must be written as 3 columns. Note that we
- * write a 3-column tag if there are 2 samples/pixel and
- * a single column of data won't suffice--hmm.
- */
- if (n>3)
- n=3;
- if (n==3)
- {
- if (tif->tif_dir.td_transferfunction[2] == NULL ||
- !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16_t)))
- n=2;
- }
- if (n==2)
- {
- if (tif->tif_dir.td_transferfunction[1] == NULL ||
- !_TIFFmemcmp(tif->tif_dir.td_transferfunction[0],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16_t)))
- n=1;
- }
- if (n==0)
- n=1;
- o=_TIFFmalloc(n*m*sizeof(uint16_t));
- if (o==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- _TIFFmemcpy(&o[0],tif->tif_dir.td_transferfunction[0],m*sizeof(uint16_t));
- if (n>1)
- _TIFFmemcpy(&o[m],tif->tif_dir.td_transferfunction[1],m*sizeof(uint16_t));
- if (n>2)
- _TIFFmemcpy(&o[2*m],tif->tif_dir.td_transferfunction[2],m*sizeof(uint16_t));
- p=TIFFWriteDirectoryTagCheckedShortArray(tif,ndir,dir,TIFFTAG_TRANSFERFUNCTION,n*m,o);
- _TIFFfree(o);
- return(p);
- }
- static int
- TIFFWriteDirectoryTagSubifd(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir)
- {
- static const char module[] = "TIFFWriteDirectoryTagSubifd";
- uint64_t m;
- int n;
- if (tif->tif_dir.td_nsubifd==0)
- return(1);
- if (dir==NULL)
- {
- (*ndir)++;
- return(1);
- }
- m=tif->tif_dataoff;
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- uint32_t* o;
- uint64_t* pa;
- uint32_t* pb;
- uint16_t p;
- o=_TIFFmalloc(tif->tif_dir.td_nsubifd*sizeof(uint32_t));
- if (o==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- pa=tif->tif_dir.td_subifd;
- pb=o;
- for (p=0; p < tif->tif_dir.td_nsubifd; p++)
- {
- assert(pa != 0);
- /* Could happen if an classicTIFF has a SubIFD of type LONG8 (which is illegal) */
- if( *pa > 0xFFFFFFFFUL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Illegal value for SubIFD tag");
- _TIFFfree(o);
- return(0);
- }
- *pb++=(uint32_t)(*pa++);
- }
- n=TIFFWriteDirectoryTagCheckedIfdArray(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,o);
- _TIFFfree(o);
- }
- else
- n=TIFFWriteDirectoryTagCheckedIfd8Array(tif,ndir,dir,TIFFTAG_SUBIFD,tif->tif_dir.td_nsubifd,tif->tif_dir.td_subifd);
- if (!n)
- return(0);
- /*
- * Total hack: if this directory includes a SubIFD
- * tag then force the next <n> directories to be
- * written as ``sub directories'' of this one. This
- * is used to write things like thumbnails and
- * image masks that one wants to keep out of the
- * normal directory linkage access mechanism.
- */
- tif->tif_flags|=TIFF_INSUBIFD;
- tif->tif_nsubifd=tif->tif_dir.td_nsubifd;
- if (tif->tif_dir.td_nsubifd==1)
- tif->tif_subifdoff=0;
- else
- tif->tif_subifdoff=m;
- return(1);
- }
- static int
- TIFFWriteDirectoryTagCheckedAscii(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, char* value)
- {
- assert(sizeof(char)==1);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_ASCII,count,count,value));
- }
- static int
- TIFFWriteDirectoryTagCheckedUndefinedArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value)
- {
- assert(sizeof(uint8_t) == 1);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_UNDEFINED,count,count,value));
- }
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagCheckedByte(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint8_t value)
- {
- assert(sizeof(uint8_t)==1);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,1,1,&value));
- }
- #endif
- static int
- TIFFWriteDirectoryTagCheckedByteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint8_t* value)
- {
- assert(sizeof(uint8_t) == 1);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_BYTE,count,count,value));
- }
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagCheckedSbyte(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int8_t value)
- {
- assert(sizeof(int8_t)==1);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,1,1,&value));
- }
- #endif
- static int
- TIFFWriteDirectoryTagCheckedSbyteArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int8_t* value)
- {
- assert(sizeof(int8_t) == 1);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SBYTE,count,count,value));
- }
- static int
- TIFFWriteDirectoryTagCheckedShort(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t value)
- {
- uint16_t m;
- assert(sizeof(uint16_t) == 2);
- m=value;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort(&m);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,1,2,&m));
- }
- static int
- TIFFWriteDirectoryTagCheckedShortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint16_t* value)
- {
- assert(count<0x80000000);
- assert(sizeof(uint16_t) == 2);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfShort(value,count);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SHORT,count,count*2,value));
- }
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagCheckedSshort(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int16_t value)
- {
- int16_t m;
- assert(sizeof(int16_t)==2);
- m=value;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort((uint16_t*)(&m));
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,1,2,&m));
- }
- #endif
- static int
- TIFFWriteDirectoryTagCheckedSshortArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int16_t* value)
- {
- assert(count<0x80000000);
- assert(sizeof(int16_t) == 2);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfShort((uint16_t*)value, count);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SSHORT,count,count*2,value));
- }
- static int
- TIFFWriteDirectoryTagCheckedLong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t value)
- {
- uint32_t m;
- assert(sizeof(uint32_t) == 4);
- m=value;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(&m);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,1,4,&m));
- }
- static int
- TIFFWriteDirectoryTagCheckedLongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value)
- {
- assert(count<0x40000000);
- assert(sizeof(uint32_t) == 4);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong(value,count);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG,count,count*4,value));
- }
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagCheckedSlong(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int32_t value)
- {
- int32_t m;
- assert(sizeof(int32_t)==4);
- m=value;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong((uint32_t*)(&m));
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,1,4,&m));
- }
- #endif
- static int
- TIFFWriteDirectoryTagCheckedSlongArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int32_t* value)
- {
- assert(count<0x40000000);
- assert(sizeof(int32_t) == 4);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong((uint32_t*)value, count);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG,count,count*4,value));
- }
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagCheckedLong8(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint64_t value)
- {
- uint64_t m;
- assert(sizeof(uint64_t)==8);
- if( !(tif->tif_flags&TIFF_BIGTIFF) ) {
- TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedLong8","LONG8 not allowed for ClassicTIFF");
- return(0);
- }
- m=value;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(&m);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,1,8,&m));
- }
- #endif
- static int
- TIFFWriteDirectoryTagCheckedLong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value)
- {
- assert(count<0x20000000);
- assert(sizeof(uint64_t) == 8);
- if( !(tif->tif_flags&TIFF_BIGTIFF) ) {
- TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedLong8Array","LONG8 not allowed for ClassicTIFF");
- return(0);
- }
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong8(value,count);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_LONG8,count,count*8,value));
- }
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagCheckedSlong8(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, int64_t value)
- {
- int64_t m;
- assert(sizeof(int64_t)==8);
- if( !(tif->tif_flags&TIFF_BIGTIFF) ) {
- TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedSlong8","SLONG8 not allowed for ClassicTIFF");
- return(0);
- }
- m=value;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8((uint64_t*)(&m));
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,1,8,&m));
- }
- #endif
- static int
- TIFFWriteDirectoryTagCheckedSlong8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, int64_t* value)
- {
- assert(count<0x20000000);
- assert(sizeof(int64_t) == 8);
- if( !(tif->tif_flags&TIFF_BIGTIFF) ) {
- TIFFErrorExt(tif->tif_clientdata,"TIFFWriteDirectoryTagCheckedSlong8Array","SLONG8 not allowed for ClassicTIFF");
- return(0);
- }
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong8((uint64_t*)value, count);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SLONG8,count,count*8,value));
- }
- static int
- TIFFWriteDirectoryTagCheckedRational(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value)
- {
- static const char module[] = "TIFFWriteDirectoryTagCheckedRational";
- uint32_t m[2];
- assert(sizeof(uint32_t) == 4);
- if (value < 0)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "Negative value is illegal");
- return 0;
- }
- else if (value != value)
- {
- TIFFErrorExt(tif->tif_clientdata, module, "Not-a-number value is illegal");
- return 0;
- }
- #ifdef not_def
- else if (value==0.0)
- {
- m[0]=0;
- m[1]=1;
- }
- else if (value <= 0xFFFFFFFFU && value==(double)(uint32_t)value)
- {
- m[0]=(uint32_t)value;
- m[1]=1;
- }
- else if (value<1.0)
- {
- m[0]=(uint32_t)(value*0xFFFFFFFF);
- m[1]=0xFFFFFFFF;
- }
- else
- {
- m[0]=0xFFFFFFFF;
- m[1]=(uint32_t)(0xFFFFFFFF/value);
- }
- #else
- /*--Rational2Double: New function also used for non-custom rational tags.
- * However, could be omitted here, because TIFFWriteDirectoryTagCheckedRational() is not used by code for custom tags,
- * only by code for named-tiff-tags like FIELD_RESOLUTION and FIELD_POSITION */
- else {
- DoubleToRational(value, &m[0], &m[1]);
- }
- #endif
- if (tif->tif_flags&TIFF_SWAB)
- {
- TIFFSwabLong(&m[0]);
- TIFFSwabLong(&m[1]);
- }
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,1,8,&m[0]));
- }
- static int
- TIFFWriteDirectoryTagCheckedRationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value)
- {
- static const char module[] = "TIFFWriteDirectoryTagCheckedRationalArray";
- uint32_t* m;
- float* na;
- uint32_t* nb;
- uint32_t nc;
- int o;
- assert(sizeof(uint32_t) == 4);
- m=_TIFFmalloc(count*2*sizeof(uint32_t));
- if (m==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
- {
- #ifdef not_def
- if (*na<=0.0 || *na != *na)
- {
- nb[0]=0;
- nb[1]=1;
- }
- else if (*na >= 0 && *na <= (float)0xFFFFFFFFU &&
- *na==(float)(uint32_t)(*na))
- {
- nb[0]=(uint32_t)(*na);
- nb[1]=1;
- }
- else if (*na<1.0)
- {
- nb[0]=(uint32_t)((double)(*na)*0xFFFFFFFF);
- nb[1]=0xFFFFFFFF;
- }
- else
- {
- nb[0]=0xFFFFFFFF;
- nb[1]=(uint32_t)((double)0xFFFFFFFF/(*na));
- }
- #else
- /*-- Rational2Double: Also for float precision accuracy is sometimes enhanced --*/
- DoubleToRational(*na, &nb[0], &nb[1]);
- #endif
- }
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong(m,count*2);
- o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]);
- _TIFFfree(m);
- return(o);
- }
- static int
- TIFFWriteDirectoryTagCheckedSrationalArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value)
- {
- static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalArray";
- int32_t* m;
- float* na;
- int32_t* nb;
- uint32_t nc;
- int o;
- assert(sizeof(int32_t) == 4);
- m=_TIFFmalloc(count*2*sizeof(int32_t));
- if (m==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
- {
- #ifdef not_def
- if (*na<0.0)
- {
- if (*na==(int32_t)(*na))
- {
- nb[0]=(int32_t)(*na);
- nb[1]=1;
- }
- else if (*na>-1.0)
- {
- nb[0]=-(int32_t)((double)(-*na)*0x7FFFFFFF);
- nb[1]=0x7FFFFFFF;
- }
- else
- {
- nb[0]=-0x7FFFFFFF;
- nb[1]=(int32_t)((double)0x7FFFFFFF/(-*na));
- }
- }
- else
- {
- if (*na==(int32_t)(*na))
- {
- nb[0]=(int32_t)(*na);
- nb[1]=1;
- }
- else if (*na<1.0)
- {
- nb[0]=(int32_t)((double)(*na)*0x7FFFFFFF);
- nb[1]=0x7FFFFFFF;
- }
- else
- {
- nb[0]=0x7FFFFFFF;
- nb[1]=(int32_t)((double)0x7FFFFFFF/(*na));
- }
- }
- #else
- /*-- Rational2Double: Also for float precision accuracy is sometimes enhanced --*/
- DoubleToSrational(*na, &nb[0], &nb[1]);
- #endif
- }
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong((uint32_t*)m, count * 2);
- o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]);
- _TIFFfree(m);
- return(o);
- }
- /*-- Rational2Double: additional write functions for double arrays */
- static int
- TIFFWriteDirectoryTagCheckedRationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value)
- {
- static const char module[] = "TIFFWriteDirectoryTagCheckedRationalDoubleArray";
- uint32_t* m;
- double* na;
- uint32_t* nb;
- uint32_t nc;
- int o;
- assert(sizeof(uint32_t) == 4);
- m=_TIFFmalloc(count*2*sizeof(uint32_t));
- if (m==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
- {
- DoubleToRational(*na, &nb[0], &nb[1]);
- }
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong(m,count*2);
- o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_RATIONAL,count,count*8,&m[0]);
- _TIFFfree(m);
- return(o);
- } /*-- TIFFWriteDirectoryTagCheckedRationalDoubleArray() ------- */
- static int
- TIFFWriteDirectoryTagCheckedSrationalDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value)
- {
- static const char module[] = "TIFFWriteDirectoryTagCheckedSrationalDoubleArray";
- int32_t* m;
- double* na;
- int32_t* nb;
- uint32_t nc;
- int o;
- assert(sizeof(int32_t) == 4);
- m=_TIFFmalloc(count*2*sizeof(int32_t));
- if (m==NULL)
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Out of memory");
- return(0);
- }
- for (na=value, nb=m, nc=0; nc<count; na++, nb+=2, nc++)
- {
- DoubleToSrational(*na, &nb[0], &nb[1]);
- }
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong((uint32_t*)m, count * 2);
- o=TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_SRATIONAL,count,count*8,&m[0]);
- _TIFFfree(m);
- return(o);
- } /*--- TIFFWriteDirectoryTagCheckedSrationalDoubleArray() -------- */
- #if 0
- static
- void DoubleToRational_direct(double value, unsigned long *num, unsigned long *denom)
- {
- /*--- OLD Code for debugging and comparison ---- */
- /* code merged from TIFFWriteDirectoryTagCheckedRationalArray() and TIFFWriteDirectoryTagCheckedRational() */
- /* First check for zero and also check for negative numbers (which are illegal for RATIONAL)
- * and also check for "not-a-number". In each case just set this to zero to support also rational-arrays.
- */
- if (value<=0.0 || value != value)
- {
- *num=0;
- *denom=1;
- }
- else if (value <= 0xFFFFFFFFU && (value==(double)(uint32_t)(value))) /* check for integer values */
- {
- *num=(uint32_t)(value);
- *denom=1;
- }
- else if (value<1.0)
- {
- *num = (uint32_t)((value) * (double)0xFFFFFFFFU);
- *denom=0xFFFFFFFFU;
- }
- else
- {
- *num=0xFFFFFFFFU;
- *denom=(uint32_t)((double)0xFFFFFFFFU/(value));
- }
- } /*-- DoubleToRational_direct() -------------- */
- #endif
- #if 0
- static
- void DoubleToSrational_direct(double value, long *num, long *denom)
- {
- /*--- OLD Code for debugging and comparison -- SIGNED-version ----*/
- /* code was amended from original TIFFWriteDirectoryTagCheckedSrationalArray() */
- /* First check for zero and also check for negative numbers (which are illegal for RATIONAL)
- * and also check for "not-a-number". In each case just set this to zero to support also rational-arrays.
- */
- if (value<0.0)
- {
- if (value==(int32_t)(value))
- {
- *num=(int32_t)(value);
- *denom=1;
- }
- else if (value>-1.0)
- {
- *num=-(int32_t)((-value) * (double)0x7FFFFFFF);
- *denom=0x7FFFFFFF;
- }
- else
- {
- *num=-0x7FFFFFFF;
- *denom=(int32_t)((double)0x7FFFFFFF / (-value));
- }
- }
- else
- {
- if (value==(int32_t)(value))
- {
- *num=(int32_t)(value);
- *denom=1;
- }
- else if (value<1.0)
- {
- *num=(int32_t)((value) *(double)0x7FFFFFFF);
- *denom=0x7FFFFFFF;
- }
- else
- {
- *num=0x7FFFFFFF;
- *denom=(int32_t)((double)0x7FFFFFFF / (value));
- }
- }
- } /*-- DoubleToSrational_direct() --------------*/
- #endif
- //#define DOUBLE2RAT_DEBUGOUTPUT
- /** ----- Rational2Double: Double To Rational Conversion ----------------------------------------------------------
- * There is a mathematical theorem to convert real numbers into a rational (integer fraction) number.
- * This is called "continuous fraction" which uses the Euclidean algorithm to find the greatest common divisor (GCD).
- * (ref. e.g. https://de.wikipedia.org/wiki/Kettenbruch or https://en.wikipedia.org/wiki/Continued_fraction
- * https://en.wikipedia.org/wiki/Euclidean_algorithm)
- * The following functions implement the
- * - ToRationalEuclideanGCD() auxiliary function which mainly implements euclidean GCD
- * - DoubleToRational() conversion function for un-signed rationals
- * - DoubleToSrational() conversion function for signed rationals
- ------------------------------------------------------------------------------------------------------------------*/
- /**---- ToRationalEuclideanGCD() -----------------------------------------
- * Calculates the rational fractional of a double input value
- * using the Euclidean algorithm to find the greatest common divisor (GCD)
- ------------------------------------------------------------------------*/
- static
- void ToRationalEuclideanGCD(double value, int blnUseSignedRange, int blnUseSmallRange, uint64_t *ullNum, uint64_t *ullDenom)
- {
- /* Internally, the integer variables can be bigger than the external ones,
- * as long as the result will fit into the external variable size.
- */
- uint64_t numSum[3] = { 0, 1, 0 }, denomSum[3] = { 1, 0, 0 };
- uint64_t aux, bigNum, bigDenom;
- uint64_t returnLimit;
- int i;
- uint64_t nMax;
- double fMax;
- unsigned long maxDenom;
- /*-- nMax and fMax defines the initial accuracy of the starting fractional,
- * or better, the highest used integer numbers used within the starting fractional (bigNum/bigDenom).
- * There are two approaches, which can accidentally lead to different accuracies just depending on the value.
- * Therefore, blnUseSmallRange steers this behavior.
- * For long long nMax = ((9223372036854775807-1)/2); for long nMax = ((2147483647-1)/2);
- */
- if (blnUseSmallRange) {
- nMax = (uint64_t)((2147483647 - 1) / 2); /* for ULONG range */
- }
- else {
- nMax = ((9223372036854775807 - 1) / 2); /* for ULLONG range */
- }
- fMax = (double)nMax;
- /*-- For the Euclidean GCD define the denominator range, so that it stays within size of unsigned long variables.
- * maxDenom should be LONG_MAX for negative values and ULONG_MAX for positive ones.
- * Also the final returned value of ullNum and ullDenom is limited according to signed- or unsigned-range.
- */
- if (blnUseSignedRange) {
- maxDenom = 2147483647UL; /*LONG_MAX = 0x7FFFFFFFUL*/
- returnLimit = maxDenom;
- }
- else {
- maxDenom = 0xFFFFFFFFUL; /*ULONG_MAX = 0xFFFFFFFFUL*/
- returnLimit = maxDenom;
- }
- /*-- First generate a rational fraction (bigNum/bigDenom) which represents the value
- * as a rational number with the highest accuracy. Therefore, uint64_t (uint64_t) is needed.
- * This rational fraction is then reduced using the Euclidean algorithm to find the greatest common divisor (GCD).
- * bigNum = big numinator of value without fraction (or cut residual fraction)
- * bigDenom = big denominator of value
- *-- Break-criteria so that uint64_t cast to "bigNum" introduces no error and bigDenom has no overflow,
- * and stop with enlargement of fraction when the double-value of it reaches an integer number without fractional part.
- */
- bigDenom = 1;
- while ((value != floor(value)) && (value < fMax) && (bigDenom < nMax)) {
- bigDenom <<= 1;
- value *= 2;
- }
- bigNum = (uint64_t)value;
- /*-- Start Euclidean algorithm to find the greatest common divisor (GCD) -- */
- #define MAX_ITERATIONS 64
- for (i = 0; i < MAX_ITERATIONS; i++) {
- uint64_t val;
- /* if bigDenom is not zero, calculate integer part of fraction. */
- if (bigDenom == 0) {
- break;
- }
- val = bigNum / bigDenom;
- /* Set bigDenom to reminder of bigNum/bigDenom and bigNum to previous denominator bigDenom. */
- aux = bigNum;
- bigNum = bigDenom;
- bigDenom = aux % bigDenom;
- /* calculate next denominator and check for its given maximum */
- aux = val;
- if (denomSum[1] * val + denomSum[0] >= maxDenom) {
- aux = (maxDenom - denomSum[0]) / denomSum[1];
- if (aux * 2 >= val || denomSum[1] >= maxDenom)
- i = (MAX_ITERATIONS + 1); /* exit but execute rest of for-loop */
- else
- break;
- }
- /* calculate next numerator to numSum2 and save previous one to numSum0; numSum1 just copy of numSum2. */
- numSum[2] = aux * numSum[1] + numSum[0];
- numSum[0] = numSum[1];
- numSum[1] = numSum[2];
- /* calculate next denominator to denomSum2 and save previous one to denomSum0; denomSum1 just copy of denomSum2. */
- denomSum[2] = aux * denomSum[1] + denomSum[0];
- denomSum[0] = denomSum[1];
- denomSum[1] = denomSum[2];
- }
- /*-- Check and adapt for final variable size and return values; reduces internal accuracy; denominator is kept in ULONG-range with maxDenom -- */
- while (numSum[1] > returnLimit || denomSum[1] > returnLimit) {
- numSum[1] = numSum[1] / 2;
- denomSum[1] = denomSum[1] / 2;
- }
- /* return values */
- *ullNum = numSum[1];
- *ullDenom = denomSum[1];
- } /*-- ToRationalEuclideanGCD() -------------- */
- /**---- DoubleToRational() -----------------------------------------------
- * Calculates the rational fractional of a double input value
- * for UN-SIGNED rationals,
- * using the Euclidean algorithm to find the greatest common divisor (GCD)
- ------------------------------------------------------------------------*/
- static
- void DoubleToRational(double value, uint32_t *num, uint32_t *denom)
- {
- /*---- UN-SIGNED RATIONAL ---- */
- double dblDiff, dblDiff2;
- uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
- /*-- Check for negative values. If so it is an error. */
- /* Test written that way to catch NaN */
- if (!(value >= 0)) {
- *num = *denom = 0;
- TIFFErrorExt(0, "TIFFLib: DoubleToRational()", " Negative Value for Unsigned Rational given.");
- return;
- }
- /*-- Check for too big numbers (> ULONG_MAX) -- */
- if (value > 0xFFFFFFFFUL) {
- *num = 0xFFFFFFFFU;
- *denom = 0;
- return;
- }
- /*-- Check for easy integer numbers -- */
- if (value == (uint32_t)(value)) {
- *num = (uint32_t)value;
- *denom = 1;
- return;
- }
- /*-- Check for too small numbers for "unsigned long" type rationals -- */
- if (value < 1.0 / (double)0xFFFFFFFFUL) {
- *num = 0;
- *denom = 0xFFFFFFFFU;
- return;
- }
- /*-- There are two approaches using the Euclidean algorithm,
- * which can accidentally lead to different accuracies just depending on the value.
- * Try both and define which one was better.
- */
- ToRationalEuclideanGCD(value, FALSE, FALSE, &ullNum, &ullDenom);
- ToRationalEuclideanGCD(value, FALSE, TRUE, &ullNum2, &ullDenom2);
- /*-- Double-Check, that returned values fit into ULONG :*/
- if (ullNum > 0xFFFFFFFFUL || ullDenom > 0xFFFFFFFFUL || ullNum2 > 0xFFFFFFFFUL || ullDenom2 > 0xFFFFFFFFUL) {
- TIFFErrorExt(0, "TIFFLib: DoubleToRational()", " Num or Denom exceeds ULONG: val=%14.6f, num=%12"PRIu64", denom=%12"PRIu64" | num2=%12"PRIu64", denom2=%12"PRIu64"", value, ullNum, ullDenom, ullNum2, ullDenom2);
- assert(0);
- }
- /* Check, which one has higher accuracy and take that. */
- dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
- dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
- if (dblDiff < dblDiff2) {
- *num = (uint32_t)ullNum;
- *denom = (uint32_t)ullDenom;
- }
- else {
- *num = (uint32_t)ullNum2;
- *denom = (uint32_t)ullDenom2;
- }
- } /*-- DoubleToRational() -------------- */
- /**---- DoubleToSrational() -----------------------------------------------
- * Calculates the rational fractional of a double input value
- * for SIGNED rationals,
- * using the Euclidean algorithm to find the greatest common divisor (GCD)
- ------------------------------------------------------------------------*/
- static
- void DoubleToSrational(double value, int32_t *num, int32_t *denom)
- {
- /*---- SIGNED RATIONAL ----*/
- int neg = 1;
- double dblDiff, dblDiff2;
- uint64_t ullNum, ullDenom, ullNum2, ullDenom2;
- /*-- Check for negative values and use then the positive one for internal calculations, but take the sign into account before returning. */
- if (value < 0) { neg = -1; value = -value; }
- /*-- Check for too big numbers (> LONG_MAX) -- */
- if (value > 0x7FFFFFFFL) {
- *num = 0x7FFFFFFFL;
- *denom = 0;
- return;
- }
- /*-- Check for easy numbers -- */
- if (value == (int32_t)(value)) {
- *num = (int32_t)(neg * value);
- *denom = 1;
- return;
- }
- /*-- Check for too small numbers for "long" type rationals -- */
- if (value < 1.0 / (double)0x7FFFFFFFL) {
- *num = 0;
- *denom = 0x7FFFFFFFL;
- return;
- }
- /*-- There are two approaches using the Euclidean algorithm,
- * which can accidentally lead to different accuracies just depending on the value.
- * Try both and define which one was better.
- * Furthermore, set behavior of ToRationalEuclideanGCD() to the range of signed-long.
- */
- ToRationalEuclideanGCD(value, TRUE, FALSE, &ullNum, &ullDenom);
- ToRationalEuclideanGCD(value, TRUE, TRUE, &ullNum2, &ullDenom2);
- /*-- Double-Check, that returned values fit into LONG :*/
- if (ullNum > 0x7FFFFFFFL || ullDenom > 0x7FFFFFFFL || ullNum2 > 0x7FFFFFFFL || ullDenom2 > 0x7FFFFFFFL) {
- TIFFErrorExt(0, "TIFFLib: DoubleToSrational()", " Num or Denom exceeds LONG: val=%14.6f, num=%12"PRIu64", denom=%12"PRIu64" | num2=%12"PRIu64", denom2=%12"PRIu64"", neg*value, ullNum, ullDenom, ullNum2, ullDenom2);
- assert(0);
- }
- /* Check, which one has higher accuracy and take that. */
- dblDiff = fabs(value - ((double)ullNum / (double)ullDenom));
- dblDiff2 = fabs(value - ((double)ullNum2 / (double)ullDenom2));
- if (dblDiff < dblDiff2) {
- *num = (int32_t)(neg * (long)ullNum);
- *denom = (int32_t)ullDenom;
- }
- else {
- *num = (int32_t)(neg * (long)ullNum2);
- *denom = (int32_t)ullDenom2;
- }
- } /*-- DoubleToSrational() --------------*/
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagCheckedFloat(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, float value)
- {
- float m;
- assert(sizeof(float)==4);
- m=value;
- TIFFCvtNativeToIEEEFloat(tif,1,&m);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabFloat(&m);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,1,4,&m));
- }
- #endif
- static int
- TIFFWriteDirectoryTagCheckedFloatArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, float* value)
- {
- assert(count<0x40000000);
- assert(sizeof(float)==4);
- TIFFCvtNativeToIEEEFloat(tif,count,&value);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfFloat(value,count);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_FLOAT,count,count*4,value));
- }
- #ifdef notdef
- static int
- TIFFWriteDirectoryTagCheckedDouble(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, double value)
- {
- double m;
- assert(sizeof(double)==8);
- m=value;
- TIFFCvtNativeToIEEEDouble(tif,1,&m);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabDouble(&m);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,1,8,&m));
- }
- #endif
- static int
- TIFFWriteDirectoryTagCheckedDoubleArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, double* value)
- {
- assert(count<0x20000000);
- assert(sizeof(double)==8);
- TIFFCvtNativeToIEEEDouble(tif,count,&value);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfDouble(value,count);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_DOUBLE,count,count*8,value));
- }
- static int
- TIFFWriteDirectoryTagCheckedIfdArray(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint32_t* value)
- {
- assert(count<0x40000000);
- assert(sizeof(uint32_t) == 4);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong(value,count);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD,count,count*4,value));
- }
- static int
- TIFFWriteDirectoryTagCheckedIfd8Array(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint32_t count, uint64_t* value)
- {
- assert(count<0x20000000);
- assert(sizeof(uint64_t) == 8);
- assert(tif->tif_flags&TIFF_BIGTIFF);
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabArrayOfLong8(value,count);
- return(TIFFWriteDirectoryTagData(tif,ndir,dir,tag,TIFF_IFD8,count,count*8,value));
- }
- static int
- TIFFWriteDirectoryTagData(TIFF* tif, uint32_t* ndir, TIFFDirEntry* dir, uint16_t tag, uint16_t datatype, uint32_t count, uint32_t datalength, void* data)
- {
- static const char module[] = "TIFFWriteDirectoryTagData";
- uint32_t m;
- m=0;
- while (m<(*ndir))
- {
- assert(dir[m].tdir_tag!=tag);
- if (dir[m].tdir_tag>tag)
- break;
- m++;
- }
- if (m<(*ndir))
- {
- uint32_t n;
- for (n=*ndir; n>m; n--)
- dir[n]=dir[n-1];
- }
- dir[m].tdir_tag=tag;
- dir[m].tdir_type=datatype;
- dir[m].tdir_count=count;
- dir[m].tdir_offset.toff_long8 = 0;
- if (datalength<=((tif->tif_flags&TIFF_BIGTIFF)?0x8U:0x4U))
- {
- if( data && datalength )
- {
- _TIFFmemcpy(&dir[m].tdir_offset,data,datalength);
- }
- }
- else
- {
- uint64_t na,nb;
- na=tif->tif_dataoff;
- nb=na+datalength;
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- nb=(uint32_t)nb;
- if ((nb<na)||(nb<datalength))
- {
- TIFFErrorExt(tif->tif_clientdata,module,"Maximum TIFF file size exceeded");
- return(0);
- }
- if (!SeekOK(tif,na))
- {
- TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
- return(0);
- }
- assert(datalength<0x80000000UL);
- if (!WriteOK(tif,data,(tmsize_t)datalength))
- {
- TIFFErrorExt(tif->tif_clientdata,module,"IO error writing tag data");
- return(0);
- }
- tif->tif_dataoff=nb;
- if (tif->tif_dataoff&1)
- tif->tif_dataoff++;
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- uint32_t o;
- o=(uint32_t)na;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong(&o);
- _TIFFmemcpy(&dir[m].tdir_offset,&o,4);
- }
- else
- {
- dir[m].tdir_offset.toff_long8 = na;
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8(&dir[m].tdir_offset.toff_long8);
- }
- }
- (*ndir)++;
- return(1);
- }
- /*
- * Link the current directory into the directory chain for the file.
- */
- static int
- TIFFLinkDirectory(TIFF* tif)
- {
- static const char module[] = "TIFFLinkDirectory";
- tif->tif_diroff = (TIFFSeekFile(tif,0,SEEK_END)+1) & (~((toff_t)1));
- /*
- * Handle SubIFDs
- */
- if (tif->tif_flags & TIFF_INSUBIFD)
- {
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- uint32_t m;
- m = (uint32_t)tif->tif_diroff;
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabLong(&m);
- (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
- if (!WriteOK(tif, &m, 4)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error writing SubIFD directory link");
- return (0);
- }
- /*
- * Advance to the next SubIFD or, if this is
- * the last one configured, revert back to the
- * normal directory linkage.
- */
- if (--tif->tif_nsubifd)
- tif->tif_subifdoff += 4;
- else
- tif->tif_flags &= ~TIFF_INSUBIFD;
- return (1);
- }
- else
- {
- uint64_t m;
- m = tif->tif_diroff;
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabLong8(&m);
- (void) TIFFSeekFile(tif, tif->tif_subifdoff, SEEK_SET);
- if (!WriteOK(tif, &m, 8)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error writing SubIFD directory link");
- return (0);
- }
- /*
- * Advance to the next SubIFD or, if this is
- * the last one configured, revert back to the
- * normal directory linkage.
- */
- if (--tif->tif_nsubifd)
- tif->tif_subifdoff += 8;
- else
- tif->tif_flags &= ~TIFF_INSUBIFD;
- return (1);
- }
- }
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- uint32_t m;
- uint32_t nextdir;
- m = (uint32_t)(tif->tif_diroff);
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabLong(&m);
- if (tif->tif_header.classic.tiff_diroff == 0) {
- /*
- * First directory, overwrite offset in header.
- */
- tif->tif_header.classic.tiff_diroff = (uint32_t) tif->tif_diroff;
- (void) TIFFSeekFile(tif,4, SEEK_SET);
- if (!WriteOK(tif, &m, 4)) {
- TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
- "Error writing TIFF header");
- return (0);
- }
- return (1);
- }
- /*
- * Not the first directory, search to the last and append.
- */
- nextdir = tif->tif_header.classic.tiff_diroff;
- while(1) {
- uint16_t dircount;
- uint32_t nextnextdir;
- if (!SeekOK(tif, nextdir) ||
- !ReadOK(tif, &dircount, 2)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error fetching directory count");
- return (0);
- }
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabShort(&dircount);
- (void) TIFFSeekFile(tif,
- nextdir+2+dircount*12, SEEK_SET);
- if (!ReadOK(tif, &nextnextdir, 4)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error fetching directory link");
- return (0);
- }
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabLong(&nextnextdir);
- if (nextnextdir==0)
- {
- (void) TIFFSeekFile(tif,
- nextdir+2+dircount*12, SEEK_SET);
- if (!WriteOK(tif, &m, 4)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error writing directory link");
- return (0);
- }
- break;
- }
- nextdir=nextnextdir;
- }
- }
- else
- {
- uint64_t m;
- uint64_t nextdir;
- m = tif->tif_diroff;
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabLong8(&m);
- if (tif->tif_header.big.tiff_diroff == 0) {
- /*
- * First directory, overwrite offset in header.
- */
- tif->tif_header.big.tiff_diroff = tif->tif_diroff;
- (void) TIFFSeekFile(tif,8, SEEK_SET);
- if (!WriteOK(tif, &m, 8)) {
- TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
- "Error writing TIFF header");
- return (0);
- }
- return (1);
- }
- /*
- * Not the first directory, search to the last and append.
- */
- nextdir = tif->tif_header.big.tiff_diroff;
- while(1) {
- uint64_t dircount64;
- uint16_t dircount;
- uint64_t nextnextdir;
- if (!SeekOK(tif, nextdir) ||
- !ReadOK(tif, &dircount64, 8)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error fetching directory count");
- return (0);
- }
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabLong8(&dircount64);
- if (dircount64>0xFFFF)
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Sanity check on tag count failed, likely corrupt TIFF");
- return (0);
- }
- dircount=(uint16_t)dircount64;
- (void) TIFFSeekFile(tif,
- nextdir+8+dircount*20, SEEK_SET);
- if (!ReadOK(tif, &nextnextdir, 8)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error fetching directory link");
- return (0);
- }
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabLong8(&nextnextdir);
- if (nextnextdir==0)
- {
- (void) TIFFSeekFile(tif,
- nextdir+8+dircount*20, SEEK_SET);
- if (!WriteOK(tif, &m, 8)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error writing directory link");
- return (0);
- }
- break;
- }
- nextdir=nextnextdir;
- }
- }
- return (1);
- }
- /************************************************************************/
- /* TIFFRewriteField() */
- /* */
- /* Rewrite a field in the directory on disk without regard to */
- /* updating the TIFF directory structure in memory. Currently */
- /* only supported for field that already exist in the on-disk */
- /* directory. Mainly used for updating stripoffset / */
- /* stripbytecount values after the directory is already on */
- /* disk. */
- /* */
- /* Returns zero on failure, and one on success. */
- /************************************************************************/
- int
- _TIFFRewriteField(TIFF* tif, uint16_t tag, TIFFDataType in_datatype,
- tmsize_t count, void* data)
- {
- static const char module[] = "TIFFResetField";
- /* const TIFFField* fip = NULL; */
- uint16_t dircount;
- tmsize_t dirsize;
- uint8_t direntry_raw[20];
- uint16_t entry_tag = 0;
- uint16_t entry_type = 0;
- uint64_t entry_count = 0;
- uint64_t entry_offset = 0;
- int value_in_entry = 0;
- uint64_t read_offset;
- uint8_t *buf_to_write = NULL;
- TIFFDataType datatype;
- /* -------------------------------------------------------------------- */
- /* Find field definition. */
- /* -------------------------------------------------------------------- */
- /*fip =*/ TIFFFindField(tif, tag, TIFF_ANY);
- /* -------------------------------------------------------------------- */
- /* Do some checking this is a straight forward case. */
- /* -------------------------------------------------------------------- */
- if( isMapped(tif) )
- {
- TIFFErrorExt( tif->tif_clientdata, module,
- "Memory mapped files not currently supported for this operation." );
- return 0;
- }
- if( tif->tif_diroff == 0 )
- {
- TIFFErrorExt( tif->tif_clientdata, module,
- "Attempt to reset field on directory not already on disk." );
- return 0;
- }
- /* -------------------------------------------------------------------- */
- /* Read the directory entry count. */
- /* -------------------------------------------------------------------- */
- if (!SeekOK(tif, tif->tif_diroff)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "%s: Seek error accessing TIFF directory",
- tif->tif_name);
- return 0;
- }
- read_offset = tif->tif_diroff;
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- if (!ReadOK(tif, &dircount, sizeof (uint16_t))) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "%s: Can not read TIFF directory count",
- tif->tif_name);
- return 0;
- }
- if (tif->tif_flags & TIFF_SWAB)
- TIFFSwabShort(&dircount);
- dirsize = 12;
- read_offset += 2;
- } else {
- uint64_t dircount64;
- if (!ReadOK(tif, &dircount64, sizeof (uint64_t))) {
- 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);
- dircount = (uint16_t)dircount64;
- dirsize = 20;
- read_offset += 8;
- }
- /* -------------------------------------------------------------------- */
- /* Read through directory to find target tag. */
- /* -------------------------------------------------------------------- */
- while( dircount > 0 )
- {
- if (!ReadOK(tif, direntry_raw, dirsize)) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "%s: Can not read TIFF directory entry.",
- tif->tif_name);
- return 0;
- }
- memcpy( &entry_tag, direntry_raw + 0, sizeof(uint16_t) );
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort( &entry_tag );
- if( entry_tag == tag )
- break;
- read_offset += dirsize;
- }
- if( entry_tag != tag )
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "%s: Could not find tag %"PRIu16".",
- tif->tif_name, tag );
- return 0;
- }
- /* -------------------------------------------------------------------- */
- /* Extract the type, count and offset for this entry. */
- /* -------------------------------------------------------------------- */
- memcpy( &entry_type, direntry_raw + 2, sizeof(uint16_t) );
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort( &entry_type );
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- uint32_t value;
-
- memcpy( &value, direntry_raw + 4, sizeof(uint32_t) );
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong( &value );
- entry_count = value;
- memcpy( &value, direntry_raw + 8, sizeof(uint32_t) );
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong( &value );
- entry_offset = value;
- }
- else
- {
- memcpy( &entry_count, direntry_raw + 4, sizeof(uint64_t) );
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8( &entry_count );
- memcpy( &entry_offset, direntry_raw + 12, sizeof(uint64_t) );
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8( &entry_offset );
- }
- /* -------------------------------------------------------------------- */
- /* When a dummy tag was written due to TIFFDeferStrileArrayWriting() */
- /* -------------------------------------------------------------------- */
- if( entry_offset == 0 && entry_count == 0 && entry_type == 0 )
- {
- if( tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS )
- {
- entry_type = (tif->tif_flags&TIFF_BIGTIFF) ? TIFF_LONG8 : TIFF_LONG;
- }
- else
- {
- int write_aslong8 = 1;
- if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS )
- {
- write_aslong8 = WriteAsLong8(tif, TIFFStripSize64(tif));
- }
- else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS )
- {
- write_aslong8 = WriteAsLong8(tif, TIFFTileSize64(tif));
- }
- if( write_aslong8 )
- {
- entry_type = TIFF_LONG8;
- }
- else
- {
- int write_aslong4 = 1;
- if( count > 1 && tag == TIFFTAG_STRIPBYTECOUNTS )
- {
- write_aslong4 = WriteAsLong4(tif, TIFFStripSize64(tif));
- }
- else if( count > 1 && tag == TIFFTAG_TILEBYTECOUNTS )
- {
- write_aslong4 = WriteAsLong4(tif, TIFFTileSize64(tif));
- }
- if( write_aslong4 )
- {
- entry_type = TIFF_LONG;
- }
- else
- {
- entry_type = TIFF_SHORT;
- }
- }
- }
- }
- /* -------------------------------------------------------------------- */
- /* What data type do we want to write this as? */
- /* -------------------------------------------------------------------- */
- if( TIFFDataWidth(in_datatype) == 8 && !(tif->tif_flags&TIFF_BIGTIFF) )
- {
- if( in_datatype == TIFF_LONG8 )
- datatype = entry_type == TIFF_SHORT ? TIFF_SHORT : TIFF_LONG;
- else if( in_datatype == TIFF_SLONG8 )
- datatype = TIFF_SLONG;
- else if( in_datatype == TIFF_IFD8 )
- datatype = TIFF_IFD;
- else
- datatype = in_datatype;
- }
- else
- {
- if( in_datatype == TIFF_LONG8 &&
- (entry_type == TIFF_SHORT || entry_type == TIFF_LONG ||
- entry_type == TIFF_LONG8 ) )
- datatype = entry_type;
- else if( in_datatype == TIFF_SLONG8 &&
- (entry_type == TIFF_SLONG || entry_type == TIFF_SLONG8 ) )
- datatype = entry_type;
- else if( in_datatype == TIFF_IFD8 &&
- (entry_type == TIFF_IFD || entry_type == TIFF_IFD8 ) )
- datatype = entry_type;
- else
- datatype = in_datatype;
- }
- /* -------------------------------------------------------------------- */
- /* Prepare buffer of actual data to write. This includes */
- /* swabbing as needed. */
- /* -------------------------------------------------------------------- */
- buf_to_write =
- (uint8_t *)_TIFFCheckMalloc(tif, count, TIFFDataWidth(datatype),
- "for field buffer.");
- if (!buf_to_write)
- return 0;
- if( datatype == in_datatype )
- memcpy( buf_to_write, data, count * TIFFDataWidth(datatype) );
- else if( datatype == TIFF_SLONG && in_datatype == TIFF_SLONG8 )
- {
- tmsize_t i;
- for( i = 0; i < count; i++ )
- {
- ((int32_t *) buf_to_write)[i] =
- (int32_t) ((int64_t *) data)[i];
- if((int64_t) ((int32_t *) buf_to_write)[i] != ((int64_t *) data)[i] )
- {
- _TIFFfree( buf_to_write );
- TIFFErrorExt( tif->tif_clientdata, module,
- "Value exceeds 32bit range of output type." );
- return 0;
- }
- }
- }
- else if( (datatype == TIFF_LONG && in_datatype == TIFF_LONG8)
- || (datatype == TIFF_IFD && in_datatype == TIFF_IFD8) )
- {
- tmsize_t i;
- for( i = 0; i < count; i++ )
- {
- ((uint32_t *) buf_to_write)[i] =
- (uint32_t) ((uint64_t *) data)[i];
- if((uint64_t) ((uint32_t *) buf_to_write)[i] != ((uint64_t *) data)[i] )
- {
- _TIFFfree( buf_to_write );
- TIFFErrorExt( tif->tif_clientdata, module,
- "Value exceeds 32bit range of output type." );
- return 0;
- }
- }
- }
- else if( datatype == TIFF_SHORT && in_datatype == TIFF_LONG8 )
- {
- tmsize_t i;
- for( i = 0; i < count; i++ )
- {
- ((uint16_t *) buf_to_write)[i] =
- (uint16_t) ((uint64_t *) data)[i];
- if((uint64_t) ((uint16_t *) buf_to_write)[i] != ((uint64_t *) data)[i] )
- {
- _TIFFfree( buf_to_write );
- TIFFErrorExt( tif->tif_clientdata, module,
- "Value exceeds 16bit range of output type." );
- return 0;
- }
- }
- }
- else
- {
- TIFFErrorExt( tif->tif_clientdata, module,
- "Unhandled type conversion." );
- return 0;
- }
- if( TIFFDataWidth(datatype) > 1 && (tif->tif_flags&TIFF_SWAB) )
- {
- if( TIFFDataWidth(datatype) == 2 )
- TIFFSwabArrayOfShort((uint16_t *) buf_to_write, count );
- else if( TIFFDataWidth(datatype) == 4 )
- TIFFSwabArrayOfLong((uint32_t *) buf_to_write, count );
- else if( TIFFDataWidth(datatype) == 8 )
- TIFFSwabArrayOfLong8((uint64_t *) buf_to_write, count );
- }
- /* -------------------------------------------------------------------- */
- /* Is this a value that fits into the directory entry? */
- /* -------------------------------------------------------------------- */
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- if( TIFFDataWidth(datatype) * count <= 4 )
- {
- entry_offset = read_offset + 8;
- value_in_entry = 1;
- }
- }
- else
- {
- if( TIFFDataWidth(datatype) * count <= 8 )
- {
- entry_offset = read_offset + 12;
- value_in_entry = 1;
- }
- }
- if( (tag == TIFFTAG_TILEOFFSETS || tag == TIFFTAG_STRIPOFFSETS) &&
- 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_stripoffset_entry.tdir_type = datatype;
- tif->tif_dir.td_stripoffset_entry.tdir_count = count;
- }
- else if( (tag == TIFFTAG_TILEBYTECOUNTS || tag == TIFFTAG_STRIPBYTECOUNTS) &&
- 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 )
- {
- tif->tif_dir.td_stripbytecount_entry.tdir_type = datatype;
- tif->tif_dir.td_stripbytecount_entry.tdir_count = count;
- }
- /* -------------------------------------------------------------------- */
- /* If the tag type, and count match, then we just write it out */
- /* over the old values without altering the directory entry at */
- /* all. */
- /* -------------------------------------------------------------------- */
- if( entry_count == (uint64_t)count && entry_type == (uint16_t) datatype )
- {
- if (!SeekOK(tif, entry_offset)) {
- _TIFFfree( buf_to_write );
- TIFFErrorExt(tif->tif_clientdata, module,
- "%s: Seek error accessing TIFF directory",
- tif->tif_name);
- return 0;
- }
- if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
- _TIFFfree( buf_to_write );
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error writing directory link");
- return (0);
- }
- _TIFFfree( buf_to_write );
- return 1;
- }
- /* -------------------------------------------------------------------- */
- /* Otherwise, we write the new tag data at the end of the file. */
- /* -------------------------------------------------------------------- */
- if( !value_in_entry )
- {
- entry_offset = TIFFSeekFile(tif,0,SEEK_END);
-
- if (!WriteOK(tif, buf_to_write, count*TIFFDataWidth(datatype))) {
- _TIFFfree( buf_to_write );
- TIFFErrorExt(tif->tif_clientdata, module,
- "Error writing directory link");
- return (0);
- }
- }
- else
- {
- memcpy( &entry_offset, buf_to_write, count*TIFFDataWidth(datatype));
- }
- _TIFFfree( buf_to_write );
- buf_to_write = 0;
- /* -------------------------------------------------------------------- */
- /* Adjust the directory entry. */
- /* -------------------------------------------------------------------- */
- entry_type = datatype;
- entry_count = (uint64_t)count;
- memcpy( direntry_raw + 2, &entry_type, sizeof(uint16_t) );
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabShort( (uint16_t *) (direntry_raw + 2) );
- if (!(tif->tif_flags&TIFF_BIGTIFF))
- {
- uint32_t value;
- value = (uint32_t) entry_count;
- memcpy( direntry_raw + 4, &value, sizeof(uint32_t) );
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong( (uint32_t *) (direntry_raw + 4) );
- value = (uint32_t) entry_offset;
- memcpy( direntry_raw + 8, &value, sizeof(uint32_t) );
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong( (uint32_t *) (direntry_raw + 8) );
- }
- else
- {
- memcpy( direntry_raw + 4, &entry_count, sizeof(uint64_t) );
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8( (uint64_t *) (direntry_raw + 4) );
- memcpy( direntry_raw + 12, &entry_offset, sizeof(uint64_t) );
- if (tif->tif_flags&TIFF_SWAB)
- TIFFSwabLong8( (uint64_t *) (direntry_raw + 12) );
- }
- /* -------------------------------------------------------------------- */
- /* Write the directory entry out to disk. */
- /* -------------------------------------------------------------------- */
- if (!SeekOK(tif, read_offset )) {
- TIFFErrorExt(tif->tif_clientdata, module,
- "%s: Seek error accessing TIFF directory",
- tif->tif_name);
- return 0;
- }
- if (!WriteOK(tif, direntry_raw,dirsize))
- {
- TIFFErrorExt(tif->tif_clientdata, module,
- "%s: Can not write TIFF directory entry.",
- tif->tif_name);
- return 0;
- }
-
- return 1;
- }
- /* vim: set ts=8 sts=8 sw=8 noet: */
- /*
- * Local Variables:
- * mode: c
- * c-basic-offset: 8
- * fill-column: 78
- * End:
- */
|