JPEG2000DecoderCS.Mod 176 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840
  1. MODULE JPEG2000DecoderCS;
  2. (* Part of the JPEG2000 decoder implementation *)
  3. (* Partially based on the JJ2000 reference implementation of EPF Lausanne (http://jj2000.epfl.ch) *)
  4. (* Contains the J2C codestream parser engine *)
  5. (*
  6. KNOWN BUGS:
  7. - Codestreams with packed packet headers in tile-part headers and with multiple tile-parts
  8. won't be decoded correctly if headers are crossing tile-part boundaries and the number of
  9. tile-parts for the tile are unknown
  10. *)
  11. (*
  12. TODO:
  13. - Interpretation of progression order change segments: is the progression order defined
  14. in such a segement really referring to the progression after the described one (as
  15. suggested by the JJ2000 reference implementation)? (See CodestreamReader.ProgressionChange)
  16. - Availability of data from the stream could cause some problems (i.e. when the stream is truncated
  17. or data is not ready yet)
  18. - Optimization: in PacketDecoder, ReadCodingPasses could be inlined.
  19. *)
  20. IMPORT
  21. SYSTEM, J2KU := JPEG2000DecoderUtil, KernelLog, Machine, Streams;
  22. CONST
  23. (* --- Compile Options --- *)
  24. (*
  25. Some codestream constraints that may be set. This may be used as some kind
  26. of control mechanism to prevent "out of memory" traps etc. (especially caused
  27. by corrupted codestreams)
  28. *)
  29. MAX_IMG_WIDTH = MAX(LONGINT); (* Default: MAX(LONGINT) *)
  30. MAX_IMG_HEIGHT = MAX(LONGINT); (* Default: MAX(LONGINT) *)
  31. MAX_TILES = 65535; (* Default: 65535 (= (maximum tile index + 1) -> refer to the Isot parameter of the SOT segment) *)
  32. MAX_COMPONENTS = 16384; (* Default: 16384 (= maximum number of components -> refer to the Csiz parameter of the SIZ segment) *)
  33. MAX_LAYERS = 65535; (* Default: 65535 (= maximum number of layers -> refer to the SGcod parameter of the COD segment) *)
  34. (* --- END Compile Options --- *)
  35. (* --- Configuration constants --- *)
  36. CODESTREAM_READER* = 0;
  37. BUF_CODESTREAM_READER* = 1;
  38. (* --- END Configuration constants --- *)
  39. (* --- General constants --- *)
  40. (**
  41. This tile-part index is set, when the codestream reader
  42. and its subcomponents are running in rebuild mode
  43. *)
  44. REBUILD_TILEPART* = MAX(LONGINT);
  45. (* --- END General constants --- *)
  46. (* --- Codestream Markers --- *)
  47. SOC = 0000FF4FH; (* Start of codestream *)
  48. SOT = 0000FF90H; (* Start of tile-part *)
  49. SOD = 0000FF93H; (* Start of data *)
  50. EOC = 0000FFD9H; (* End of codestream *)
  51. SIZ = 0000FF51H; (* Image and tile size *)
  52. COD = 0000FF52H; (* Coding style default *)
  53. COC = 0000FF53H; (* Coding style component *)
  54. RGN = 0000FF5EH; (* Region-of-interest *)
  55. QCD = 0000FF5CH; (* Quantization default *)
  56. QCC = 0000FF5DH; (* Quantization component *)
  57. POC = 0000FF5FH; (* Progression order change *)
  58. TLM = 0000FF55H; (* Tile-part lengths *)
  59. PLM = 0000FF57H; (* Packet length, main header *)
  60. PLT = 0000FF58H; (* Packet length, tile-part header *)
  61. PPM = 0000FF60H; (* Packed packet headers, main header *)
  62. PPT = 0000FF61H; (* Packed packet headers, tile-part header *)
  63. SOP = 0000FF91H; (* Start of packet *)
  64. EPH = 0000FF92H; (* End of packet header *)
  65. CRG = 0000FF63H; (* Component registration *)
  66. COM = 0000FF64H; (* Comment *)
  67. (* --- END Codestream Markers --- *)
  68. ENTROPY_NUM_PASSES = 3;
  69. ENTROPY_FIRST_BYPASS_IDX = 3 * ENTROPY_NUM_PASSES + 1;
  70. (* --- Quantization styles --- *)
  71. NOQUANT* = 00000000H; (* No quantization *)
  72. QUANT_DER* = 00000001H; (* Scalar derived quantization *)
  73. QUANT_EXP* = 00000002H; (* Scalar expounded quantization *)
  74. (* --- END Quantization styles --- *)
  75. (* --- Wavelet transformation types --- *)
  76. TRANS_9X7_IRREV* = 00000000H;
  77. TRANS_5X3_REV* = 00000001H;
  78. (* --- END Wavelet transformation types --- *)
  79. (* --- Progression orders --- *)
  80. PROG_LRCP = 00000000H; (* Layer - resolution level - component - position progression *)
  81. PROG_RLCP = 00000001H; (* Resolution level - layer - component - position progression *)
  82. PROG_RPCL = 00000002H; (* Resolution level - position - component - layer progression *)
  83. PROG_PCRL = 00000003H; (* Position - component - resolution level - layer progression *)
  84. PROG_CPRL = 00000004H; (* Component - position - resolution level - layer progression *)
  85. (* --- END Progression orders --- *)
  86. (* --- Precinct constants --- *)
  87. MAX_PREC_SIZ = 15;
  88. (* --- END Precinct constants --- *)
  89. TYPE
  90. PrecinctExp = RECORD
  91. ppx : LONGINT; (* Precinct width exponent *)
  92. ppy : LONGINT; (* Precinct height exponent *)
  93. END;
  94. (** Component dependent coding style *)
  95. CodingStyle = OBJECT
  96. VAR
  97. maxps : BOOLEAN; (* Maximum precinct size used? *)
  98. ndec : LONGINT; (* Number of decomposition levels *)
  99. cblw : LONGINT; (* Code-block width exponent *)
  100. cblh : LONGINT; (* Code-block heigth exponent *)
  101. selcb : BOOLEAN; (* Selective arithmetic coding bypass? *)
  102. rescp : BOOLEAN; (* Reset context probabilities on coding pass boundaries? *)
  103. term : BOOLEAN; (* Termination on each coding pass? *)
  104. vert : BOOLEAN; (* Vertically causal context? *)
  105. pred : BOOLEAN; (* Predictable termination? *)
  106. segs : BOOLEAN; (* Segmentation symbols used? *)
  107. trans : LONGINT; (* Wavelet transformation type *)
  108. precs : POINTER TO ARRAY OF PrecinctExp; (* Precinct sizes (in defined order) *)
  109. END CodingStyle;
  110. (** Component Independent Coding Style *)
  111. CICodingStyle = OBJECT
  112. VAR
  113. po : LONGINT; (* Progression order *)
  114. nl : LONGINT; (* Number of layers *)
  115. mct : LONGINT; (* Multiple component tranformation type *)
  116. sop : BOOLEAN; (* SOP markers used? *)
  117. eph : BOOLEAN; (* EPH markers used? *)
  118. END CICodingStyle;
  119. Component = OBJECT
  120. VAR
  121. signed : BOOLEAN; (* TRUE if component samples are signed values *)
  122. depth : LONGINT; (* Component bit depth *)
  123. subsx : LONGINT; (* Horizonal separation (sub-sampling factor) of the component *)
  124. subsy : LONGINT; (* Vertical separation (sub-sampling factor) of the component *)
  125. END Component;
  126. Quantization = OBJECT
  127. VAR
  128. style : LONGINT; (* Quantization style *)
  129. nguardb : LONGINT; (* Number of guard bits *)
  130. nstepsiz : LONGINT;
  131. stepsiz : POINTER TO ARRAY OF QuantStep; (* Array containing quantization step sizes (if signalled in codestream) *)
  132. END Quantization;
  133. QuantStep = OBJECT
  134. VAR
  135. mant : LONGINT; (* Mantissa *)
  136. exp : LONGINT; (* Exponent *)
  137. END QuantStep;
  138. (**
  139. Image information object. Gives information on image width/heigth
  140. on different decomposition levels etc.
  141. *)
  142. ImageInfo* = OBJECT
  143. VAR
  144. xsiz, ysiz : LONGINT; (* Width / height of reference grid *)
  145. xos, yos : LONGINT; (* Horizontal / vertical offset from the origin *)
  146. nt : LONGINT; (* Overall number of tiles *)
  147. nxt, nyt : LONGINT; (* Number of tiles in horizontal / vertical direction *)
  148. xt, yt : LONGINT; (* Width / height of one reference tile w.r.t the reference grid *)
  149. xtos, ytos : LONGINT; (* Horizontal / vertical offset from the origin to the first tile *)
  150. ncomp : LONGINT; (* Number of components in the image *)
  151. comps : POINTER TO ARRAY OF Component;
  152. (**
  153. Get width of image on reference grid at decomposition level 'declevel'.
  154. *)
  155. PROCEDURE GetImgWidth* (declevel : LONGINT) : LONGINT;
  156. VAR
  157. tmp : LONGINT;
  158. BEGIN
  159. tmp := LSH(SYSTEM.VAL(LONGINT, 1), declevel) - 1;
  160. RETURN LSH(xsiz + tmp, -declevel) - LSH(xos + tmp, -declevel);
  161. END GetImgWidth;
  162. (**
  163. Get height of image on reference grid at decomposition level 'declevel'.
  164. *)
  165. PROCEDURE GetImgHeight* (declevel : LONGINT) : LONGINT;
  166. VAR
  167. tmp : LONGINT;
  168. BEGIN
  169. tmp := LSH(SYSTEM.VAL(LONGINT, 1), declevel) - 1;
  170. RETURN LSH(ysiz + tmp, -declevel) - LSH(yos + tmp, -declevel);
  171. END GetImgHeight;
  172. (**
  173. Get horizontal image offset relative to reference grid origin at decomposition level 'declevel'.
  174. *)
  175. PROCEDURE GetImgULX* (declevel : LONGINT) : LONGINT;
  176. VAR
  177. tmp : LONGINT;
  178. BEGIN
  179. tmp := LSH(SYSTEM.VAL(LONGINT, 1), declevel) - 1;
  180. RETURN LSH(xos + tmp, -declevel);
  181. END GetImgULX;
  182. (**
  183. Get vertical image offset relative to reference grid origin at decomposition level 'declevel'.
  184. *)
  185. PROCEDURE GetImgULY* (declevel : LONGINT) : LONGINT;
  186. VAR
  187. tmp : LONGINT;
  188. BEGIN
  189. tmp := LSH(SYSTEM.VAL(LONGINT, 1), declevel) - 1;
  190. RETURN LSH(yos + tmp, -declevel);
  191. END GetImgULY;
  192. (**
  193. Get width of one component on reference grid at decomposition level 'declevel'.
  194. *)
  195. PROCEDURE GetCompImgWidth* (component, declevel : LONGINT) : LONGINT;
  196. VAR
  197. subsx, tmp, cx0, cx1 : LONGINT;
  198. (* cx0 : Horizontal coordinate of upper left hand sample of component *)
  199. (* cx1 - 1: Horizontal coordinate of lower right hand sample of component *)
  200. BEGIN
  201. subsx := comps[component].subsx;
  202. tmp := LSH(SYSTEM.VAL(LONGINT, 1), declevel) - 1;
  203. cx0 := (xos + subsx - 1) DIV subsx;
  204. cx1 := (xsiz + subsx - 1) DIV subsx;
  205. RETURN LSH(cx1 + tmp, -declevel) - LSH(cx0 + tmp, -declevel);
  206. END GetCompImgWidth;
  207. (**
  208. Get height of one component on reference grid at decomposition level 'declevel'.
  209. *)
  210. PROCEDURE GetCompImgHeight* (component, declevel : LONGINT) : LONGINT;
  211. VAR
  212. subsy, tmp, cy0, cy1 : LONGINT;
  213. (* cy0 : Vertical coordinate of upper left hand sample of component *)
  214. (* cy1 - 1: Vertical coordinate of lower right hand sample of component *)
  215. BEGIN
  216. subsy := comps[component].subsy;
  217. tmp := LSH(SYSTEM.VAL(LONGINT, 1), declevel) - 1;
  218. cy0 := (yos + subsy - 1) DIV subsy;
  219. cy1 := (ysiz + subsy - 1) DIV subsy;
  220. RETURN LSH(cy1 + tmp, -declevel) - LSH(cy0 + tmp, -declevel);
  221. END GetCompImgHeight;
  222. (**
  223. Get total numbe of tiles in the image.
  224. *)
  225. PROCEDURE GetNumTiles* () : LONGINT;
  226. BEGIN
  227. RETURN nt;
  228. END GetNumTiles;
  229. (**
  230. Get number of tiles in horizontal direction.
  231. *)
  232. PROCEDURE GetNumTilesX* () : LONGINT;
  233. BEGIN
  234. RETURN nxt;
  235. END GetNumTilesX;
  236. (**
  237. Get number of tiles in horizontal direction.
  238. *)
  239. PROCEDURE GetNumTilesY* () : LONGINT;
  240. BEGIN
  241. RETURN nyt;
  242. END GetNumTilesY;
  243. (**
  244. Get width of tile with index 'tile' on reference grid at decomposition level 'declevel'.
  245. *)
  246. PROCEDURE GetTileWidth* (tile, declevel : LONGINT) : LONGINT;
  247. VAR
  248. tx0, tx1, p, tmp : LONGINT;
  249. BEGIN
  250. tmp := LSH(SYSTEM.VAL(LONGINT, 1), declevel) - 1;
  251. (* Compute the horizontal index of the current tile in the reference grid *)
  252. p := tile MOD nxt;
  253. (* Compute upper and lower x-coordinate *)
  254. tx0 := xtos + p*xt;
  255. tx1 := tx0 + xt;
  256. (* Handle boundary conditions *)
  257. IF xos > tx0 THEN
  258. tx0 := xos;
  259. END;
  260. IF xsiz < tx1 THEN
  261. tx1 := xsiz;
  262. END;
  263. RETURN LSH(tx1 + tmp, -declevel) - LSH(tx0 + tmp, -declevel);
  264. END GetTileWidth;
  265. (**
  266. Get height of tile with index 'tile' on reference grid at decomposition level 'declevel'.
  267. *)
  268. PROCEDURE GetTileHeight* (tile, declevel : LONGINT) : LONGINT;
  269. VAR
  270. ty0, ty1, q, tmp : LONGINT;
  271. BEGIN
  272. tmp := LSH(SYSTEM.VAL(LONGINT, 1), declevel) - 1;
  273. (* Compute the vertical index of the current tile in the reference grid *)
  274. q := tile DIV nxt;
  275. (* Compute upper and lower y-coordinate *)
  276. ty0 := ytos + q*yt;
  277. ty1 := ty0 + yt;
  278. (* Handle boundary conditions *)
  279. IF yos > ty0 THEN
  280. ty0 := yos;
  281. END;
  282. IF ysiz < ty1 THEN
  283. ty1 := ysiz;
  284. END;
  285. RETURN LSH(ty1 + tmp, -declevel) - LSH(ty0 + tmp, -declevel);
  286. END GetTileHeight;
  287. (**
  288. Get horizontal offset of tile with index 'tile' relative to reference grid origin
  289. at decomposition level 'declevel'.
  290. *)
  291. PROCEDURE GetTileULX* (tile, declevel : LONGINT) : LONGINT;
  292. VAR
  293. tx0, p, tmp : LONGINT;
  294. BEGIN
  295. tmp := LSH(SYSTEM.VAL(LONGINT, 1), declevel) - 1;
  296. (* Compute the horizontal index of the current tile in the reference grid *)
  297. p := tile MOD nxt;
  298. (* Determine the actual upper left x-coordinate of the tile *)
  299. tx0 := xtos + p*xt;
  300. IF xos > tx0 THEN
  301. tx0 := xos;
  302. END;
  303. RETURN LSH(tx0 + tmp, -declevel);
  304. END GetTileULX;
  305. (**
  306. Get horizontal offset of tile with index 'tile' relative to reference grid origin
  307. at decomposition level 'declevel'.
  308. *)
  309. PROCEDURE GetTileULY* (tile, declevel : LONGINT) : LONGINT;
  310. VAR
  311. ty0, q, tmp : LONGINT;
  312. BEGIN
  313. tmp := LSH(SYSTEM.VAL(LONGINT, 1), declevel) - 1;
  314. (* Compute the vertical index of the current tile in the reference grid *)
  315. q := tile DIV nxt;
  316. (* Determine the actual upper left y-coordinate of the tile *)
  317. ty0 := ytos + q*yt;
  318. IF yos > ty0 THEN
  319. ty0 := yos;
  320. END;
  321. RETURN LSH(ty0 + tmp, -declevel);
  322. END GetTileULY;
  323. PROCEDURE GetNumComponents* () : LONGINT;
  324. BEGIN
  325. RETURN ncomp;
  326. END GetNumComponents;
  327. (**
  328. Get horizontal subsampling factor of component 'component'
  329. *)
  330. PROCEDURE GetSubsX* (component : LONGINT) : LONGINT;
  331. BEGIN
  332. RETURN comps[component].subsx;
  333. END GetSubsX;
  334. (**
  335. Get vertical subsampling factor of component 'component'
  336. *)
  337. PROCEDURE GetSubsY* (component : LONGINT) : LONGINT;
  338. BEGIN
  339. RETURN comps[component].subsy;
  340. END GetSubsY;
  341. PROCEDURE GetBitDepth* (component : LONGINT) : LONGINT;
  342. BEGIN
  343. RETURN comps[component].depth;
  344. END GetBitDepth;
  345. END ImageInfo;
  346. (**
  347. This object is used to obtain information on the codestream (image info, coding styles, etc.)
  348. It's created by and obtained through the codestream reader.
  349. *)
  350. DecoderSpecs* = OBJECT
  351. VAR
  352. imgInfo : ImageInfo;
  353. (* 1st dimension: tile index; 2nd dimension (if any): component index *)
  354. cstyle : POINTER TO ARRAY OF ARRAY OF CodingStyle;
  355. cics : POINTER TO ARRAY OF CICodingStyle;
  356. quant : POINTER TO ARRAY OF ARRAY OF Quantization;
  357. roiShift : POINTER TO ARRAY OF ARRAY OF LONGINT;
  358. PROCEDURE &InitNew*;
  359. BEGIN
  360. imgInfo := NIL;
  361. cstyle := NIL;
  362. cics := NIL;
  363. quant := NIL;
  364. roiShift := NIL;
  365. END InitNew;
  366. (**
  367. Return the image information object
  368. *)
  369. PROCEDURE GetImageInfo* () : ImageInfo;
  370. BEGIN
  371. RETURN imgInfo;
  372. END GetImageInfo;
  373. (**
  374. TRUE if arithmetic bypass coding is used for the given tile-component.
  375. *)
  376. PROCEDURE BypassCoding* (tile, component : LONGINT) : BOOLEAN;
  377. BEGIN
  378. RETURN cstyle[tile][component].selcb;
  379. END BypassCoding;
  380. (**
  381. TRUE if regular termination is used when decoding data for the given tile-component.
  382. *)
  383. PROCEDURE RegularTermination* (tile, component : LONGINT) : BOOLEAN;
  384. BEGIN
  385. RETURN cstyle[tile][component].term;
  386. END RegularTermination;
  387. (**
  388. TRUE if vertically causal context formation is used when decoding data for the given tile-component.
  389. *)
  390. PROCEDURE VerticallyCausalContext* (tile, component : LONGINT) : BOOLEAN;
  391. BEGIN
  392. RETURN cstyle[tile][component].vert;
  393. END VerticallyCausalContext;
  394. (**
  395. TRUE if predictable termination is used when decoding data for the given tile-component.
  396. *)
  397. PROCEDURE PredictableTermination* (tile, component : LONGINT) : BOOLEAN;
  398. BEGIN
  399. RETURN cstyle[tile][component].pred;
  400. END PredictableTermination;
  401. (**
  402. TRUE if contexts are reset after each coding pass when decoding data for the given tile-component.
  403. *)
  404. PROCEDURE ResetContexts* (tile, component : LONGINT) : BOOLEAN;
  405. BEGIN
  406. RETURN cstyle[tile][component].rescp;
  407. END ResetContexts;
  408. (**
  409. TRUE if segmentation symbols are used when decoding data for the given tile-component.
  410. *)
  411. PROCEDURE SegmentationSymbols* (tile, component : LONGINT) : BOOLEAN;
  412. BEGIN
  413. RETURN cstyle[tile][component].segs;
  414. END SegmentationSymbols;
  415. (**
  416. The wavelet transformation type used for the give tile-component
  417. *)
  418. PROCEDURE GetWavTransType* (tile, component : LONGINT) : LONGINT;
  419. BEGIN
  420. RETURN cstyle[tile][component].trans;
  421. END GetWavTransType;
  422. (**
  423. TRUE if the wavelet transformation for the given tile-component is reversible
  424. *)
  425. PROCEDURE IsReversibleWavTrans* (tile, component : LONGINT) : BOOLEAN;
  426. BEGIN
  427. RETURN cstyle[tile][component].trans = TRANS_5X3_REV;
  428. END IsReversibleWavTrans;
  429. (**
  430. TRUE if a multiple component transformation is used for the given tile.
  431. *)
  432. PROCEDURE CompTransUsed* (tile : LONGINT) : BOOLEAN;
  433. BEGIN
  434. RETURN cics[tile].mct # 0;
  435. END CompTransUsed;
  436. (**
  437. Returns the number of wavelet decomposition levels for a given
  438. tile-component.
  439. *)
  440. PROCEDURE GetNumDecLevels* (tile, component : LONGINT) : LONGINT;
  441. BEGIN
  442. RETURN cstyle[tile][component].ndec;
  443. END GetNumDecLevels;
  444. (**
  445. Gets the minimum number of wavelet decomposition levels over all
  446. tile-components
  447. *)
  448. PROCEDURE GetImgMinDecLevels* () : LONGINT;
  449. VAR
  450. min, i, j : LONGINT;
  451. BEGIN
  452. min := cstyle[0][0].ndec;
  453. FOR j := 0 TO imgInfo.nt - 1 DO
  454. FOR i := 1 TO imgInfo.ncomp - 1 DO
  455. IF cstyle[j][i].ndec < min THEN
  456. min := cstyle[j][i].ndec;
  457. END;
  458. END;
  459. END;
  460. RETURN min;
  461. END GetImgMinDecLevels;
  462. (**
  463. Gets the maximum number of wavelet decomposition levels over all
  464. tile-components
  465. *)
  466. PROCEDURE GetImgMaxDecLevels* () : LONGINT;
  467. VAR
  468. max, i, j : LONGINT;
  469. BEGIN
  470. max := cstyle[0][0].ndec;
  471. FOR j := 0 TO imgInfo.nt - 1 DO
  472. FOR i := 1 TO imgInfo.ncomp - 1 DO
  473. IF cstyle[j][i].ndec > max THEN
  474. max := cstyle[j][i].ndec;
  475. END;
  476. END;
  477. END;
  478. RETURN max;
  479. END GetImgMaxDecLevels;
  480. (**
  481. Gets the minimum number of wavelet decomposition levels
  482. for a given tile.
  483. *)
  484. PROCEDURE GetMinDecLevels* (tile : LONGINT) : LONGINT;
  485. VAR
  486. min, i : LONGINT;
  487. BEGIN
  488. min := cstyle[tile][0].ndec;
  489. FOR i := 1 TO imgInfo.ncomp - 1 DO
  490. IF cstyle[tile][i].ndec < min THEN
  491. min := cstyle[tile][i].ndec;
  492. END;
  493. END;
  494. RETURN min;
  495. END GetMinDecLevels;
  496. PROCEDURE GetMaxDecLevels* (tile : LONGINT) : LONGINT;
  497. VAR
  498. max, i : LONGINT;
  499. BEGIN
  500. max := cstyle[tile][0].ndec;
  501. FOR i := 1 TO imgInfo.ncomp - 1 DO
  502. IF cstyle[tile][i].ndec > max THEN
  503. max := cstyle[tile][i].ndec;
  504. END;
  505. END;
  506. RETURN max;
  507. END GetMaxDecLevels;
  508. (**
  509. Gets the number of layers for a given tile
  510. *)
  511. PROCEDURE GetNumLayers* (tile : LONGINT) : LONGINT;
  512. BEGIN
  513. RETURN cics[tile].nl;
  514. END GetNumLayers;
  515. (**
  516. Gets the minimum number of layers over all tiles
  517. *)
  518. PROCEDURE GetMinNumLayers* () : LONGINT;
  519. VAR
  520. i, min : LONGINT;
  521. BEGIN
  522. min := cics[0].nl;
  523. FOR i := 0 TO imgInfo.nt - 1 DO
  524. IF cics[i].nl < min THEN
  525. min := cics[i].nl;
  526. END;
  527. END;
  528. RETURN min;
  529. END GetMinNumLayers;
  530. (*
  531. Gets the precinct width exponent for a given tile, component and
  532. resolution level
  533. *)
  534. PROCEDURE GetPPX (tile, comp, reslevel : LONGINT) : LONGINT;
  535. BEGIN
  536. IF cstyle[tile][comp].maxps THEN
  537. RETURN MAX_PREC_SIZ;
  538. ELSE
  539. RETURN cstyle[tile][comp].precs[reslevel].ppx;
  540. END;
  541. END GetPPX;
  542. (*
  543. Gets the precinct height exponent for a given tile, component and
  544. resolution level
  545. *)
  546. PROCEDURE GetPPY (tile, comp, reslevel : LONGINT) : LONGINT;
  547. BEGIN
  548. IF cstyle[tile][comp].maxps THEN
  549. RETURN MAX_PREC_SIZ;
  550. ELSE
  551. RETURN cstyle[tile][comp].precs[reslevel].ppy;
  552. END;
  553. END GetPPY;
  554. (**
  555. Returns the maximum code-block width exponent for a specific tile.
  556. *)
  557. PROCEDURE GetMaxCblkWidthExp* (tile : LONGINT) : LONGINT;
  558. VAR
  559. i, maxw : LONGINT;
  560. BEGIN
  561. maxw := cstyle[tile][0].cblw;
  562. FOR i := 1 TO imgInfo.ncomp - 1 DO
  563. IF cstyle[tile][i].cblw > maxw THEN
  564. maxw := cstyle[tile][i].cblw;
  565. END;
  566. END;
  567. RETURN maxw;
  568. END GetMaxCblkWidthExp;
  569. (**
  570. Returns the maximum code-block height exponent for a specific tile.
  571. *)
  572. PROCEDURE GetMaxCblkHeightExp* (tile : LONGINT) : LONGINT;
  573. VAR
  574. i, maxh : LONGINT;
  575. BEGIN
  576. maxh := cstyle[tile][0].cblh;
  577. FOR i := 1 TO imgInfo.ncomp - 1 DO
  578. IF cstyle[tile][i].cblh > maxh THEN
  579. maxh := cstyle[tile][i].cblh;
  580. END;
  581. END;
  582. RETURN maxh;
  583. END GetMaxCblkHeightExp;
  584. (**
  585. Returns the quantization style for a given tile-component
  586. *)
  587. PROCEDURE GetQuantStyle* (tile, comp : LONGINT) : LONGINT;
  588. BEGIN
  589. RETURN quant[tile][comp].style;
  590. END GetQuantStyle;
  591. (**
  592. Gets the exponent used in the calculation of the quantization step
  593. (for a given tile, component, resolution level and subband)
  594. *)
  595. PROCEDURE GetQuantExponent* (tile, comp, reslevel, subband : LONGINT) : LONGINT;
  596. BEGIN
  597. IF reslevel = 0 THEN
  598. RETURN quant[tile][comp].stepsiz[0].exp
  599. ELSE
  600. RETURN quant[tile][comp].stepsiz[3*(reslevel-1) + subband].exp;
  601. END;
  602. END GetQuantExponent;
  603. (**
  604. Gets the mantissa used in the calculation of the quantization step
  605. (for a given tile, component, resolution level and subband)
  606. *)
  607. PROCEDURE GetQuantMantissa* (tile, comp, reslevel, subband : LONGINT) : LONGINT;
  608. BEGIN
  609. IF reslevel = 0 THEN
  610. RETURN quant[tile][comp].stepsiz[0].mant;
  611. ELSE
  612. RETURN quant[tile][comp].stepsiz[3*(reslevel-1) + subband].mant;
  613. END;
  614. END GetQuantMantissa;
  615. (**
  616. TRUE, if ROI coding is used for a given tile-component
  617. *)
  618. PROCEDURE ROIUsed* (tile, comp : LONGINT) : BOOLEAN;
  619. BEGIN
  620. RETURN (roiShift # NIL) & (roiShift[tile][comp] >= 0);
  621. END ROIUsed;
  622. (**
  623. Returns the shift value (as defined in the Maxshift method) for
  624. ROI decoding (or -1 if there is no such value)
  625. *)
  626. PROCEDURE GetROIShift* (tile, comp : LONGINT) : LONGINT;
  627. BEGIN
  628. IF (roiShift = NIL) THEN
  629. RETURN -1;
  630. ELSE
  631. RETURN roiShift[tile][comp];
  632. END;
  633. END GetROIShift;
  634. END DecoderSpecs;
  635. (*
  636. Holds the progression state for a single tile
  637. *)
  638. ProgState = RECORD
  639. progNr : LONGINT; (* The current progression number = number of prog. changes so far *)
  640. progOrder : LONGINT; (* The progression order *)
  641. curLay : LONGINT; (* The current layer *)
  642. startLay : J2KU.LongInt2DArrayPtr;
  643. endLay : LONGINT; (* The last layer of this progression *)
  644. startRes : LONGINT; (* The resolution level to start with *)
  645. curRes : LONGINT; (* The current res. level *)
  646. endRes : LONGINT; (* The last res. level of this progression *)
  647. startComp : LONGINT; (* The component to start with *)
  648. curComp : LONGINT; (* The current component *)
  649. endComp : LONGINT; (* The last component of this progression *)
  650. curPrec : J2KU.LongInt3DArrayPtr;
  651. (* NOTE: The following state variables are not needed in the case of position-first progressions *)
  652. curX : LONGINT;
  653. curY : LONGINT;
  654. END;
  655. (*
  656. Specifies progression changes.
  657. *)
  658. ProgChange = RECORD
  659. progOrder : LONGINT; (* The progression order *)
  660. startRes : LONGINT; (* The first res. level of this progression *)
  661. startComp : LONGINT; (* The first component of this progression *)
  662. endLay : LONGINT; (* The last layer of this progression *)
  663. endRes : LONGINT; (* The last res .level of this progression *)
  664. endComp : LONGINT; (* The last component of this progression *)
  665. END;
  666. ProgChangeArrayPtr = POINTER TO ARRAY OF ProgChange;
  667. (*
  668. Used to construct a linked list of byte arrays
  669. (i.e. for packed packet headers)
  670. *)
  671. DataListElement = OBJECT
  672. VAR
  673. data : J2KU.ByteArrayPtr;
  674. next : DataListElement;
  675. END DataListElement;
  676. (*
  677. Contains information on how many code-blocks are located (entirely or partial) in
  678. a specific precinct of a specific tile, component, resolution level and subband. There will be one
  679. such record per resolution level.
  680. *)
  681. PrecinctInfo = RECORD
  682. (*
  683. 1st dim: subband (NOTE: 0 = LL at lowest resolution level; 0 = HL, 1 = LH, 2 = HH otherwise)
  684. 2nd dim.: Precinct index in the subband (in raster order)
  685. 3rd dim.: 0: Number of code-blocks in horizontal direction,
  686. 1: Number of code-blocks in vertical direction
  687. *)
  688. nblocks : POINTER TO ARRAY OF ARRAY OF ARRAY 2 OF LONGINT;
  689. nprecx : LONGINT; (* The number of precincts in horizontal direction for a specific tile, component, resolution level (per subband) *)
  690. nprecy : LONGINT; (* The number of precincts in vertical direction for a specific tile, component, resolution leve (per subband) *)
  691. END;
  692. (*
  693. Is used to decode packets contained in a JPEG2000 codestream.
  694. *)
  695. PacketDecoder = OBJECT(J2KU.BitSource)
  696. VAR
  697. cr : CodestreamReader; (* A reference to the codestream reader so we can read bytes from the stream *)
  698. curTile : LONGINT; (* The tile for which packets are decoded currently *)
  699. curByte : LONGINT; (* A buffer containing the current byte in the packet (-header) *)
  700. curBytePos : LONGINT; (* The position in the current byte buffer. 8 means the buffer is empty, 0 means we're at the beginning of the buffer *)
  701. decSpec : DecoderSpecs;(* A reference to the current decoder specification *)
  702. pph : DataListElement; (* The current data element of packed packet headers *)
  703. pphPos : LONGINT; (* The position in the data array of the current first data element *)
  704. pphTileFirstLast : POINTER TO ARRAY OF ARRAY OF DataListElement; (* The currently first/last data elements of each tile *)
  705. pphTilePos : J2KU.LongIntArrayPtr; (* The poitions in the data array of the currently first data element of each tile *)
  706. pphMainUsed : BOOLEAN; (* Indicates wether packed packet headers in the main header are used *)
  707. pphTileUsed : POINTER TO ARRAY OF BOOLEAN; (* Indicates wether packed packet headers in tile-part headers are used (for each tile separately) *)
  708. sopUsed, ephUsed : BOOLEAN; (* Indicate if SOP or EPH markers are used in the current tile *)
  709. (*
  710. Pointers to increment step arrays. That's the step from one precinct to the next one projected to the reference grid at full resolution.
  711. 1st dim: tile index
  712. 2nd dim: component
  713. 3rd dim: resolution level
  714. 4th dim: 0: x direction
  715. 1: y direction
  716. *)
  717. incStep : POINTER TO ARRAY OF ARRAY OF POINTER TO ARRAY OF ARRAY 2 OF LONGINT;
  718. (*
  719. Same as above, only that the minimal increment step over all resolution levels are stored.
  720. 1st dim: tile index
  721. 2nd dim: component
  722. 3rd dim: 0: x direction
  723. 1: y direction
  724. *)
  725. minIncStep : POINTER TO ARRAY OF ARRAY OF ARRAY 2 OF LONGINT;
  726. (*
  727. The start and end of each tile. The start index is the start index of the tile-component. The end index
  728. is the start index of the last precinct contained in the tile-component (at a particular resolution level)
  729. 1st dim: tile index
  730. 2nd dim: component
  731. 3rd dim: resolution level
  732. 4th dim: 0: x direction
  733. 1: y direction
  734. 5th dim: 0: start index
  735. 1: end index
  736. *)
  737. sotEot : POINTER TO ARRAY OF ARRAY OF POINTER TO ARRAY OF ARRAY 2, 2 OF LONGINT;
  738. (*
  739. Same as above, only that the values of the largest tile-component over all resolution levels are stored
  740. 1st dim: tile index
  741. 2nd dim: component
  742. 3rd dim: 0: x direction
  743. 1: y direction
  744. 4th dim: 0: start index
  745. 1: end index
  746. *)
  747. maxSotEot : POINTER TO ARRAY OF ARRAY OF ARRAY 2, 2 OF LONGINT;
  748. (*
  749. Pointers to tag trees (inclusion tree & zero bit-plane information tree):
  750. 1st dim: tile index
  751. 2nd dim: component
  752. 3rd dim: resolution level
  753. 4th dim: subband (NOTE: 0 = LL at lowest resolution level; 0 = HL, 1 = LH, 2 = HH otherwise)
  754. 5th dim: precinct index (in raster order)
  755. *)
  756. inclTrees : POINTER TO ARRAY OF ARRAY OF POINTER TO ARRAY OF POINTER TO ARRAY OF POINTER TO ARRAY OF J2KU.TagTree;
  757. zeroTrees : POINTER TO ARRAY OF ARRAY OF POINTER TO ARRAY OF POINTER TO ARRAY OF POINTER TO ARRAY OF J2KU.TagTree;
  758. (*
  759. Pointer to lblock for each code-block of the image:
  760. 1st dim: tile index
  761. 2nd dim: component
  762. 3rd dim: resolution level
  763. 4th dim: subband (NOTE: 0 = LL at lowest resolution level; 0 = HL, 1 = LH, 2 = HH otherwise)
  764. 5th dim: precinct index in the subband (in raster order)
  765. 6th dim: code-block index in the precinct (in raster order)
  766. *)
  767. lblock : POINTER TO ARRAY OF ARRAY OF J2KU.LongInt4DArrayPtr;
  768. (*
  769. Pointer to code-block information for each code-block of the image:
  770. 1st dim: tile index
  771. 2nd dim: component
  772. 3rd dim: resolution level
  773. 4th dim: subband (NOTE: 0 = LL at lowest resolution level; 0=HL, 1=LH, 2=HH otherwise)
  774. 5th dim: precinct index in the subband (in raster order)
  775. 6th dim : code-block index in the precinct (in raster order)
  776. *)
  777. cblkInfo : POINTER TO ARRAY OF ARRAY OF POINTER TO ARRAY OF POINTER TO ARRAY OF POINTER TO ARRAY OF POINTER TO ARRAY OF J2KU.CblkInfo;
  778. (*
  779. Pointer to precinct information for each precinct of the image
  780. 1st dim: tile index
  781. 2nd dim: component
  782. 3rd dim: resolution level
  783. *)
  784. precInfo : POINTER TO ARRAY OF ARRAY OF POINTER TO ARRAY OF PrecinctInfo;
  785. (*
  786. Creates a new PacketDecoder instance and initializes its member variables.
  787. cr: A reference to the CodestreamReader which will deliver the packet headers and data
  788. decSpec : A reference to the decoder specifications
  789. pphMain : A list of packed packet headers found in the main header of the codestream
  790. *)
  791. PROCEDURE &InitNew *( cr : CodestreamReader;
  792. decSpec : DecoderSpecs;
  793. pphMain : DataListElement);
  794. BEGIN
  795. ReInit(cr, decSpec, pphMain);
  796. END InitNew;
  797. (*
  798. Reinitializes the PacketDecoder and its member variables.
  799. cr: A reference to the CodestreamReader which will deliver the packet headers and data
  800. decSpec : A reference to the decoder specifications
  801. pphMain : A list of packed packet headers found in the main header of the codestream
  802. *)
  803. PROCEDURE ReInit ( cr : CodestreamReader;
  804. decSpec : DecoderSpecs;
  805. pphMain : DataListElement);
  806. VAR
  807. nt, ncomp : LONGINT;
  808. BEGIN
  809. SELF.cr := cr;
  810. SELF.decSpec := decSpec;
  811. curByte := 0; (* TODO : Maybe we don't need to initialize this value *)
  812. curBytePos := 0;
  813. curTile := 0; (* TODO : Maybe we don't need to initialize this value *)
  814. nt := decSpec.imgInfo.GetNumTiles();
  815. ncomp := decSpec.imgInfo.GetNumComponents();
  816. NEW(precInfo, nt, ncomp);
  817. NEW(lblock, nt, ncomp);
  818. NEW(inclTrees, nt, ncomp);
  819. NEW(zeroTrees, nt, ncomp);
  820. NEW(cblkInfo, nt, ncomp);
  821. NEW(incStep, nt, ncomp);
  822. NEW(minIncStep, nt, ncomp);
  823. NEW(sotEot, nt, ncomp);
  824. NEW(maxSotEot, nt, ncomp);
  825. IF pphMain # NIL THEN
  826. (* We create a dummy element and set the position to the end *)
  827. NEW(pph);
  828. NEW(pph.data, 1);
  829. pphPos := 1;
  830. pph.next := pphMain;
  831. pphMainUsed := TRUE;
  832. ELSE
  833. pph := NIL;
  834. pphMainUsed := FALSE;
  835. END;
  836. pphTileFirstLast := NIL;
  837. pphTileUsed := NIL;
  838. END ReInit;
  839. (*
  840. Initializes tile-specific member variables of the PacketDecoder instance to
  841. their appropriate values and sets the current tile to 't'. Usually this is done after a new tile header has been read
  842. by the CodestreamReader.
  843. t: The index of the new current tile in the reference grid
  844. *)
  845. PROCEDURE SetAndInitTile(t : LONGINT);
  846. VAR
  847. c, r, ndec : LONGINT;
  848. BEGIN
  849. BuildIncSotEotArrays(t);
  850. (* Loop on components *)
  851. FOR c := 0 TO decSpec.imgInfo.ncomp - 1 DO
  852. ndec := decSpec.cstyle[t][c].ndec;
  853. (* Instantiate new arrays for each tile-component *)
  854. NEW(precInfo[t][c], ndec + 1);
  855. NEW(lblock[t][c], ndec + 1);
  856. NEW(zeroTrees[t][c], ndec + 1);
  857. NEW(inclTrees[t][c], ndec + 1);
  858. NEW(cblkInfo[t][c], ndec + 1);
  859. (* Loop on resolution levels *)
  860. FOR r := 0 TO ndec DO
  861. (* Create precinct information *)
  862. CreatePrecinctInfo(t, c, r, precInfo[t][c][r]);
  863. (* Initialize subbands *)
  864. InitSubbands(t, c, r, precInfo[t][c][r]);
  865. END;
  866. END;
  867. SetTile(t);
  868. END SetAndInitTile;
  869. (*
  870. Sets t as new current tile
  871. *)
  872. PROCEDURE SetTile (t : LONGINT);
  873. BEGIN
  874. IF pphTileUsed # NIL THEN
  875. (* Store the packet packet headers of the previous tile (if there was one) *)
  876. IF pph # NIL THEN
  877. pphTileFirstLast[curTile][0] := pph;
  878. pphTilePos[curTile] := pphPos;
  879. END;
  880. IF pphTileUsed[t] THEN
  881. pph := pphTileFirstLast[t][0];
  882. pphPos := pphTilePos[t];
  883. ELSE
  884. pph := NIL;
  885. END;
  886. END;
  887. (* See, if we need to move on to the next chunk of packed packet headers *)
  888. IF (pph # NIL) & (pphPos >= LEN(pph.data^)) THEN
  889. pph := pph.next;
  890. pphPos := 0;
  891. END;
  892. sopUsed := decSpec.cics[t].sop;
  893. ephUsed := decSpec.cics[t].eph;
  894. SELF.curTile := t;
  895. END SetTile;
  896. (*
  897. Build helper arrays for finding precinct start & end points
  898. *)
  899. PROCEDURE BuildIncSotEotArrays (tile : LONGINT);
  900. VAR
  901. c, r, subsX, subsY, ndec, ppx, ppy, shift : LONGINT;
  902. tileCompULX, tileCompWidth, tileCompULY, tileCompHeight : LONGINT;
  903. subbInfo : J2KU.SubbandInfo;
  904. BEGIN
  905. FOR c := 0 TO decSpec.imgInfo.ncomp - 1 DO
  906. ndec := decSpec.cstyle[tile][c].ndec;
  907. (* Get the component subsampling factors *)
  908. subsX := decSpec.imgInfo.comps[c].subsx;
  909. subsY := decSpec.imgInfo.comps[c].subsy;
  910. minIncStep[tile][c][0] := MAX(LONGINT);
  911. minIncStep[tile][c][1] := MAX(LONGINT);
  912. NEW(incStep[tile][c], ndec + 1);
  913. NEW(sotEot[tile][c], ndec + 1);
  914. (* Get information on the LL band of the highest resolution level, i.e. the whole tile *)
  915. subbInfo := cr.GetSubbandInfo(tile, c, ndec, J2KU.SUB_LL);
  916. tileCompULX := subbInfo.ulcx;
  917. tileCompWidth := subbInfo.width;
  918. tileCompULY := subbInfo.ulcy;
  919. tileCompHeight := subbInfo.height;
  920. FOR r := 0 TO ndec DO
  921. (* First we handle the increment arrays *)
  922. ppx := decSpec.GetPPX(tile, c, r);
  923. ppy := decSpec.GetPPY(tile, c, r);
  924. shift := ndec - r;
  925. incStep[tile][c][r][0] := LSH(LSH(subsX, shift), ppx);
  926. IF incStep[tile][c][r][0] < minIncStep[tile][c][0] THEN
  927. minIncStep[tile][c][0] := incStep[tile][c][r][0];
  928. END;
  929. incStep[tile][c][r][1] := LSH(LSH(subsY, shift), ppy);
  930. IF incStep[tile][c][r][1] < minIncStep[tile][c][1] THEN
  931. minIncStep[tile][c][1] := incStep[tile][c][r][1];
  932. END;
  933. (* Now handle the start/end of tile array *)
  934. IF incStep[tile][c][r][0] = 0 THEN
  935. sotEot[tile][c][r][0][0] := 0;
  936. sotEot[tile][c][r][0][1] := 1;
  937. incStep[tile][c][r][0] := 1;
  938. ELSE
  939. sotEot[tile][c][r][0][0] := SYSTEM.VAL(LONGINT,
  940. SYSTEM.VAL(SET, tileCompULX)
  941. * (SYSTEM.VAL(SET, incStep[tile][c][r][0] - 1) / SYSTEM.VAL(SET, J2KU.SWAP_MASK))
  942. );
  943. sotEot[tile][c][r][0][1] := tileCompULX + tileCompWidth;
  944. END;
  945. IF incStep[tile][c][r][1] = 0 THEN
  946. sotEot[tile][c][r][1][0] := 0;
  947. sotEot[tile][c][r][1][1] := 1;
  948. incStep[tile][c][r][1] := 1;
  949. ELSE
  950. sotEot[tile][c][r][1][0] := SYSTEM.VAL(LONGINT,
  951. SYSTEM.VAL(SET, tileCompULY)
  952. * (SYSTEM.VAL(SET, incStep[tile][c][r][1] - 1) / SYSTEM.VAL(SET, J2KU.SWAP_MASK))
  953. );
  954. sotEot[tile][c][r][1][1] := tileCompULY + tileCompHeight;
  955. END;
  956. END;
  957. (*
  958. Last handle the maximum start/end of tile array, i.e. the start/end
  959. of tile for the highest resolution level and smallest increment step
  960. *)
  961. IF minIncStep[tile][c][0] = 0 THEN
  962. maxSotEot[tile][c][0][0] := 0;
  963. maxSotEot[tile][c][0][1] := 1;
  964. minIncStep[tile][c][0] := 1;
  965. ELSE
  966. maxSotEot[tile][c][0][0] := SYSTEM.VAL(LONGINT,
  967. SYSTEM.VAL(SET, tileCompULX)
  968. * (SYSTEM.VAL(SET, minIncStep[tile][c][0] - 1) / SYSTEM.VAL(SET, J2KU.SWAP_MASK))
  969. );
  970. maxSotEot[tile][c][0][1] := tileCompULX + tileCompWidth;
  971. END;
  972. IF minIncStep[tile][c][1] = 0 THEN
  973. maxSotEot[tile][c][1][0] := 0;
  974. maxSotEot[tile][c][1][1] := 1;
  975. minIncStep[tile][c][1] := 1;
  976. ELSE
  977. maxSotEot[tile][c][1][0] := SYSTEM.VAL(LONGINT,
  978. SYSTEM.VAL(SET, tileCompULY)
  979. * (SYSTEM.VAL(SET, minIncStep[tile][c][1] - 1) / SYSTEM.VAL(SET, J2KU.SWAP_MASK))
  980. );
  981. maxSotEot[tile][c][1][1] := tileCompULY + tileCompHeight;
  982. END;
  983. END;
  984. END BuildIncSotEotArrays;
  985. (*
  986. Creates and initializes a precinct information object
  987. *)
  988. PROCEDURE CreatePrecinctInfo(tile, comp, reslevel : LONGINT; VAR precInfo : PrecinctInfo);
  989. VAR
  990. incX, incY, incXR, incYR, maxSotX, maxSotY, maxEotX, maxEotY, sotX, sotY, xr, yr : LONGINT;
  991. ppx, ppy, nprecx, nprecy, nprec, curPrec, px, py, width, height : LONGINT;
  992. cblkw, cblkh : LONGINT;
  993. nband, subband : LONGINT;
  994. subbInfo : J2KU.SubbandInfo;
  995. cblkwCeil, cblkhCeil : LONGINT; (* These values are needed when we perform integer division with 'ceil' operation *)
  996. precw, prech : LONGINT; (* The width and height of the precincts (i.e. 2^ppx & 2^ppy) *)
  997. ndec : LONGINT;
  998. maxpsUsed : BOOLEAN; (* Maximum precinct size used? *)
  999. tmp : LONGINT;
  1000. BEGIN
  1001. cblkw := decSpec.cstyle[tile][comp].cblw;
  1002. cblkh := decSpec.cstyle[tile][comp].cblh;
  1003. maxpsUsed := decSpec.cstyle[tile][comp].maxps;
  1004. ndec := decSpec.cstyle[tile][comp].ndec;
  1005. ppx := decSpec.GetPPX(tile, comp, reslevel);
  1006. ppy := decSpec.GetPPY(tile, comp, reslevel);
  1007. incX := minIncStep[tile][comp][0];
  1008. incY := minIncStep[tile][comp][1];
  1009. IF reslevel = 0 THEN
  1010. IF cblkw > ppx THEN
  1011. cblkw := ppx;
  1012. END;
  1013. IF cblkh > ppy THEN
  1014. cblkh := ppy;
  1015. END;
  1016. precw := LSH(SYSTEM.VAL(LONGINT, 1), ppx);
  1017. prech := LSH(SYSTEM.VAL(LONGINT, 1), ppy);
  1018. nband := 1;
  1019. ELSE
  1020. IF cblkw > (ppx - 1) THEN
  1021. cblkw := ppx - 1;
  1022. END;
  1023. IF cblkh > (ppy - 1) THEN
  1024. cblkh := ppy - 1;
  1025. END;
  1026. (*
  1027. NOTE:
  1028. Resolution level # 0 -> precinct/packet size (in terms of samples)
  1029. must be divided by 2 since the PPX and PPY values found in the
  1030. stream refer to the LL-band that will be reconstructed from the
  1031. 3 subbands from the same and the LL-band from the next lower
  1032. resolution level
  1033. *)
  1034. precw := LSH(SYSTEM.VAL(LONGINT, 1), ppx - 1);
  1035. prech := LSH(SYSTEM.VAL(LONGINT, 1), ppy - 1);
  1036. nband := 3;
  1037. END;
  1038. (* Get the LL subband of the current resolution level *)
  1039. subbInfo := cr.GetSubbandInfo(tile, comp, reslevel, J2KU.SUB_LL);
  1040. (* Compute the number of precincts *)
  1041. IF subbInfo.width > 0 THEN
  1042. (* NOTE: Implicit 'ceil' operation is done in this division (i.e. shift) by adding [divisor - 1] to the dividend *)
  1043. tmp := LSH(subbInfo.ulcx + subbInfo.width + LSH(SYSTEM.VAL(LONGINT, 1), ppx) - 1, -ppx);
  1044. nprecx := tmp - LSH(subbInfo.ulcx, -ppx);
  1045. ELSE
  1046. nprecx := 0;
  1047. END;
  1048. IF subbInfo.height > 0 THEN
  1049. (* NOTE: Implicit 'ceil' operation is done in this division (i.e. shift) by adding [divisor - 1] to the dividend *)
  1050. tmp := LSH(subbInfo.ulcy + subbInfo.height + LSH(SYSTEM.VAL(LONGINT, 1), ppy) - 1, -ppy);
  1051. nprecy := tmp - LSH(subbInfo.ulcy, -ppy);
  1052. ELSE
  1053. nprecy := 0;
  1054. END;
  1055. nprec := nprecx * nprecy;
  1056. precInfo.nprecx := nprecx;
  1057. precInfo.nprecy := nprecy;
  1058. (* Allocate space for number-of-code-blocks information *)
  1059. NEW(precInfo.nblocks, nband, nprec);
  1060. (* Precompute values that are needed several times *)
  1061. incXR := incStep[tile][comp][reslevel][0];
  1062. incYR := incStep[tile][comp][reslevel][1];
  1063. maxSotX := maxSotEot[tile][comp][0][0];
  1064. maxSotY := maxSotEot[tile][comp][1][0];
  1065. maxEotX := maxSotEot[tile][comp][0][1];
  1066. maxEotY := maxSotEot[tile][comp][1][1];
  1067. sotX := sotEot[tile][comp][reslevel][0][0];
  1068. sotY := sotEot[tile][comp][reslevel][1][0];
  1069. cblkwCeil := LSH(SYSTEM.VAL(LONGINT, 1), cblkw) - 1;
  1070. cblkhCeil := LSH(SYSTEM.VAL(LONGINT, 1), cblkh) - 1;
  1071. (* Build the information on number of code-blocks per precinct *)
  1072. curPrec := 0;
  1073. yr := maxSotY;
  1074. WHILE yr < maxEotY DO
  1075. xr := maxSotX;
  1076. WHILE xr < maxEotX DO
  1077. (* Check wether a precinct starts at this position *)
  1078. IF ((xr = maxSotX) OR (xr MOD incXR = 0))
  1079. & ((yr = maxSotY) OR (yr MOD incYR = 0))
  1080. THEN
  1081. (* See wether the precinct's index is within the bounds *)
  1082. IF curPrec < nprec THEN
  1083. (* Here begins a new precinct *)
  1084. FOR subband := 0 TO nband - 1 DO
  1085. subbInfo := cr.GetSubbandInfo(tile, comp, reslevel, J2KU.SubbandIndexToSubband(reslevel, subband));
  1086. (* Compute the horiztontal index in the subband *)
  1087. IF (xr = maxSotX)
  1088. & (LSH(sotX, reslevel - ndec) # maxSotX)
  1089. THEN
  1090. IF reslevel = 0 THEN
  1091. px := LSH(sotX, reslevel - ndec) - subbInfo.ulcx;
  1092. ELSE
  1093. px := LSH(sotX, reslevel - ndec - 1) - subbInfo.ulcx;
  1094. END;
  1095. ELSE
  1096. IF reslevel = 0 THEN
  1097. px := LSH(xr, reslevel - ndec) - subbInfo.ulcx;
  1098. ELSE
  1099. px := LSH(xr, reslevel - ndec - 1) - subbInfo.ulcx;
  1100. END;
  1101. END;
  1102. (* Compute the vertical index in the subband *)
  1103. IF (yr = maxSotY)
  1104. & (LSH(sotY, reslevel - ndec) # maxSotY)
  1105. THEN
  1106. IF reslevel = 0 THEN
  1107. py := LSH(sotY, reslevel - ndec) - subbInfo.ulcy;
  1108. ELSE
  1109. py := LSH(sotY, reslevel - ndec - 1) - subbInfo.ulcy;
  1110. END;
  1111. ELSE
  1112. IF reslevel = 0 THEN
  1113. py := LSH(yr, reslevel - ndec) - subbInfo.ulcy;
  1114. ELSE
  1115. py := LSH(yr, reslevel - ndec - 1) - subbInfo.ulcy;
  1116. END;
  1117. END;
  1118. IF (subbInfo.width <= 0) OR (subbInfo.height <= 0)
  1119. OR (px + precw <= 0) OR (py + prech <= 0)
  1120. OR (px >= subbInfo.width) OR (py >= subbInfo.height)
  1121. THEN
  1122. precInfo.nblocks[subband][curPrec][0] := 0;
  1123. precInfo.nblocks[subband][curPrec][1] := 0;
  1124. ELSE
  1125. (* Calculate number of code-blocks in horizontal direction *)
  1126. IF px + precw > subbInfo.width THEN
  1127. width := subbInfo.width - px;
  1128. ELSE
  1129. width := precw;
  1130. END;
  1131. IF px < 0 THEN
  1132. width := width + px;
  1133. px := 0;
  1134. END;
  1135. (* NOTE: Implicit 'ceil' operation is done in the first division (i.e. shift) by adding [divisor - 1] to the dividend *)
  1136. precInfo.nblocks[subband][curPrec][0] := LSH(px + subbInfo.ulcx + width + cblkwCeil, -cblkw)
  1137. - LSH(px + subbInfo.ulcx, -cblkw);
  1138. (* Calculate number of code-blocks in vertical direction *)
  1139. IF py + prech > subbInfo.height THEN
  1140. height := subbInfo.height - py;
  1141. ELSE
  1142. height := prech;
  1143. END;
  1144. IF py < 0 THEN
  1145. height := height + py;
  1146. py := 0;
  1147. END;
  1148. (* NOTE: Implicit 'ceil' operation is done in the first division (i.e. shift) by adding [divisor - 1] to the dividend *)
  1149. precInfo.nblocks[subband][curPrec][1] := LSH(py + subbInfo.ulcy + height + cblkhCeil, -cblkh)
  1150. - LSH(py + subbInfo.ulcy , -cblkh);
  1151. END;
  1152. END; (* Loop on subbands *)
  1153. INC(curPrec);
  1154. END;
  1155. END;
  1156. INC(xr, incX);
  1157. END;
  1158. INC(yr, incY);
  1159. END;
  1160. END CreatePrecinctInfo;
  1161. (*
  1162. Initializes all state & information objects contained in the subbands of
  1163. a given tile, component & resolution level
  1164. *)
  1165. PROCEDURE InitSubbands (tile, comp, reslevel : LONGINT; VAR precInfo : PrecinctInfo);
  1166. VAR
  1167. nl : LONGINT;
  1168. nband, subband : LONGINT;
  1169. subbInfo : J2KU.SubbandInfo;
  1170. ppx, ppy, nprec, precx, nprecx, precy, nprecy, precIdx : LONGINT;
  1171. nblocks, ncblkx, ncblky, cblkIdx, cblkIdxX, cblkIdxY, cblkPrecIdx, i, j, cblkw, cblkh : LONGINT;
  1172. cblkInfoObj : J2KU.CblkInfo;
  1173. cblkStartX, cblkStartY : LONGINT; (* The start coordinates of the first code-blocks in each column/row of code-blocks in a subband *)
  1174. nomCblkw, nomCblkh : LONGINT; (* The nominal code-block width and height. These are the actual values, not just the exponents *)
  1175. tmp1, tmp2 : LONGINT;
  1176. BEGIN
  1177. nl := decSpec.cics[tile].nl;
  1178. ppx := decSpec.GetPPX(tile, comp, reslevel);
  1179. ppy := decSpec.GetPPY(tile, comp, reslevel);
  1180. cblkw := decSpec.cstyle[tile][comp].cblw;
  1181. cblkh := decSpec.cstyle[tile][comp].cblh;
  1182. IF reslevel = 0 THEN
  1183. IF cblkw > ppx THEN
  1184. cblkw := ppx;
  1185. END;
  1186. IF cblkh > ppy THEN
  1187. cblkh := ppy;
  1188. END;
  1189. nband := 1;
  1190. ELSE
  1191. IF cblkw > (ppx - 1) THEN
  1192. cblkw := ppx - 1;
  1193. END;
  1194. IF cblkh > (ppy - 1) THEN
  1195. cblkh := ppy - 1;
  1196. END;
  1197. nband := 3;
  1198. END;
  1199. nomCblkw := LSH(SYSTEM.VAL(LONGINT, 1), cblkw);
  1200. nomCblkh := LSH(SYSTEM.VAL(LONGINT, 1), cblkh);
  1201. nprecx := precInfo.nprecx;
  1202. nprecy := precInfo.nprecy;
  1203. nprec := nprecx*nprecy;
  1204. NEW(zeroTrees[tile][comp][reslevel], nband);
  1205. NEW(inclTrees[tile][comp][reslevel], nband);
  1206. NEW(lblock[tile][comp][reslevel], nband);
  1207. NEW(cblkInfo[tile][comp][reslevel], nband);
  1208. FOR subband := 0 TO nband - 1 DO
  1209. subbInfo := cr.GetSubbandInfo(tile, comp, reslevel, J2KU.SubbandIndexToSubband(reslevel, subband));
  1210. NEW(zeroTrees[tile][comp][reslevel][subband], nprec);
  1211. NEW(inclTrees[tile][comp][reslevel][subband], nprec);
  1212. NEW(lblock[tile][comp][reslevel][subband], nprec);
  1213. NEW(cblkInfo[tile][comp][reslevel][subband], nprec);
  1214. cblkIdx := 0;
  1215. precIdx := 0;
  1216. cblkStartY := LSH(LSH(subbInfo.ulcy, -cblkh), cblkh);
  1217. cblkStartX := LSH(LSH(subbInfo.ulcx, -cblkw), cblkw);
  1218. FOR precy := 0 TO nprecy - 1 DO
  1219. (*
  1220. Store the current code-block index; we will need it when
  1221. advancing to the next precinct in vertical direction
  1222. *)
  1223. tmp1 := cblkIdx;
  1224. FOR precx := 0 TO nprecx - 1 DO
  1225. ncblkx := precInfo.nblocks[subband][precIdx][0];
  1226. ncblky := precInfo.nblocks[subband][precIdx][1];
  1227. nblocks := ncblkx*ncblky;
  1228. NEW(zeroTrees[tile][comp][reslevel][subband][precIdx], ncblkx, ncblky, SELF);
  1229. NEW(inclTrees[tile][comp][reslevel][subband][precIdx], ncblkx, ncblky, SELF);
  1230. IF nblocks > 0 THEN
  1231. NEW(lblock[tile][comp][reslevel][subband][precIdx], nblocks);
  1232. NEW(cblkInfo[tile][comp][reslevel][subband][precIdx], nblocks);
  1233. Machine.Fill32(ADDRESSOF(lblock[tile][comp][reslevel][subband][precIdx][0]), nblocks*SIZEOF(LONGINT), 3);
  1234. END;
  1235. cblkPrecIdx := 0;
  1236. tmp2 := cblkIdx;
  1237. FOR i := 0 TO ncblky - 1 DO
  1238. FOR j := 0 TO ncblkx - 1 DO
  1239. NEW(cblkInfoObj);
  1240. cblkInfoObj.subbinfo := subbInfo;
  1241. cblkInfoObj.index := cblkIdx;
  1242. NEW(cblkInfoObj.cpasseslyr, nl);
  1243. NEW(cblkInfoObj.datalenlyr, nl);
  1244. cblkIdxX := cblkIdx MOD subbInfo.nblocksx;
  1245. cblkIdxY := cblkIdx DIV subbInfo.nblocksx;
  1246. (* Compute upper-left x and y coordinates of the code-block with respect to the tile-component *)
  1247. IF cblkIdxY = 0 THEN
  1248. cblkInfoObj.ulsy := subbInfo.ulsy;
  1249. ELSE
  1250. (* Compute index of first code-block in row on partition grid with origin (0,0) *)
  1251. cblkInfoObj.ulsy := cblkStartY + cblkIdxY*nomCblkh - subbInfo.ulcy + subbInfo.ulsy;
  1252. END;
  1253. IF cblkIdxX = 0 THEN
  1254. cblkInfoObj.ulsx := subbInfo.ulsx;
  1255. ELSE
  1256. (* Compute index of first code-block in row on partition grid with origin (0,0) *)
  1257. cblkInfoObj.ulsx := cblkStartX + cblkIdxX*nomCblkw - subbInfo.ulcx + subbInfo.ulsx;
  1258. END;
  1259. (* Compute code-block width and height *)
  1260. IF (cblkIdxY < subbInfo.nblocksy - 1) THEN
  1261. cblkInfoObj.height := cblkStartY + (cblkIdxY+1)*nomCblkh - subbInfo.ulcy + subbInfo.ulsy - cblkInfoObj.ulsy;
  1262. ELSE
  1263. cblkInfoObj.height := (subbInfo.ulsy + subbInfo.height) - cblkInfoObj.ulsy;
  1264. END;
  1265. IF (cblkIdxX < subbInfo.nblocksx - 1) THEN
  1266. cblkInfoObj.width := cblkStartX + (cblkIdxX+1)*nomCblkw - subbInfo.ulcx + subbInfo.ulsx - cblkInfoObj.ulsx;
  1267. ELSE
  1268. cblkInfoObj.width := (subbInfo.ulsx + subbInfo.width) - cblkInfoObj.ulsx;
  1269. END;
  1270. cblkInfo[tile][comp][reslevel][subband][precIdx][cblkPrecIdx] := cblkInfoObj;
  1271. (* Index of the next code-block *)
  1272. INC(cblkIdx);
  1273. INC(cblkPrecIdx);
  1274. END;
  1275. (*
  1276. Compute the index of the first code-block on
  1277. the next row of the current precinct. We need
  1278. to first subtract 1 from the current index since
  1279. we moved one to far
  1280. *)
  1281. cblkIdx := (cblkIdx - ncblkx) + subbInfo.nblocksx;
  1282. END;
  1283. (*
  1284. Compute the index of the code-block at the beginning
  1285. of the next precinct in horizontal direction
  1286. *)
  1287. cblkIdx := tmp2 + ncblkx;
  1288. INC(precIdx);
  1289. END;
  1290. (* Compute the index of the code-block at the beginning of the next row *)
  1291. (*
  1292. NOTE:
  1293. The implicit precondition here is that we assume that we have
  1294. at least 1 precinct in the horizontal direction. It would not make
  1295. any sense to have a vertical precinct and no horizontal one, anyway
  1296. *)
  1297. cblkIdx := tmp1 + ncblky*subbInfo.nblocksx;
  1298. END;
  1299. END;
  1300. END InitSubbands;
  1301. (*
  1302. Sets packed packet headers for a given tile
  1303. *)
  1304. PROCEDURE SetPPHeadersTile (pphNewFirst, pphNewLast : DataListElement; tile : LONGINT);
  1305. VAR
  1306. nt, i : LONGINT;
  1307. BEGIN
  1308. (* We assume that checks are done prior to a call to this procedure -> we use an assertion as 'ultima ratio' *)
  1309. ASSERT(~pphMainUsed);
  1310. IF pphTileFirstLast = NIL THEN
  1311. nt := decSpec.imgInfo.nt;
  1312. NEW(pphTileFirstLast, nt, 2);
  1313. NEW(pphTilePos, nt);
  1314. NEW(pphTileUsed, nt);
  1315. FOR i := 0 TO nt - 1 DO
  1316. pphTileUsed[i] := FALSE;
  1317. END;
  1318. END;
  1319. IF pphTileFirstLast[tile][0] = NIL THEN
  1320. pphTileFirstLast[tile][0] := pphNewFirst;
  1321. pphTileFirstLast[tile][1] := pphNewLast;
  1322. pphTilePos[tile] := 0;
  1323. pphTileUsed[tile] := TRUE;
  1324. ELSE
  1325. pphTileFirstLast[tile][1].next := pphNewFirst;
  1326. pphTileFirstLast[tile][1] := pphNewLast;
  1327. END;
  1328. END SetPPHeadersTile;
  1329. (*
  1330. TRUE, if packed packet headers in tile-part headers are used for the current tile.
  1331. *)
  1332. PROCEDURE PPHTileUsed () : BOOLEAN;
  1333. BEGIN
  1334. RETURN ((pphTileUsed # NIL) & pphTileUsed[curTile]);
  1335. END PPHTileUsed;
  1336. (*
  1337. Indicates wether there still are packed packet headers for the current tile-part (not tile).
  1338. NOTE: It is prohibited to call this procedure when the packed packet headers don't stem
  1339. from the main header of the codestream.
  1340. *)
  1341. PROCEDURE PPHMainAvailable () : BOOLEAN;
  1342. BEGIN
  1343. (* We assume that checks are done prior to a call to this procedure -> we use an assertion as 'ultima ratio' *)
  1344. ASSERT(pphMainUsed);
  1345. RETURN (pph # NIL) & (pphPos < LEN(pph.data^));
  1346. END PPHMainAvailable;
  1347. (*
  1348. Indicates wether there still are packed packet headers for the current tile
  1349. (not only for the current tile-part but also for all following tile-parts of the current tile).
  1350. NOTE: It is prohibited to call this procedure if packed
  1351. packet headers in the main header are used.
  1352. *)
  1353. PROCEDURE PPHTileAvailable () : BOOLEAN;
  1354. BEGIN
  1355. (* We assume that checks are done prior to a call to this procedure -> we use an assertion as 'ultima ratio' *)
  1356. ASSERT(~pphMainUsed);
  1357. RETURN (pph # NIL) & ((pphPos < LEN(pph.data^)) OR (pph.next # NIL));
  1358. END PPHTileAvailable;
  1359. (*
  1360. Decodes the next packet in the stream.
  1361. comp: The component to which the code-blocks in the packet belong to
  1362. reslevel: The resolution level to which the code-blocks in the packet belong to
  1363. layer: The layer to which the code-blocks in the packet belong to
  1364. precno: The precinct to which the code-blocks in the packet belong to
  1365. RETURN: The number of code-blocks for which data has been read; -1 if an error occured
  1366. *)
  1367. PROCEDURE DecodePacket (comp, reslevel, layer, precno : LONGINT; VAR cblk : ARRAY OF J2KU.CodedCblk; VAR cblkInfo : ARRAY OF J2KU.CblkInfo) : LONGINT;
  1368. VAR
  1369. blocksInPacket, i, j, bit, bitsUsed, subband, nbands, ncblx, ncbly, cblkx, cblky : LONGINT;
  1370. cblkPrecIdx, cpasses, nseg, passtype, dataLen, lastIdx : LONGINT;
  1371. inclTree, zeroTree : J2KU.TagTree;
  1372. emptyPkt, included : BOOLEAN;
  1373. cInfo : J2KU.CblkInfo;
  1374. BEGIN
  1375. (* TODO: Maybe we can place this check somewhere in the CodestreamReader *)
  1376. (* Check that precinct really exists *)
  1377. IF precno
  1378. >= (precInfo[curTile][comp][reslevel].nprecx * precInfo[curTile][comp][reslevel].nprecy)
  1379. THEN
  1380. (* Packet does not exist *)
  1381. RETURN 0;
  1382. END;
  1383. (* Check if SOP markers are used *)
  1384. IF sopUsed THEN
  1385. ReadSOP();
  1386. END;
  1387. (* Init the current byte position to 8 so that a new byte is read from the stream or packed packet headers *)
  1388. (* NOTE: We don't need to set curByte to 0, because the bit stuffing routine ensures that the last byte of the previous packet was not 0xFF *)
  1389. curBytePos := 0;
  1390. (* reslevel = 0 means we only have the NL-LL band *)
  1391. IF reslevel = 0 THEN
  1392. nbands := 1;
  1393. ELSE
  1394. nbands := 3;
  1395. END;
  1396. blocksInPacket := 0;
  1397. IF NextBit() = 0 THEN
  1398. (* No code-block is included; no more packet header data available *)
  1399. emptyPkt := TRUE;
  1400. ELSE
  1401. emptyPkt := FALSE;
  1402. END;
  1403. FOR subband := 0 TO nbands - 1 DO
  1404. inclTree := inclTrees[curTile][comp][reslevel][subband][precno];
  1405. zeroTree := zeroTrees[curTile][comp][reslevel][subband][precno];
  1406. ncblx := precInfo[curTile][comp][reslevel].nblocks[subband][precno][0];
  1407. ncbly := precInfo[curTile][comp][reslevel].nblocks[subband][precno][1];
  1408. cblkPrecIdx := 0;
  1409. FOR cblky := 0 TO ncbly - 1 DO
  1410. FOR cblkx := 0 TO ncblx - 1 DO
  1411. cInfo := SELF.cblkInfo[curTile][comp][reslevel][subband][precno][cblkPrecIdx];
  1412. (* Code-block inclusion bits *)
  1413. (* If not previously included then update tag tree else 1 bit *)
  1414. included := FALSE;
  1415. IF ~emptyPkt THEN
  1416. (* Check if current code-block is included *)
  1417. IF ~inclTree.IsValid(cblkx, cblky) THEN
  1418. IF ~inclTree.Update(cblkx, cblky, layer) THEN
  1419. (* Error occurred *)
  1420. RETURN -1;
  1421. END;
  1422. IF inclTree.IsValid(cblkx, cblky) THEN
  1423. included := TRUE;
  1424. END;
  1425. ELSE
  1426. bit := NextBit();
  1427. IF bit = 1 THEN
  1428. included := TRUE;
  1429. END;
  1430. END;
  1431. END;
  1432. IF included THEN (* Code-block is included *)
  1433. (* If code-block included for the first time then update zero-bit plane tag-tree *)
  1434. IF ~zeroTree.IsValid(cblkx, cblky) THEN
  1435. IF ~zeroTree.Update(cblkx, cblky, MAX(LONGINT)) THEN
  1436. (* Error occurred *)
  1437. RETURN -1;
  1438. END;
  1439. cInfo.zerobp := zeroTree.CurrentVal(cblkx, cblky);
  1440. cInfo.curbp := J2KU.LONGINT_BITS - 2 - cInfo.zerobp;
  1441. cInfo.truncpt := 0;
  1442. END;
  1443. (* Number of coding passes included *)
  1444. cpasses := ReadCodingPasses();
  1445. cblk[blocksInPacket].cpasses := cpasses;
  1446. INC(cInfo.truncpt, cpasses);
  1447. (* Increase of Lblock *)
  1448. bit := NextBit();
  1449. WHILE bit = 1 DO
  1450. INC(lblock[curTile][comp][reslevel][subband][precno][cblkPrecIdx]);
  1451. bit := NextBit();
  1452. END;
  1453. (* We need to see, how much (terminated) passes there are *)
  1454. IF decSpec.cstyle[curTile][comp].term THEN
  1455. (* Termination on each coding pass is used -> we have as much segments as passes *)
  1456. nseg := cpasses;
  1457. ELSIF decSpec.cstyle[curTile][comp].selcb THEN
  1458. (*
  1459. Selective arithmetic coding bypass is used -> the number of terminated passes depends
  1460. on the indices of the current passes, relativ to the passes that have been read already for
  1461. this code-block
  1462. *)
  1463. IF cInfo.truncpt <= ENTROPY_FIRST_BYPASS_IDX THEN
  1464. (* The new passes are all before the first bypass occurence *)
  1465. nseg := 1;
  1466. ELSE
  1467. nseg := 1; (* The last segment (which may be terminated or not) *)
  1468. FOR i := cInfo.truncpt - cpasses TO cInfo.truncpt - 2 DO
  1469. IF i >= ENTROPY_FIRST_BYPASS_IDX - 1 THEN
  1470. passtype := i MOD ENTROPY_NUM_PASSES;
  1471. (* passtype = 0 -> cleanup pass, passtype = 2 -> magnitude refinement pass *)
  1472. IF (passtype = 0) OR (passtype = 2) THEN
  1473. INC(nseg);
  1474. END;
  1475. END;
  1476. END;
  1477. END;
  1478. ELSE
  1479. (* Only one single segment *)
  1480. nseg := 1;
  1481. END;
  1482. cblk[blocksInPacket].nseg := nseg;
  1483. (* Length of codeword segments *)
  1484. IF nseg = 1 THEN
  1485. bitsUsed := lblock[curTile][comp][reslevel][subband][precno][cblkPrecIdx] + J2KU.Log2Floor(cpasses);
  1486. cblk[blocksInPacket].dataLen := NextBits(bitsUsed);
  1487. ELSE
  1488. (* Multiple segments used *)
  1489. NEW(cblk[blocksInPacket].segLen, nseg);
  1490. dataLen := 0;
  1491. IF decSpec.cstyle[curTile][comp].term THEN
  1492. (* Termination on each coding pass is used *)
  1493. FOR i := 0 TO nseg - 1 DO
  1494. (* NOTE: Log2Floor(passes) = 0, since passes = 1 *)
  1495. bitsUsed := lblock[curTile][comp][reslevel][subband][precno][cblkPrecIdx];
  1496. cblk[blocksInPacket].segLen[i] := NextBits(bitsUsed);
  1497. INC(dataLen, cblk[blocksInPacket].segLen[i]);
  1498. END;
  1499. ELSIF decSpec.cstyle[curTile][comp].selcb THEN
  1500. (* Selective arithmetic coding bypass is used *)
  1501. j := 0;
  1502. lastIdx := cInfo.truncpt - cpasses - 1;
  1503. FOR i := cInfo.truncpt - cpasses TO cInfo.truncpt - 2 DO
  1504. IF i >= ENTROPY_FIRST_BYPASS_IDX - 1 THEN
  1505. passtype := i MOD ENTROPY_NUM_PASSES;
  1506. (* passtype = 1 -> significance propagation pass -> skip *)
  1507. IF passtype # 1 THEN
  1508. bitsUsed := lblock[curTile][comp][reslevel][subband][precno][cblkPrecIdx] + J2KU.Log2Floor(i - lastIdx);
  1509. cblk[blocksInPacket].segLen[j] := NextBits(bitsUsed);
  1510. INC(dataLen, cblk[blocksInPacket].segLen[j]);
  1511. INC(j);
  1512. lastIdx := i;
  1513. END;
  1514. END;
  1515. END;
  1516. (* Last included pass *)
  1517. bitsUsed := lblock[curTile][comp][reslevel][subband][precno][cblkPrecIdx] + J2KU.Log2Floor(i - lastIdx);
  1518. cblk[blocksInPacket].segLen[j] := NextBits(bitsUsed);
  1519. INC(dataLen, cblk[blocksInPacket].segLen[j]);
  1520. END;
  1521. (* Set the dataLen field of the current code-block *)
  1522. cblk[blocksInPacket].dataLen := dataLen;
  1523. END;
  1524. ELSE (* Code-block is not included *)
  1525. cblk[blocksInPacket].segLen := NIL;
  1526. cblk[blocksInPacket].dataLen := 0;
  1527. cblk[blocksInPacket].cpasses := 0;
  1528. END;
  1529. cblkInfo[blocksInPacket] := cInfo;
  1530. (* Update layer-dependent information *)
  1531. IF layer = 0 THEN
  1532. cInfo.cpasseslyr[layer] := cblk[blocksInPacket].cpasses;
  1533. cInfo.datalenlyr[layer] := cblk[blocksInPacket].dataLen;
  1534. ELSE
  1535. cInfo.cpasseslyr[layer] := cblk[blocksInPacket].cpasses + cInfo.cpasseslyr[layer - 1];
  1536. cInfo.datalenlyr[layer] := cblk[blocksInPacket].dataLen + cInfo.datalenlyr[layer - 1];
  1537. END;
  1538. INC(blocksInPacket);
  1539. INC(cblkPrecIdx);
  1540. END;
  1541. END;
  1542. END;
  1543. (*
  1544. The specification states that a packet header must not end
  1545. with a 0xFF byte. If the last byte of data is 0xFF, the encoder ought
  1546. to have inserted a 0 bit a the beginning of the next byte (as usual).
  1547. This last byte then contains only the stuffed 0 bit, the remaining bits
  1548. are meaningless.
  1549. *)
  1550. IF curByte = 0FFH THEN
  1551. curByte := NextByte();
  1552. END;
  1553. (* Check wether EPH markers have been used *)
  1554. IF ephUsed THEN
  1555. ReadEPH();
  1556. END;
  1557. (* Internalize code-block data *)
  1558. FOR i := 0 TO blocksInPacket - 1 DO
  1559. IF cblk[i].dataLen > 0 THEN
  1560. NEW(cblk[i].data, cblk[i].dataLen);
  1561. cr.ReadBytes(cblk[i].data^, cblk[i].dataLen);
  1562. cblk[i].dataOffset := 0;
  1563. END;
  1564. END;
  1565. RETURN blocksInPacket;
  1566. END DecodePacket;
  1567. PROCEDURE ReadCodingPasses() : LONGINT;
  1568. VAR
  1569. buf : LONGINT;
  1570. BEGIN
  1571. buf := NextBit();
  1572. IF buf = 0 THEN
  1573. RETURN 1;
  1574. END;
  1575. buf := NextBit();
  1576. IF buf = 0 THEN
  1577. RETURN 2;
  1578. END;
  1579. buf := NextBits(2);
  1580. IF buf < 00000003H THEN
  1581. RETURN 3 + buf;
  1582. END;
  1583. buf := NextBits(5);
  1584. IF buf < 0000001FH THEN
  1585. RETURN 6 + buf;
  1586. END;
  1587. buf := NextBits(7);
  1588. RETURN 37 + buf;
  1589. END ReadCodingPasses;
  1590. PROCEDURE GetNumPrecincts(comp, reslevel : LONGINT) : LONGINT;
  1591. BEGIN
  1592. RETURN precInfo[curTile][comp][reslevel].nprecx * precInfo[curTile][comp][reslevel].nprecy;
  1593. END GetNumPrecincts;
  1594. (*
  1595. Returns the maximum number of code-blocks in a packet for the current tile
  1596. (i.e. maximum over all components and resolution levels for the current tile)
  1597. *)
  1598. PROCEDURE GetMaxNumCodeblocksPkt() : LONGINT;
  1599. VAR
  1600. ncomp, nprec, ndec, maxCblks, curCblks : LONGINT;
  1601. i, r, k : LONGINT;
  1602. BEGIN
  1603. ncomp := decSpec.imgInfo.GetNumComponents();
  1604. (* Initialize maximum to 0 *)
  1605. maxCblks := 0;
  1606. FOR i := 0 TO ncomp - 1 DO
  1607. (* Go over all resolution levels *)
  1608. (* First resoltion level (0) *)
  1609. nprec := precInfo[curTile][i][0].nprecx * precInfo[curTile][i][0].nprecy;
  1610. (* Loop over precincts *)
  1611. FOR k := 0 TO nprec - 1 DO
  1612. (* There's only the LL band *)
  1613. curCblks := precInfo[curTile][i][0].nblocks[0][k][0] * precInfo[curTile][i][0].nblocks[0][k][1];
  1614. IF curCblks > maxCblks THEN
  1615. maxCblks := curCblks;
  1616. END;
  1617. END;
  1618. (* Loop over remaining resolution levels *)
  1619. ndec := decSpec.GetNumDecLevels(curTile, i);
  1620. FOR r := 1 TO ndec DO
  1621. nprec := precInfo[curTile][i][r].nprecx * precInfo[curTile][i][r].nprecy;
  1622. (* Loop over precincts *)
  1623. FOR k := 0 TO nprec - 1 DO
  1624. (* We have the HL, LH and HH subbands *)
  1625. curCblks := precInfo[curTile][i][r].nblocks[0][k][0] * precInfo[curTile][i][r].nblocks[0][k][1]
  1626. + precInfo[curTile][i][r].nblocks[1][k][0] * precInfo[curTile][i][r].nblocks[1][k][1]
  1627. + precInfo[curTile][i][r].nblocks[2][k][0] * precInfo[curTile][i][r].nblocks[2][k][1];
  1628. IF curCblks > maxCblks THEN
  1629. maxCblks := curCblks;
  1630. END;
  1631. END;
  1632. END;
  1633. END;
  1634. RETURN maxCblks;
  1635. END GetMaxNumCodeblocksPkt;
  1636. (*
  1637. Returns the code-block information object for the code-block located
  1638. in component 'comp', resolution level 'reslevel', subband 'subband' and
  1639. having code-block index 'cblkSubbIdx' within the subband.
  1640. *)
  1641. PROCEDURE GetCblkInfo (comp, reslevel, subband, cblkSubbIdx : LONGINT) : J2KU.CblkInfo;
  1642. VAR
  1643. lastIdx, cblkPrecIdx, cblkPrecIdxX, cblkPrecIdxY : LONGINT;
  1644. nprecx, precIdx, precMin, precMax, precX, precY, precFirstInRowIdx : LONGINT;
  1645. subbIdx, cblkSubbIdxX, cblkSubbIdxY, cblkInfoUpLeftIdx, cblkInfoLowRightIdx : LONGINT;
  1646. subbInfo : J2KU.SubbandInfo;
  1647. BEGIN
  1648. nprecx := precInfo[curTile][comp][reslevel].nprecx;
  1649. subbIdx := J2KU.SubbandToSubbandIndex(subband);
  1650. subbInfo := cr.GetSubbandInfo(curTile, comp, reslevel, subband);
  1651. (* Get the y and x indices of the code-block in the subband *)
  1652. cblkSubbIdxX := cblkSubbIdx MOD subbInfo.nblocksx;
  1653. cblkSubbIdxY := cblkSubbIdx DIV subbInfo.nblocksx;
  1654. (* Search for x index of precinct in which the code-block is located *)
  1655. (* -> Binary search *)
  1656. precMin := 0;
  1657. precMax := nprecx - 1;
  1658. precX := ASH(precMax + precMin, -1);
  1659. LOOP
  1660. IF precMax <= precMin THEN EXIT END;
  1661. (* Get the index of the first code-block in the precinct, i.e. the code-block at the upper left corner of the precinct *)
  1662. cblkInfoUpLeftIdx := cblkInfo[curTile][comp][reslevel][subbIdx][precX][0].index;
  1663. (* Get the index of the last code-block in the precinct, i.e. the code-block at the lower right corner of the precinct *)
  1664. lastIdx := LEN(cblkInfo[curTile][comp][reslevel][subbIdx][precX]^) - 1;
  1665. cblkInfoLowRightIdx := cblkInfo[curTile][comp][reslevel][subbIdx][precX][lastIdx].index;
  1666. IF (cblkInfoUpLeftIdx MOD subbInfo.nblocksx) > cblkSubbIdxX THEN
  1667. (* Searched precinct has lower x index *)
  1668. precMax := precX - 1;
  1669. ELSIF (cblkInfoLowRightIdx MOD subbInfo.nblocksx) < cblkSubbIdxX THEN
  1670. (* Searched precinct has higher x index *)
  1671. precMin := precX + 1;
  1672. ELSE
  1673. (* We have the correct x index of the precinct *)
  1674. EXIT;
  1675. END;
  1676. precX := ASH(precMax + precMin, -1);
  1677. END;
  1678. (* Search for y index (within subband) of precinct *)
  1679. precMin := 0;
  1680. precMax := precInfo[curTile][comp][reslevel].nprecy - 1;
  1681. precY := ASH(precMax + precMin, -1);
  1682. precFirstInRowIdx := ASH(precMax + precMin, -1)*nprecx;
  1683. LOOP
  1684. IF precMax <= precMin THEN EXIT END;
  1685. (* Get the index of the first code-block in the precinct, i.e. the code-block at the upper left corner of the precinct *)
  1686. cblkInfoUpLeftIdx := cblkInfo[curTile][comp][reslevel][subbIdx][precFirstInRowIdx][0].index;
  1687. (* Get the index of the last code-block in the precinct, i.e. the code-block at the lower right corner of the precinct *)
  1688. lastIdx := LEN(cblkInfo[curTile][comp][reslevel][subbIdx][precFirstInRowIdx]^) - 1;
  1689. cblkInfoLowRightIdx := cblkInfo[curTile][comp][reslevel][subbIdx][precFirstInRowIdx][lastIdx].index;
  1690. IF (cblkInfoUpLeftIdx DIV subbInfo.nblocksx) > cblkSubbIdxY THEN
  1691. (* Searched precinct has lower y index *)
  1692. precMax := precY - 1;
  1693. ELSIF (cblkInfoLowRightIdx DIV subbInfo.nblocksx) < cblkSubbIdxY THEN
  1694. (* Searched precinct has higher y index *)
  1695. precMin := precY + 1;
  1696. ELSE
  1697. (* We have the correct x index of the precinct *)
  1698. EXIT;
  1699. END;
  1700. precY := ASH(precMax + precMin, -1);
  1701. precFirstInRowIdx := ASH(precMax + precMin, -1)*nprecx;
  1702. END;
  1703. precIdx := precFirstInRowIdx + precX;
  1704. (* Now compute the code-block index within the precinct *)
  1705. cblkInfoUpLeftIdx := cblkInfo[curTile][comp][reslevel][subbIdx][precIdx][0].index;
  1706. cblkPrecIdxX := cblkSubbIdxX - (cblkInfoUpLeftIdx MOD subbInfo.nblocksx);
  1707. cblkPrecIdxY := cblkSubbIdxY - (cblkInfoUpLeftIdx DIV subbInfo.nblocksx);
  1708. cblkPrecIdx := cblkPrecIdxY*precInfo[curTile][comp][reslevel].nblocks[subbIdx][precIdx][0] + cblkPrecIdxX;
  1709. RETURN cblkInfo[curTile][comp][reslevel][subbIdx][precIdx][cblkPrecIdx];
  1710. END GetCblkInfo;
  1711. PROCEDURE GetIncStep (comp, reslevel : LONGINT; VAR xStep, yStep : LONGINT);
  1712. BEGIN
  1713. xStep := incStep[curTile][comp][reslevel][0];
  1714. yStep := incStep[curTile][comp][reslevel][1];
  1715. END GetIncStep;
  1716. PROCEDURE GetMinIncStep (comp : LONGINT; VAR xStep, yStep : LONGINT);
  1717. BEGIN
  1718. xStep := minIncStep[curTile][comp][0];
  1719. yStep := minIncStep[curTile][comp][1];
  1720. END GetMinIncStep;
  1721. PROCEDURE GetSotEot (comp, reslevel : LONGINT; VAR sotX, eotX, sotY, eotY : LONGINT);
  1722. BEGIN
  1723. sotX := sotEot[curTile][comp][reslevel][0][0];
  1724. eotX := sotEot[curTile][comp][reslevel][0][1];
  1725. sotY := sotEot[curTile][comp][reslevel][1][0];
  1726. eotY := sotEot[curTile][comp][reslevel][1][1];
  1727. END GetSotEot;
  1728. PROCEDURE GetMaxSotEot (comp : LONGINT; VAR sotX, eotX, sotY, eotY : LONGINT);
  1729. BEGIN
  1730. sotX := maxSotEot[curTile][comp][0][0];
  1731. eotX := maxSotEot[curTile][comp][0][1];
  1732. sotY := maxSotEot[curTile][comp][1][0];
  1733. eotY := maxSotEot[curTile][comp][1][1];
  1734. END GetMaxSotEot;
  1735. PROCEDURE ReadSOP;
  1736. VAR
  1737. marker : LONGINT;
  1738. tmpBytes : ARRAY 6 OF CHAR;
  1739. BEGIN
  1740. (* See, if the marker is used *)
  1741. marker := cr.Peek16();
  1742. IF marker = SOP THEN
  1743. (* Marker is used -> Skip the next 6 bytes *)
  1744. (* NOTE: We don't do any checks *)
  1745. cr.ReadBytes(tmpBytes, 6);
  1746. END;
  1747. END ReadSOP;
  1748. PROCEDURE ReadEPH;
  1749. VAR
  1750. marker : LONGINT;
  1751. tmpBytes : ARRAY 2 OF CHAR;
  1752. BEGIN
  1753. IF (pph # NIL) & ((LEN(pph.data^) - pphPos) >= 2) THEN
  1754. marker := SYSTEM.VAL(LONGINT,
  1755. SYSTEM.VAL(SET, LSH(LONG(ORD(pph.data[pphPos])), 8))
  1756. + SYSTEM.VAL(SET, LONG(ORD(pph.data[pphPos + 1])))
  1757. );
  1758. IF marker = EPH THEN
  1759. INC(pphPos, 2);
  1760. END;
  1761. ELSE
  1762. marker := cr.Peek16();
  1763. IF marker = EPH THEN
  1764. (* Marker is used -> Skip the next 2 bytes *)
  1765. (* NOTE: We don't do any checks *)
  1766. cr.ReadBytes(tmpBytes, 2);
  1767. END;
  1768. END;
  1769. END ReadEPH;
  1770. PROCEDURE NextByte () : LONGINT;
  1771. VAR
  1772. byte8 : CHAR;
  1773. BEGIN
  1774. IF pph # NIL THEN
  1775. IF pphPos >= LEN(pph.data^) THEN
  1776. pph := pph.next;
  1777. IF pph = NIL THEN
  1778. KernelLog.String("ERROR (PacketDecoder.NextByte) : No more data available from packed packet headers");
  1779. KernelLog.Ln();
  1780. RETURN -1;
  1781. END;
  1782. pphPos := 0;
  1783. END;
  1784. INC(pphPos);
  1785. RETURN ORD(pph.data[pphPos - 1]);
  1786. ELSE
  1787. cr.ReadByte(byte8);
  1788. RETURN ORD(byte8);
  1789. END;
  1790. END NextByte;
  1791. (*
  1792. Reads the next bit in the stream (i.e. the next bit in the buffer which contains the
  1793. most recently read "stream byte". Bit unstuffing is performed, where necessary.
  1794. *)
  1795. PROCEDURE NextBit*() : LONGINT;
  1796. BEGIN
  1797. IF curBytePos = 0 THEN
  1798. (* Do bit unstuffing? *)
  1799. IF curByte = 0FFH THEN
  1800. curBytePos := 7;
  1801. ELSE
  1802. curBytePos := 8;
  1803. END;
  1804. curByte := NextByte();
  1805. END;
  1806. DEC(curBytePos);
  1807. RETURN SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(curByte, -curBytePos)) * {0} );
  1808. END NextBit;
  1809. (*
  1810. Reads the next bits in the stream (i.e. the next bits from the stream).
  1811. At most 32 bits may be read. Bit unstuffing is performed, where necessary.
  1812. *)
  1813. PROCEDURE NextBits (n : LONGINT) : LONGINT;
  1814. VAR
  1815. result : LONGINT;
  1816. BEGIN
  1817. IF n <= curBytePos THEN
  1818. DEC(curBytePos, n);
  1819. RETURN SYSTEM.VAL(LONGINT,
  1820. SYSTEM.VAL(SET, LSH(curByte, -curBytePos))
  1821. * SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), n) - 1)
  1822. );
  1823. ELSE
  1824. result := 0;
  1825. REPEAT
  1826. result := SYSTEM.VAL(LONGINT,
  1827. SYSTEM.VAL(SET, LSH(result, curBytePos))
  1828. + (
  1829. SYSTEM.VAL(SET, curByte)
  1830. * SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), curBytePos) - 1)
  1831. )
  1832. );
  1833. DEC(n, curBytePos);
  1834. (* Do bit unstuffing? *)
  1835. IF curByte = 0FFH THEN
  1836. curBytePos := 7;
  1837. ELSE
  1838. curBytePos := 8;
  1839. END;
  1840. curByte := NextByte();
  1841. UNTIL n <= curBytePos;
  1842. DEC(curBytePos, n);
  1843. result := SYSTEM.VAL(LONGINT,
  1844. SYSTEM.VAL(SET, LSH(result, n))
  1845. + SYSTEM.VAL(SET, LSH(curByte, -curBytePos))
  1846. );
  1847. RETURN result;
  1848. END;
  1849. END NextBits;
  1850. END PacketDecoder;
  1851. CodestreamReader* = OBJECT
  1852. VAR
  1853. s : Streams.Reader; (* A reference to the stream containing the JPEG2000 codestream *)
  1854. ntp : LONGINT; (* The number of tile-parts found in the stream (including the current part) *)
  1855. ntilePartsRead : J2KU.LongIntArrayPtr; (* The number of tile-parts found in the stream, for each tile *)
  1856. ntilePartsAvailable : J2KU.LongIntArrayPtr; (* The number of tile-parts for each tile as signalled in by a TNSot parameter of a SOT segment of at least one tile-part *)
  1857. curTile : LONGINT; (* The index of the current tile for which data is being read *)
  1858. curPart : LONGINT; (* The index of the current tile-part of curTile for which data is being read *)
  1859. partRem : LONGINT; (* Number of bytes remaining in the current tile-part *)
  1860. initError : BOOLEAN; (* TRUE if an error occured during initialization *)
  1861. pktDec : PacketDecoder; (* The packet decoder used to extract encoded code-block data *)
  1862. cblkBuf : POINTER TO ARRAY OF J2KU.CodedCblk; (* Buffer for coded code-blocks obtained from the packed decoder *)
  1863. cblkInfoBuf : POINTER TO ARRAY OF J2KU.CblkInfo;
  1864. cblkBufSize : LONGINT;
  1865. ncblkInBuf : LONGINT;
  1866. cblkBufPos : LONGINT;
  1867. endOfCS : BOOLEAN;
  1868. curMarker : LONGINT;
  1869. (*
  1870. Subband information objects
  1871. 1st dim: tile index
  1872. 2nd dim: component index
  1873. 3rd dim: subbands in order (from lowest to highes resolution level, always 4 subbands: LL, HL, LH, HH, in that order)
  1874. *)
  1875. subbInfos : POINTER TO ARRAY OF ARRAY OF POINTER TO ARRAY OF J2KU.SubbandInfo;
  1876. decSpec : DecoderSpecs;
  1877. ppmUsed : BOOLEAN; (* True if packed packet headers in the main header are used *)
  1878. buf8 : LONGINT;
  1879. buf8Valid : BOOLEAN;
  1880. (*
  1881. Pointers to progression order changes
  1882. 1st dim: tile index
  1883. 2nd dim: progression change
  1884. *)
  1885. progChanges : POINTER TO ARRAY OF ProgChangeArrayPtr;
  1886. (*
  1887. References to current progression state of each tile:
  1888. 1st dim: tile index
  1889. *)
  1890. progStates : POINTER TO ARRAY OF ProgState;
  1891. curLay, curComp, curRes : LONGINT;
  1892. (*
  1893. Current precinct(s) for which packets are being received.
  1894. 1st dim: component
  1895. 2nd dim: resolution level
  1896. 3rd dim: layer
  1897. *)
  1898. curPrec : J2KU.LongInt3DArrayPtr;
  1899. lmin : J2KU.LongInt2DArrayPtr;
  1900. lmax, cmax, rmax, rmin, cmin : LONGINT;
  1901. curX, curY, incX, incY : LONGINT;
  1902. xmax, ymax, xmin, ymin : LONGINT;
  1903. progOrder : LONGINT;
  1904. maxStartLayer, maxEndLayer : LONGINT;
  1905. startLayer, endLayer : LONGINT;
  1906. maxStartDecLvl, maxEndDecLvl : LONGINT;
  1907. startDecLvl, endDecLvl : LONGINT;
  1908. (* If TRUE, tile-part and main headers will be printed (to a certain extent) *)
  1909. printCSInfo : BOOLEAN;
  1910. (* If TRUE, comments found in COM segments will be printed *)
  1911. printCOM : BOOLEAN;
  1912. (*
  1913. Initializes an instance of a JPEG2000-Codestream-Reader.
  1914. The main header is already read here.
  1915. NOTE: The constructor actually just makes a call to the re-initialization method.
  1916. crOpt : The codestream reader options
  1917. stream : The raw byte stream
  1918. *)
  1919. PROCEDURE &InitNew* (crOpt : J2KU.CodestreamReaderOptions;
  1920. stream : Streams.Reader);
  1921. BEGIN
  1922. pktDec := NIL;
  1923. ReInit(crOpt, stream);
  1924. END InitNew;
  1925. (**
  1926. Re-Initializes the JPEG2000-Codestream-Reader.
  1927. The main header is read here.
  1928. crOpt : The codestream reader options
  1929. stream : The raw byte stream
  1930. *)
  1931. PROCEDURE ReInit* (crOpt : J2KU.CodestreamReaderOptions;
  1932. stream : Streams.Reader);
  1933. VAR
  1934. ok : BOOLEAN;
  1935. nt, ncomp, comp, i, j : LONGINT;
  1936. markerStr : ARRAY 8 OF CHAR;
  1937. nppmLeft, nppmRead : LONGINT;
  1938. ppmFirst, ppmLast : DataListElement;
  1939. ncod, nqcd, npoc, ncrg : LONGINT; (* Counter variables used for constraint checking *)
  1940. ncoc, nqcc, nrgn : J2KU.LongIntArrayPtr;
  1941. changes : ProgChangeArrayPtr;
  1942. cstyle : CodingStyle;
  1943. cics : CICodingStyle;
  1944. quant : Quantization;
  1945. imgInfo : ImageInfo;
  1946. roiShift : LONGINT;
  1947. BEGIN
  1948. s := stream;
  1949. curMarker := s.Net16();
  1950. printCOM := crOpt.printComments;
  1951. IF curMarker # SOC THEN
  1952. KernelLog.String("ERROR (CodestreamReader.InitNew): Unexpected/Invalid marker found at beginning of codestream (");
  1953. MarkerToString(curMarker, markerStr);
  1954. KernelLog.String(markerStr);
  1955. KernelLog.String(")");
  1956. KernelLog.Ln();
  1957. initError := TRUE;
  1958. RETURN;
  1959. END;
  1960. curMarker := s.Net16();
  1961. IF curMarker # SIZ THEN
  1962. KernelLog.String("ERROR: Unexpected/Invalid marker found at beginning of main header (");
  1963. MarkerToString(curMarker, markerStr);
  1964. KernelLog.String(markerStr);
  1965. KernelLog.String(")");
  1966. KernelLog.Ln();
  1967. initError := TRUE;
  1968. RETURN;
  1969. END;
  1970. ok := ReadSIZSegment(imgInfo);
  1971. IF ok THEN
  1972. (* Initialize local variables *)
  1973. nt := imgInfo.nt;
  1974. ncomp := imgInfo.ncomp;
  1975. ncod := 0;
  1976. nqcd := 0;
  1977. npoc := 0;
  1978. ncrg := 0;
  1979. NEW(ncoc, ncomp);
  1980. NEW(nqcc, ncomp);
  1981. NEW(nrgn, ncomp);
  1982. Machine.Fill32(ADDRESSOF(ncoc[0]), imgInfo.ncomp*SIZEOF(LONGINT), 0);
  1983. Machine.Fill32(ADDRESSOF(nqcc[0]), imgInfo.ncomp*SIZEOF(LONGINT), 0);
  1984. Machine.Fill32(ADDRESSOF(nrgn[0]), imgInfo.ncomp*SIZEOF(LONGINT), 0);
  1985. nppmLeft := 0;
  1986. nppmRead := 0;
  1987. ppmFirst := NIL;
  1988. ppmLast := NIL;
  1989. (* Initialize member variables needed soon *)
  1990. ppmUsed := FALSE;
  1991. progChanges := NIL;
  1992. (* Now the image information is available and we may allocate the space needed *)
  1993. NEW(decSpec);
  1994. decSpec.imgInfo := imgInfo;
  1995. NEW(decSpec.cstyle, nt, ncomp);
  1996. NEW(decSpec.cics, nt);
  1997. NEW(decSpec.quant, nt, ncomp);
  1998. NEW(decSpec.roiShift, nt, ncomp);
  1999. Machine.Fill32(ADDRESSOF(decSpec.roiShift[0][0]), nt*ncomp*SIZEOF(LONGINT), -1);
  2000. curMarker := s.Net16();
  2001. END;
  2002. WHILE ok & (curMarker # SOT) DO
  2003. CASE curMarker OF
  2004. | COD :
  2005. ok := ReadCODSegment(cstyle, cics);
  2006. FOR i := 0 TO nt - 1 DO
  2007. decSpec.cics[i] := cics;
  2008. FOR j := 0 TO ncomp - 1 DO
  2009. IF ncoc[j] = 0 THEN
  2010. decSpec.cstyle[i][j] := cstyle;
  2011. END;
  2012. END;
  2013. END;
  2014. INC(ncod);
  2015. | COC :
  2016. ok := ReadCOCSegment(cstyle, comp);
  2017. (* We need to add the check here, since 'comp' could be beyond of the valid range *)
  2018. IF ok THEN
  2019. (* This is the default coding style for this component (for all tiles) *)
  2020. FOR i := 0 TO nt - 1 DO
  2021. decSpec.cstyle[i][comp] := cstyle;
  2022. END;
  2023. INC(ncoc[comp]);
  2024. END;
  2025. | RGN :
  2026. ok := ReadRGNSegment(roiShift, comp);
  2027. (* We need to add the check here, since 'comp' could be beyond of the valid range *)
  2028. IF ok THEN
  2029. FOR i := 0 TO nt - 1 DO
  2030. decSpec.roiShift[i][comp] := roiShift;
  2031. END;
  2032. INC(nrgn[comp]);
  2033. END;
  2034. | QCD :
  2035. ok := ReadQCDSegment(quant);
  2036. FOR i := 0 TO nt - 1 DO
  2037. FOR j := 0 TO ncomp - 1 DO
  2038. IF nqcc[j] = 0 THEN
  2039. decSpec.quant[i][j] := quant;
  2040. END;
  2041. END;
  2042. END;
  2043. INC(nqcd);
  2044. | QCC :
  2045. ok := ReadQCCSegment(quant, comp);
  2046. (* We need to add the check here, since 'comp' could be beyond of the valid range *)
  2047. IF ok THEN
  2048. (* This is the default quantization for this component (for all tiles) *)
  2049. FOR i := 0 TO nt - 1 DO
  2050. decSpec.quant[i][comp] := quant;
  2051. END;
  2052. INC(nqcc[comp]);
  2053. END;
  2054. | POC :
  2055. ok := ReadPOCSegment(changes);
  2056. NEW(progChanges, nt);
  2057. FOR i := 0 TO nt - 1 DO
  2058. progChanges[i] := changes;
  2059. END;
  2060. INC(npoc);
  2061. | TLM :
  2062. ok := ReadTLMSegment();
  2063. | PLM :
  2064. ok := ReadPLMSegment();
  2065. | PPM :
  2066. ok := ReadPPMSegment(ppmFirst, ppmLast, nppmLeft, nppmRead);
  2067. ppmUsed := TRUE;
  2068. | CRG :
  2069. ok := ReadCRGSegment();
  2070. INC(ncrg);
  2071. | COM :
  2072. ok := ReadCOMSegment();
  2073. ELSE
  2074. KernelLog.String("ERROR: Unexpected/Invalid marker found in main header (");
  2075. MarkerToString(curMarker, markerStr);
  2076. KernelLog.String(markerStr);
  2077. KernelLog.String(")");
  2078. KernelLog.Ln();
  2079. ok := FALSE;
  2080. END;
  2081. curMarker := s.Net16();
  2082. END;
  2083. IF ok THEN
  2084. (* Constraint checks *)
  2085. IF ncod # 1 THEN
  2086. KernelLog.String("ERROR: Found ");
  2087. KernelLog.Int(ncod, 0);
  2088. KernelLog.String(" COD segments in main header (exactly 1 required)");
  2089. KernelLog.Ln();
  2090. ok := FALSE;
  2091. END;
  2092. IF nqcd # 1 THEN
  2093. KernelLog.String("ERROR: Found ");
  2094. KernelLog.Int(nqcd, 0);
  2095. KernelLog.String(" QCD segments in main header (exactly 1 required)");
  2096. KernelLog.Ln();
  2097. ok := FALSE;
  2098. END;
  2099. IF npoc > 1 THEN
  2100. KernelLog.String("ERROR: Found ");
  2101. KernelLog.Int(npoc, 0);
  2102. KernelLog.String(" POC segments in main header (at most 1 allowed)");
  2103. KernelLog.Ln();
  2104. ok := FALSE;
  2105. END;
  2106. IF ncrg > 1 THEN
  2107. KernelLog.String("ERROR: Found ");
  2108. KernelLog.Int(ncrg, 0);
  2109. KernelLog.String(" CRG segments in main header (at most 1 allowed)");
  2110. KernelLog.Ln();
  2111. ok := FALSE;
  2112. END;
  2113. (* Check cardinality constraints of component-specific segments *)
  2114. FOR i := 0 TO ncomp - 1 DO
  2115. IF ncoc[i] > 1 THEN
  2116. KernelLog.String("ERROR: Found ");
  2117. KernelLog.Int(ncoc[i], 0);
  2118. KernelLog.String(" COC segments for component ");
  2119. KernelLog.Int(i, 0);
  2120. KernelLog.String(" in main header (at most 1 per component allowed)");
  2121. KernelLog.Ln();
  2122. ok := FALSE;
  2123. END;
  2124. IF nqcc[i] > 1 THEN
  2125. KernelLog.String("ERROR: Found ");
  2126. KernelLog.Int(nqcc[i], 0);
  2127. KernelLog.String(" QCC segments for component ");
  2128. KernelLog.Int(i, 0);
  2129. KernelLog.String(" in main header (at most 1 per component allowed)");
  2130. KernelLog.Ln();
  2131. ok := FALSE;
  2132. END;
  2133. IF nrgn[i] > 1 THEN
  2134. KernelLog.String("ERROR: Found ");
  2135. KernelLog.Int(nrgn[i], 0);
  2136. KernelLog.String(" RGN segments for component ");
  2137. KernelLog.Int(i, 0);
  2138. KernelLog.String(" in main header (at most 1 per component allowed)");
  2139. KernelLog.Ln();
  2140. ok := FALSE;
  2141. END;
  2142. END;
  2143. END;
  2144. IF ok THEN
  2145. (* Initialize and/or create other members, now that we know that all went well *)
  2146. ntp := 0;
  2147. NEW(ntilePartsRead, nt);
  2148. NEW(ntilePartsAvailable, nt);
  2149. Machine.Fill32(ADDRESSOF(ntilePartsRead[0]), nt*SIZEOF(LONGINT), 0);
  2150. Machine.Fill32(ADDRESSOF(ntilePartsAvailable[0]), nt*SIZEOF(LONGINT), 0);
  2151. ncblkInBuf := 0;
  2152. cblkBufPos := 0;
  2153. cblkBufSize := 0;
  2154. partRem := 0;
  2155. endOfCS := FALSE;
  2156. buf8Valid := FALSE;
  2157. (* We set the maximum range to the maximum allowed (we don't use it here anyhow) *)
  2158. maxStartLayer := 0;
  2159. maxEndLayer := MAX(LONGINT);
  2160. maxStartDecLvl := MAX(LONGINT);
  2161. maxEndDecLvl := 0;
  2162. (* Whole image shall be decoded by default *)
  2163. startLayer := 0;
  2164. endLayer := MAX(LONGINT);
  2165. startDecLvl := MAX(LONGINT);
  2166. endDecLvl := 0;
  2167. NEW(subbInfos, nt, ncomp);
  2168. NEW(progStates, nt);
  2169. IF pktDec = NIL THEN
  2170. NEW(pktDec, SELF, decSpec, ppmFirst);
  2171. ELSE
  2172. pktDec.ReInit(SELF, decSpec, ppmFirst);
  2173. END;
  2174. END;
  2175. initError := ~ok;
  2176. END ReInit;
  2177. PROCEDURE InitError* () : BOOLEAN;
  2178. BEGIN
  2179. RETURN initError;
  2180. END InitError;
  2181. (**
  2182. Reads the header of the next tile-part (if any)
  2183. RETURN: TRUE, if data for the next tile-part is ready to be read, FALSE otherwise
  2184. *)
  2185. PROCEDURE NextTilePart*() : BOOLEAN;
  2186. VAR
  2187. markerStr : ARRAY 8 OF CHAR;
  2188. ok : BOOLEAN;
  2189. bytesSkipped, ncomp, c, ndec: LONGINT;
  2190. BEGIN
  2191. (* Check preconditions *)
  2192. IF endOfCS THEN
  2193. KernelLog.String("ERROR (CodestreamReader.NextTilePart) : Already at end of stream");
  2194. KernelLog.Ln();
  2195. RETURN FALSE;
  2196. ELSIF TilePartAvailable() THEN
  2197. bytesSkipped := JumpToTilePartEnd();
  2198. (*
  2199. There was some data available before jumping to the end of the tile-part,
  2200. so the number of skipped bytes must be > 0
  2201. *)
  2202. IF bytesSkipped <= 0 THEN
  2203. KernelLog.String("ERROR (CodestreamReader.NextTilePart): ");
  2204. KernelLog.String("Tried to jump to end of tile-part (because end of current tile-part has not been reached yet), but failed");
  2205. KernelLog.Ln();
  2206. RETURN FALSE;
  2207. END;
  2208. END;
  2209. IF ntp > 0 THEN
  2210. (* Need to see if we have a byte (of the stream) in the buffer -> flush buffer if so *)
  2211. IF buf8Valid THEN
  2212. buf8Valid := FALSE;
  2213. curMarker := SYSTEM.VAL(LONGINT,
  2214. SYSTEM.VAL(SET, LSH(buf8, 8))
  2215. + SYSTEM.VAL(SET, LONG(ORD(s.Get())))
  2216. );
  2217. ELSE
  2218. curMarker := s.Net16();
  2219. END;
  2220. (* Write back progression information on the last tile *)
  2221. progStates[curTile].progOrder := progOrder;
  2222. progStates[curTile].curLay := curLay;
  2223. progStates[curTile].startLay := lmin;
  2224. progStates[curTile].endLay := lmax;
  2225. progStates[curTile].curRes := curRes;
  2226. progStates[curTile].endRes := rmax;
  2227. progStates[curTile].startRes := rmin;
  2228. progStates[curTile].curComp := curComp;
  2229. progStates[curTile].endComp := cmax;
  2230. progStates[curTile].startComp := cmin;
  2231. progStates[curTile].curPrec := curPrec;
  2232. progStates[curTile].curX := curX;
  2233. progStates[curTile].curY := curY;
  2234. END;
  2235. IF curMarker = SOT THEN
  2236. IF ReadSOTSegment() THEN
  2237. IF curPart = 0 THEN
  2238. CreateSubbandInfos();
  2239. pktDec.SetAndInitTile(curTile);
  2240. (* Init the progression number field of the progression state record for this tile *)
  2241. progStates[curTile].progNr := 0;
  2242. ncomp := decSpec.imgInfo.ncomp;
  2243. NEW(lmin, ncomp);
  2244. FOR c := 0 TO ncomp - 1 DO
  2245. ndec := decSpec.cstyle[curTile][c].ndec;
  2246. NEW(lmin[c], ndec + 1);
  2247. Machine.Fill32(ADDRESSOF(lmin[c][0]), (ndec+1)*SIZEOF(LONGINT), 0);
  2248. END;
  2249. lmax := -1;
  2250. (* We need to start a new progression *)
  2251. ProgressionChange();
  2252. (* Set the start values *)
  2253. curRes := rmin;
  2254. curComp := cmin;
  2255. curLay := 0;
  2256. curX := xmin;
  2257. curY := ymin;
  2258. ELSE
  2259. pktDec.SetTile(curTile);
  2260. (* Set the current progression order for the current tile *)
  2261. progOrder := progStates[curTile].progOrder;
  2262. curLay := progStates[curTile].curLay;
  2263. lmin := progStates[curTile].startLay;
  2264. lmax := progStates[curTile].endLay;
  2265. curRes := progStates[curTile].curRes;
  2266. rmax := progStates[curTile].endRes;
  2267. rmin := progStates[curTile].startRes;
  2268. curComp := progStates[curTile].curComp;
  2269. cmax:= progStates[curTile].endComp;
  2270. cmin := progStates[curTile].startComp;
  2271. curPrec := progStates[curTile].curPrec;
  2272. curX := progStates[curTile].curX;
  2273. curY := progStates[curTile].curY;
  2274. pktDec.GetMinIncStep(curComp, incX, incY);
  2275. pktDec.GetMaxSotEot(curComp, xmin, xmax, ymin, ymax);
  2276. (* The coordinates of the last sample are (xmax - 1, ymax - 1) *)
  2277. DEC(xmax);
  2278. DEC(ymax);
  2279. END;
  2280. (*
  2281. Call the initialization routine for the new tile (even if the new tile-part belongs to the
  2282. same tile as the last one)
  2283. *)
  2284. IF InitTile() THEN
  2285. INC(ntp);
  2286. INC(ntilePartsRead[curTile]);
  2287. ok := TRUE;
  2288. END;
  2289. ELSE
  2290. ok := FALSE;
  2291. END;
  2292. ELSIF curMarker = EOC THEN
  2293. endOfCS := TRUE;
  2294. ok := FALSE;
  2295. ELSE
  2296. MarkerToString(curMarker, markerStr);
  2297. KernelLog.String("ERROR (CodestreamReader.NextTilePart) : Invalid marker found (");
  2298. KernelLog.String(markerStr);
  2299. KernelLog.String(")");
  2300. KernelLog.Ln();
  2301. ok := FALSE;
  2302. END;
  2303. RETURN ok;
  2304. END NextTilePart;
  2305. PROCEDURE InitTile () : BOOLEAN;
  2306. VAR
  2307. nblocksPkt : LONGINT;
  2308. BEGIN
  2309. (* See how much packets there are at most for this tile *)
  2310. nblocksPkt := pktDec.GetMaxNumCodeblocksPkt();
  2311. (* Adjust buffer size if needed *)
  2312. IF nblocksPkt > cblkBufSize THEN
  2313. NEW(cblkBuf, nblocksPkt);
  2314. NEW(cblkInfoBuf, nblocksPkt);
  2315. cblkBufSize := nblocksPkt;
  2316. END;
  2317. RETURN TRUE;
  2318. END InitTile;
  2319. (**
  2320. Sets the maximum layer range for which data shall be delivered
  2321. and decoded, i.e. data outside this range shall NEVER be requested.
  2322. This procedure shall NOT be called after the first code-block data
  2323. has been read.
  2324. maxStartLayer and maxEndLayer are inclusive.
  2325. *)
  2326. PROCEDURE SetMaxLayerRange* (maxStartLayer, maxEndLayer : LONGINT);
  2327. BEGIN
  2328. SELF.maxStartLayer := maxStartLayer;
  2329. SELF.maxEndLayer := maxEndLayer;
  2330. END SetMaxLayerRange;
  2331. (**
  2332. Sets the layer range for which data shall be delivered
  2333. and decoded.
  2334. startLayer and endLayer are inclusive.
  2335. *)
  2336. PROCEDURE SetLayerRange* (startLayer, endLayer : LONGINT);
  2337. BEGIN
  2338. SELF.startLayer := startLayer;
  2339. SELF.endLayer := endLayer;
  2340. END SetLayerRange;
  2341. (**
  2342. Gets the layer range for which data shall be delivered
  2343. and decoded.
  2344. startLayer and endLayer are inclusive.
  2345. *)
  2346. PROCEDURE GetLayerRange* (VAR startLayer, endLayer : LONGINT);
  2347. BEGIN
  2348. startLayer := SELF.startLayer;
  2349. endLayer := SELF.endLayer;
  2350. END GetLayerRange;
  2351. (**
  2352. Sets the maximum decomposition level range for which data shall be delivered
  2353. and decoded, i.e. data outside this range shall NEVER be requested. This procedure
  2354. shall NOT be called after the first code-block data has been read.
  2355. maxStartDecLvl : The decompositon level to start at (inclusive) -> upper bound
  2356. maxEndDecLvl : The decomposition level to end at (inclusive) -> lower bound
  2357. *)
  2358. PROCEDURE SetMaxDecLevelRange* (maxStartDecLvl, maxEndDecLvl : LONGINT);
  2359. BEGIN
  2360. SELF.maxStartDecLvl := maxStartDecLvl;
  2361. SELF.maxEndDecLvl := maxEndDecLvl;
  2362. END SetMaxDecLevelRange;
  2363. (**
  2364. Sets the decomposition level range for which data shall be delivered
  2365. and decoded.
  2366. startDecLvl : The decompositon level to start at (inclusive) -> upper bound
  2367. endDecLvl : The decomposition level to end at (inclusive) -> lower bound
  2368. *)
  2369. PROCEDURE SetDecLevelRange* (startDecLvl, endDecLvl : LONGINT);
  2370. BEGIN
  2371. SELF.startDecLvl := startDecLvl;
  2372. SELF.endDecLvl := endDecLvl;
  2373. END SetDecLevelRange;
  2374. (**
  2375. Gets the decomposition level range for which data shall be delivered
  2376. and decoded.
  2377. startDecLvl : The decompositon level to start at (inclusive) -> upper bound
  2378. endDecLvl : The decomposition level to end at (inclusive) -> lower bound
  2379. *)
  2380. PROCEDURE GetDecLevelRange* (VAR startDecLvl, endDecLvl : LONGINT);
  2381. BEGIN
  2382. startDecLvl := SELF.startDecLvl;
  2383. endDecLvl := SELF.endDecLvl;
  2384. END GetDecLevelRange;
  2385. PROCEDURE SetReBuildMode*;
  2386. BEGIN
  2387. (* No rebuild allowed *)
  2388. HALT(99);
  2389. END SetReBuildMode;
  2390. (**
  2391. Gets the next (coded) code-blocks for the current tile-part in the stream. Previously a call to ReadTilePartHeader
  2392. is necessary before any code-blocks may be read.
  2393. cblocks: A reference to an array where CodedCblk records are stored
  2394. cblockInfos: A reference to an array where CblkInfo object references may be stored
  2395. These objects will contain information about the code-blocks in cblocks
  2396. ncblocks: The number of code-blocks that shall be fetched
  2397. RETURN: The actual number of code-blocks fetched
  2398. *)
  2399. PROCEDURE GetCodeBlocks* (VAR cblocks : ARRAY OF J2KU.CodedCblk; VAR cblockInfos: ARRAY OF J2KU.CblkInfo; ncblocks : LONGINT) : LONGINT;
  2400. VAR
  2401. i, startPos, cblkDecLvl : LONGINT;
  2402. ok : BOOLEAN;
  2403. BEGIN
  2404. i := 0;
  2405. (* See, wether buffer not empty: if not then return max(bufSize, ncblocks) code blocks *)
  2406. WHILE i < ncblocks DO
  2407. (* See if the code-block buffer has been read entirely *)
  2408. IF ~TilePartAvailable() THEN
  2409. RETURN i;
  2410. END;
  2411. IF ncblkInBuf <= cblkBufPos THEN
  2412. startPos := s.Pos();
  2413. (* Read the next packet *)
  2414. ncblkInBuf := pktDec.DecodePacket(curComp, curRes, curLay, curPrec[curComp][curRes][curLay], cblkBuf^, cblkInfoBuf^);
  2415. (* Need to check if the code-block is in the valid range (decomposition level, layer) *)
  2416. cblkDecLvl := decSpec.cstyle[curTile][curComp].ndec - curRes;
  2417. IF (cblkDecLvl < endDecLvl)
  2418. OR (cblkDecLvl > startDecLvl)
  2419. OR (curLay < startLayer)
  2420. OR (curLay > endLayer)
  2421. THEN
  2422. ncblkInBuf := 0;
  2423. END;
  2424. CASE progOrder OF
  2425. PROG_LRCP:
  2426. ok := AdvanceLayResComPos ();
  2427. | PROG_RLCP:
  2428. ok := AdvanceResLayComPos ();
  2429. | PROG_RPCL:
  2430. ok := AdvanceResPosComLay ();
  2431. | PROG_PCRL:
  2432. ok := AdvancePosComResLay ();
  2433. | PROG_CPRL:
  2434. ok := AdvanceComPosResLay ();
  2435. ELSE
  2436. ok := FALSE;
  2437. END;
  2438. cblkBufPos := 0;
  2439. partRem := partRem - (s.Pos() - startPos);
  2440. IF ~ok THEN
  2441. RETURN i;
  2442. END;
  2443. ELSE
  2444. IF cblkBuf[cblkBufPos].dataLen > 0 THEN (* Don't deliver code-blocks with no data *)
  2445. cblocks[i] := cblkBuf[cblkBufPos];
  2446. cblockInfos[i] := cblkInfoBuf[cblkBufPos];
  2447. (* If we don't start from layer 0, we update the current bit plane *)
  2448. IF startLayer > 0 THEN
  2449. cblockInfos[i].curbp := J2KU.LONGINT_BITS - 2 - cblockInfos[i].zerobp
  2450. - ((cblockInfos[i].truncpt - cblocks[i].cpasses + 2) DIV 3);
  2451. END;
  2452. INC(i);
  2453. END;
  2454. INC(cblkBufPos);
  2455. END;
  2456. END;
  2457. RETURN ncblocks;
  2458. END GetCodeBlocks;
  2459. PROCEDURE AdvanceLayResComPos () : BOOLEAN;
  2460. VAR
  2461. kmax, c, r : LONGINT;
  2462. BEGIN
  2463. kmax := pktDec.GetNumPrecincts(curComp, curRes) - 1;
  2464. IF curPrec[curComp][curRes][curLay] >= kmax THEN
  2465. (* We need to jump to the next nearest component that has as much resolution levels as indicated by curRes *)
  2466. REPEAT
  2467. IF curComp >= cmax THEN
  2468. IF curRes >= rmax THEN
  2469. IF curLay >= lmax THEN
  2470. (* We have reached the end of this progression -> get next progression *)
  2471. ProgressionChange();
  2472. curLay := MAX(LONGINT);
  2473. FOR c := cmin TO cmax DO
  2474. FOR r := rmin TO rmax DO
  2475. IF (r < LEN(lmin[c]^)) & (lmin[c][r] < curLay) THEN
  2476. curLay := lmin[c][r];
  2477. END;
  2478. END;
  2479. END;
  2480. ELSE
  2481. INC(curLay);
  2482. END;
  2483. curRes := rmin;
  2484. ELSE
  2485. INC(curRes);
  2486. END;
  2487. curComp := cmin;
  2488. ELSE
  2489. INC(curComp);
  2490. END;
  2491. UNTIL (curRes <= decSpec.cstyle[curTile][curComp].ndec) & (curLay >= lmin[curComp][curRes]);
  2492. ELSE
  2493. INC(curPrec[curComp][curRes][curLay]);
  2494. END;
  2495. RETURN TRUE;
  2496. END AdvanceLayResComPos;
  2497. PROCEDURE AdvanceResLayComPos () : BOOLEAN;
  2498. VAR
  2499. kmax, c : LONGINT;
  2500. BEGIN
  2501. kmax := pktDec.GetNumPrecincts(curComp, curRes) - 1;
  2502. IF curPrec[curComp][curRes][curLay] >= kmax THEN
  2503. (* We need to jump to the next nearest component that has as much resolution levels as indicated by curRes *)
  2504. REPEAT
  2505. IF curComp >= cmax THEN
  2506. IF curLay >= lmax THEN
  2507. IF curRes >= rmax THEN
  2508. (* We have reached the end of this progression -> get next progression *)
  2509. ProgressionChange();
  2510. curRes := rmin;
  2511. ELSE
  2512. INC(curRes);
  2513. END;
  2514. curLay := MAX(LONGINT);
  2515. FOR c := cmin TO cmax DO
  2516. IF (curRes < LEN(lmin[c]^)) & (lmin[c][curRes] < curLay) THEN
  2517. curLay := lmin[c][curRes];
  2518. END;
  2519. END;
  2520. ELSE
  2521. INC(curLay);
  2522. END;
  2523. curComp := cmin;
  2524. ELSE
  2525. INC(curComp);
  2526. END;
  2527. UNTIL (curRes <= decSpec.cstyle[curTile, curComp].ndec) & (curLay >= lmin[curComp][curRes]);
  2528. ELSE
  2529. INC(curPrec[curComp][curRes][curLay]);
  2530. END;
  2531. RETURN TRUE;
  2532. END AdvanceResLayComPos;
  2533. PROCEDURE AdvanceResPosComLay () : BOOLEAN;
  2534. VAR
  2535. foundNext : BOOLEAN;
  2536. incXR, incYR : LONGINT;
  2537. BEGIN
  2538. foundNext := FALSE;
  2539. INC(curPrec[curComp][curRes][curLay]);
  2540. (* Get the minimum increment step, i.e. the minimum precinct size projected to the reference grid at full resolution *)
  2541. IF curLay >= lmax THEN
  2542. (* We need to jump to the next nearest component that has as much resolution levels as indicated by curRes *)
  2543. REPEAT
  2544. IF curComp >= cmax THEN
  2545. IF curX >= xmax THEN
  2546. IF curY >= ymax THEN
  2547. IF curRes >= rmax THEN
  2548. (* We have reached the end of this progression -> get next progression *)
  2549. ProgressionChange();
  2550. curRes := rmin;
  2551. ELSE
  2552. INC(curRes);
  2553. END;
  2554. curY := ymin;
  2555. ELSE
  2556. INC(curY, incY);
  2557. END;
  2558. curX := xmin;
  2559. ELSE
  2560. INC(curX, incX);
  2561. END;
  2562. curComp := cmin;
  2563. ELSE
  2564. INC(curComp);
  2565. END;
  2566. IF (curRes <= decSpec.GetNumDecLevels(curTile, curComp)) THEN
  2567. pktDec.GetIncStep(curComp, curRes, incXR, incYR);
  2568. IF (((curX = xmin) OR (curX MOD incXR = 0)) & (curX <= xmax))
  2569. & (((curY = ymin) OR (curY MOD incYR = 0)) & (curY <= ymax))
  2570. THEN
  2571. foundNext := TRUE;
  2572. END;
  2573. END;
  2574. UNTIL foundNext;
  2575. curLay := lmin[curComp][curRes];
  2576. ELSE
  2577. INC(curLay);
  2578. END;
  2579. RETURN TRUE;
  2580. END AdvanceResPosComLay;
  2581. PROCEDURE AdvancePosComResLay () : BOOLEAN;
  2582. VAR
  2583. foundNext : BOOLEAN;
  2584. incXR, incYR : LONGINT;
  2585. BEGIN
  2586. foundNext := FALSE;
  2587. INC(curPrec[curComp][curRes][curLay]);
  2588. (* Get the minimum increment step, i.e. the minimum precinct size projected to the reference grid at full resolution *)
  2589. IF curLay >= lmax THEN
  2590. (* We need to jump to the next nearest component that has as much resolution levels as indicated by curRes *)
  2591. REPEAT
  2592. IF curRes >= rmax THEN
  2593. IF curComp >= cmax THEN
  2594. IF curX >= xmax THEN
  2595. IF curY >= ymax THEN
  2596. (* We have reached the end of this progression -> get next progression *)
  2597. ProgressionChange();
  2598. curY := ymin;
  2599. ELSE
  2600. INC(curY, incY);
  2601. END;
  2602. curX := xmin;
  2603. ELSE
  2604. INC(curX, incX);
  2605. END;
  2606. curComp := cmin;
  2607. ELSE
  2608. INC(curComp);
  2609. END;
  2610. curRes := rmin;
  2611. ELSE
  2612. INC(curRes);
  2613. END;
  2614. IF (curRes <= decSpec.GetNumDecLevels(curTile, curComp)) THEN
  2615. pktDec.GetIncStep(curComp, curRes, incXR, incYR);
  2616. IF (((curX = xmin) OR (curX MOD incXR = 0)) & (curX <= xmax))
  2617. & (((curY = ymin) OR (curY MOD incYR = 0)) & (curY <= ymax))
  2618. THEN
  2619. foundNext := TRUE;
  2620. END;
  2621. END;
  2622. UNTIL foundNext;
  2623. curLay := lmin[curComp][curRes];
  2624. ELSE
  2625. INC(curLay);
  2626. END;
  2627. RETURN TRUE;
  2628. END AdvancePosComResLay;
  2629. PROCEDURE AdvanceComPosResLay () : BOOLEAN;
  2630. VAR
  2631. foundNext : BOOLEAN;
  2632. incXR, incYR : LONGINT;
  2633. BEGIN
  2634. foundNext := FALSE;
  2635. INC(curPrec[curComp][curRes][curLay]);
  2636. (* Get the minimum increment step, i.e. the minimum precinct size projected to the reference grid at full resolution *)
  2637. IF curLay >= lmax THEN
  2638. (* We need to jump to the next nearest component that has as much resolution levels as indicated by curRes *)
  2639. REPEAT
  2640. IF curRes >= rmax THEN
  2641. IF curX >= xmax THEN
  2642. IF curY >= ymax THEN
  2643. IF curComp >= cmax THEN
  2644. (* We have reached the end of this progression -> get next progression *)
  2645. ProgressionChange();
  2646. curComp := cmin;
  2647. ELSE
  2648. INC(curComp);
  2649. END;
  2650. curY := ymin;
  2651. ELSE
  2652. INC(curY, incY);
  2653. END;
  2654. curX := xmin;
  2655. ELSE
  2656. INC(curX, incX);
  2657. END;
  2658. curRes := rmin;
  2659. ELSE
  2660. INC(curRes);
  2661. END;
  2662. IF (curRes <= decSpec.GetNumDecLevels(curTile, curComp)) THEN
  2663. pktDec.GetIncStep(curComp, curRes, incXR, incYR);
  2664. IF (((curX = xmin) OR (curX MOD incXR = 0)) & (curX <= xmax))
  2665. & (((curY = ymin) OR (curY MOD incYR = 0)) & (curY <= ymax))
  2666. THEN
  2667. foundNext := TRUE;
  2668. END;
  2669. END;
  2670. UNTIL foundNext;
  2671. curLay := lmin[curComp][curRes];
  2672. ELSE
  2673. INC(curLay);
  2674. END;
  2675. RETURN TRUE;
  2676. END AdvanceComPosResLay;
  2677. (*
  2678. TODO: The implementation of this procedure conforms with the reference implmentation (JJ2000).
  2679. But it's not clear, wether the reference implementation is correct (on the issue of
  2680. progression changes, that is).
  2681. -> See further below.
  2682. *)
  2683. PROCEDURE ProgressionChange;
  2684. VAR
  2685. nextProgIdx, c, r : LONGINT;
  2686. BEGIN
  2687. (* Update next first layer index *)
  2688. FOR c := cmin TO cmax DO
  2689. FOR r := rmin TO rmax DO
  2690. IF r < LEN(lmin[c]^) THEN
  2691. lmin[c][r] := lmax + 1;
  2692. END;
  2693. END;
  2694. END;
  2695. nextProgIdx := progStates[curTile].progNr;
  2696. IF (progChanges # NIL) & (progChanges[curTile] # NIL) & (nextProgIdx < LEN(progChanges[curTile]^)) THEN
  2697. IF nextProgIdx > 0 THEN
  2698. progOrder := progChanges[curTile][nextProgIdx - 1].progOrder;
  2699. ELSE
  2700. progOrder := decSpec.cics[curTile].po;
  2701. END;
  2702. rmax := progChanges[curTile][nextProgIdx].endRes - 1;
  2703. cmax := progChanges[curTile][nextProgIdx].endComp - 1;
  2704. lmax := progChanges[curTile][nextProgIdx].endLay - 1;
  2705. rmin := progChanges[curTile][nextProgIdx].startRes;
  2706. cmin := progChanges[curTile][nextProgIdx].startComp;
  2707. ELSE
  2708. IF (progChanges # NIL) & (progChanges[curTile] # NIL) & (nextProgIdx = LEN(progChanges[curTile]^)) THEN
  2709. progOrder := progChanges[curTile][nextProgIdx - 1].progOrder;
  2710. ELSE
  2711. progOrder := decSpec.cics[curTile].po;
  2712. END;
  2713. rmax := decSpec.GetMaxDecLevels(curTile);
  2714. cmax := decSpec.imgInfo.ncomp - 1;
  2715. lmax := decSpec.cics[curTile].nl - 1;
  2716. rmin := 0;
  2717. cmin := 0;
  2718. END;
  2719. (* Set the position boundaries (even if not needed) *)
  2720. pktDec.GetMinIncStep(cmin, incX, incY);
  2721. pktDec.GetMaxSotEot(cmin, xmin, xmax, ymin, ymax);
  2722. DEC(xmax);
  2723. DEC(ymax);
  2724. (* Need to create/reinitialize new precinct counters *)
  2725. CreatePrecCounter();
  2726. INC(progStates[curTile].progNr);
  2727. END ProgressionChange;
  2728. (* TODO: The semantics of a progression change implied by the reference codec (JJ2000) differs from
  2729. the semantics suggested by this procedure. But which interpretation is correct?
  2730. *)
  2731. (*
  2732. PROCEDURE ProgressionChange ();
  2733. VAR
  2734. nextProgIdx, c, r : LONGINT;
  2735. BEGIN
  2736. (* Update next first layer index *)
  2737. FOR c := cmin TO cmax DO
  2738. FOR r := rmin TO rmax DO
  2739. IF r < LEN(lmin[c]^) THEN
  2740. lmin[c][r] := lmax + 1;
  2741. END;
  2742. END;
  2743. END;
  2744. nextProgIdx := progStates[curTile].progNr;
  2745. IF (progChanges # NIL) & (progChanges[curTile] # NIL) & (nextProgIdx < LEN(progChanges[curTile]^)) THEN
  2746. progOrder := progChanges[curTile][nextProgIdx].progOrder;
  2747. rmax := progChanges[curTile][nextProgIdx].endRes - 1;
  2748. cmax := progChanges[curTile][nextProgIdx].endComp - 1;
  2749. lmax := progChanges[curTile][nextProgIdx].endLay - 1;
  2750. rmin := progChanges[curTile][nextProgIdx].startRes;
  2751. cmin := progChanges[curTile][nextProgIdx].startComp;
  2752. ELSE
  2753. progOrder := decSpec.cics[curTile].po;
  2754. rmax := decSpec.GetMaxDecLevels(curTile);
  2755. cmax := decSpec.imgInfo.ncomp - 1;
  2756. lmax := decSpec.cics[curTile].nl - 1;
  2757. rmin := 0;
  2758. cmin := 0;
  2759. END;
  2760. (* Set the position boundaries (even if not needed) *)
  2761. pktDec.GetMinIncStep(cmin, incX, incY);
  2762. pktDec.GetMaxSotEot(cmin, xmin, xmax, ymin, ymax);
  2763. DEC(xmax);
  2764. DEC(ymax);
  2765. (* Need to create new precinct counters *)
  2766. CreatePrecCounter();
  2767. INC(progStates[curTile].progNr);
  2768. END ProgressionChange;
  2769. *)
  2770. PROCEDURE EndOfCodestream* () : BOOLEAN;
  2771. BEGIN
  2772. RETURN endOfCS;
  2773. END EndOfCodestream;
  2774. (*
  2775. Advances to the end of the current tile-part, reads all packets from the stream
  2776. *)
  2777. PROCEDURE JumpToTilePartEnd () : LONGINT;
  2778. VAR
  2779. bytesSkipped, startPos : LONGINT;
  2780. ok : BOOLEAN;
  2781. BEGIN
  2782. bytesSkipped := 0;
  2783. ok := TRUE;
  2784. WHILE TilePartAvailable() & ok DO
  2785. startPos := s.Pos();
  2786. (* Read the next packet *)
  2787. ncblkInBuf := pktDec.DecodePacket(curComp, curRes, curLay, curPrec[curComp][curRes][curLay], cblkBuf^, cblkInfoBuf^);
  2788. CASE progOrder OF
  2789. PROG_LRCP:
  2790. ok := AdvanceLayResComPos ();
  2791. | PROG_RLCP:
  2792. ok := AdvanceResLayComPos ();
  2793. | PROG_RPCL:
  2794. ok := AdvanceResPosComLay ();
  2795. | PROG_PCRL:
  2796. ok := AdvancePosComResLay ();
  2797. | PROG_CPRL:
  2798. ok := AdvanceComPosResLay ();
  2799. ELSE
  2800. ok := FALSE;
  2801. END;
  2802. partRem := partRem - (s.Pos() - startPos);
  2803. INC(bytesSkipped, s.Pos() - startPos);
  2804. END;
  2805. RETURN bytesSkipped;
  2806. END JumpToTilePartEnd;
  2807. (**
  2808. Returns the decoder specification object.
  2809. That object contains all information necessary to
  2810. properly decode the compressed image data
  2811. *)
  2812. PROCEDURE GetDecoderSpecs* () : DecoderSpecs;
  2813. BEGIN
  2814. RETURN decSpec;
  2815. END GetDecoderSpecs;
  2816. PROCEDURE CreateSubbandInfos;
  2817. VAR
  2818. c, ndec, tx0, tx1, ty0, ty1, tcx0, tcx1, tcy0, tcy1, p, q, curIdx, reslevel, declevel, tmpW, tmpH : LONGINT;
  2819. ppx, ppy, cblw, cblh : LONGINT;
  2820. parentBand, llBand, hlBand, lhBand, hhBand : J2KU.SubbandInfo;
  2821. cstyle : CodingStyle;
  2822. imgInfo : ImageInfo;
  2823. BEGIN
  2824. imgInfo := decSpec.imgInfo;
  2825. (* Compute the horizontal and vertical indices of the current tile in the reference grid *)
  2826. p := curTile MOD imgInfo.nxt;
  2827. q := curTile DIV imgInfo.nxt;
  2828. (* Determine the actual upper left x-coordinate of the tile *)
  2829. tx0 := imgInfo.xtos + p*imgInfo.xt;
  2830. IF imgInfo.xos > tx0 THEN
  2831. tx0 := imgInfo.xos;
  2832. END;
  2833. (* Determine the actual upper left y-coordinate of the tile *)
  2834. ty0 := imgInfo.ytos + q*imgInfo.yt;
  2835. IF imgInfo.yos > ty0 THEN
  2836. ty0 := imgInfo.yos;
  2837. END;
  2838. (* Determine the actual lower right x-coordinate of the tile *)
  2839. tx1 := imgInfo.xtos + (p+1)*imgInfo.xt;
  2840. IF imgInfo.xsiz < tx1 THEN
  2841. tx1 := imgInfo.xsiz;
  2842. END;
  2843. (* Determine the actual lower right y-coordinate of the tile *)
  2844. ty1 := imgInfo.ytos + (q+1)*imgInfo.yt;
  2845. IF imgInfo.ysiz < ty1 THEN
  2846. ty1 := imgInfo.ysiz;
  2847. END;
  2848. FOR c := 0 TO imgInfo.ncomp - 1 DO
  2849. (* Compute the tile coordinates in the component domain *)
  2850. (* Determine the x-coordinate of the upper left hand sample of the tile-component *)
  2851. tcx0 := (tx0 + imgInfo.comps[c].subsx - 1) DIV imgInfo.comps[c].subsx;
  2852. (* Determine the y-coordinate of the upper left hand sample of the tile-component *)
  2853. tcy0 := (ty0 + imgInfo.comps[c].subsy - 1) DIV imgInfo.comps[c].subsy;
  2854. (* Determine the x-coordinate of the lower right hand sample of the tile-component *)
  2855. tcx1 := (tx1 + imgInfo.comps[c].subsx - 1) DIV imgInfo.comps[c].subsx;
  2856. (* Determine the y-coordinate of the lower right hand sample of the tile-component *)
  2857. tcy1 := (ty1 + imgInfo.comps[c].subsy - 1) DIV imgInfo.comps[c].subsy;
  2858. (* Get number of decomposition levels for the current component *)
  2859. cstyle := decSpec.cstyle[curTile][c];
  2860. ndec := cstyle.ndec;
  2861. ppx := decSpec.GetPPX(curTile, c, ndec);
  2862. ppy := decSpec.GetPPY(curTile, c, ndec);
  2863. IF cstyle.cblw > ppx THEN
  2864. cblw := ppx;
  2865. ELSE
  2866. cblw := cstyle.cblw;
  2867. END;
  2868. IF cstyle.cblh > ppy THEN
  2869. cblh := ppy;
  2870. ELSE
  2871. cblh := cstyle.cblh;
  2872. END;
  2873. (* Values used for implicit 'ceil' operation after division (i.e. shifting) *)
  2874. tmpW := LSH(SYSTEM.VAL(LONGINT, 1), cblw) - 1;
  2875. tmpH := LSH(SYSTEM.VAL(LONGINT, 1), cblh) - 1;
  2876. (* We have to allocate space for all subbands in each decomposition level *)
  2877. NEW(subbInfos[curTile][c], 4 * ndec + 1);
  2878. (* Init the top subband info which holds information on the original tile-component *)
  2879. NEW(parentBand);
  2880. parentBand.type := J2KU.SUB_LL;
  2881. parentBand.index := 0;
  2882. parentBand.ulcx := tcx0;
  2883. parentBand.ulcy := tcy0;
  2884. parentBand.width := tcx1 - tcx0;
  2885. parentBand.height := tcy1 - tcy0;
  2886. IF parentBand.width = 0 THEN
  2887. parentBand.nblocksx := 0;
  2888. ELSE
  2889. (* NOTE: Implicit 'ceil' operation is applied to first term *)
  2890. parentBand.nblocksx := LSH(tcx1 + tmpW, -cblw) - LSH(tcx0, -cblw);
  2891. END;
  2892. IF parentBand.height = 0 THEN
  2893. parentBand.nblocksy := 0;
  2894. ELSE
  2895. (* NOTE: Implicit 'ceil' operation is applied to first term *)
  2896. parentBand.nblocksy := LSH(tcy1 + tmpH, -cblh) - LSH(tcy0, -cblh);
  2897. END;
  2898. (* We always start from the origin in the subband decomposition domain *)
  2899. parentBand.ulsx := 0;
  2900. parentBand.ulsy := 0;
  2901. (*
  2902. The number of magnitude bits of any LL band shall be the
  2903. number of magnitude bits of the LL band of the lowest resolution level.
  2904. NOTE: This is not specified by the standard but is just a convention
  2905. of this implementation. For the top LL band this is a quite nice
  2906. convention since when there are no decomposition levels we at
  2907. least have the right value set here
  2908. *)
  2909. parentBand.magbits := GetNumMagBits(curTile, c, 0, J2KU.SUB_LL);
  2910. parentBand.component := c;
  2911. parentBand.reslevel := ndec;
  2912. parentBand.declevel := 0;
  2913. subbInfos[curTile][c][0] := parentBand;
  2914. (*
  2915. Now that we have set the values for the top subband, we can go over the others in an
  2916. iterative way
  2917. *)
  2918. curIdx := 1;
  2919. declevel := 1;
  2920. FOR reslevel := ndec TO 1 BY -1 DO
  2921. IF cstyle.cblw > (ppx - 1) THEN
  2922. cblw := ppx - 1;
  2923. ELSE
  2924. cblw := cstyle.cblw;
  2925. END;
  2926. IF cstyle.cblh > (ppy - 1) THEN
  2927. cblh := ppy - 1;
  2928. ELSE
  2929. cblh := cstyle.cblh;
  2930. END;
  2931. (* Values used for implicit 'ceil' operation after division (i.e. shifting) *)
  2932. tmpW := LSH(SYSTEM.VAL(LONGINT, 1), cblw) - 1;
  2933. tmpH := LSH(SYSTEM.VAL(LONGINT, 1), cblh) - 1;
  2934. (* The HL subband *)
  2935. NEW(hlBand);
  2936. hlBand.type := J2KU.SUB_HL;
  2937. hlBand.index := 0;
  2938. hlBand.ulcx := LSH(parentBand.ulcx, -1);
  2939. hlBand.ulcy := LSH(parentBand.ulcy + 1, -1);
  2940. hlBand.width := LSH(parentBand.ulcx + parentBand.width, -1) - hlBand.ulcx;
  2941. hlBand.height := LSH(parentBand.ulcy + parentBand.height + 1, -1) - hlBand.ulcy;
  2942. (* Set number of code-blocks for this subband *)
  2943. IF hlBand.width = 0 THEN
  2944. hlBand.nblocksx := 0;
  2945. ELSE
  2946. (* NOTE: Implicit 'ceil' operation is applied to first term *)
  2947. hlBand.nblocksx := LSH(hlBand.ulcx+hlBand.width + tmpW, -cblw) - LSH(hlBand.ulcx, -cblw);
  2948. END;
  2949. IF hlBand.height = 0 THEN
  2950. hlBand.nblocksy := 0;
  2951. ELSE
  2952. (* NOTE: Implicit 'ceil' operation is applied to first term *)
  2953. hlBand.nblocksy := LSH(hlBand.ulcy+hlBand.height + tmpH, -cblh) - LSH(hlBand.ulcy, -cblh);
  2954. END;
  2955. hlBand.magbits := GetNumMagBits(curTile, c, reslevel, J2KU.SUB_HL);
  2956. hlBand.component := c;
  2957. hlBand.reslevel := reslevel;
  2958. hlBand.declevel := declevel;
  2959. subbInfos[curTile][c][curIdx] := hlBand;
  2960. INC(curIdx);
  2961. (* The LH subband *)
  2962. NEW(lhBand);
  2963. lhBand.type := J2KU.SUB_LH;
  2964. lhBand.index := 1;
  2965. lhBand.ulcx := LSH(parentBand.ulcx + 1, -1);
  2966. lhBand.ulcy := LSH(parentBand.ulcy, -1);
  2967. lhBand.width := LSH(parentBand.ulcx + parentBand.width + 1, -1) - lhBand.ulcx;
  2968. lhBand.height := LSH(parentBand.ulcy + parentBand.height, -1) - lhBand.ulcy;
  2969. (* Set number of code-blocks for this subband *)
  2970. IF lhBand.width = 0 THEN
  2971. lhBand.nblocksx := 0;
  2972. ELSE
  2973. (* NOTE: Implicit 'ceil' operation is applied to first term *)
  2974. lhBand.nblocksx := LSH(lhBand.ulcx+lhBand.width + tmpW, -cblw) - LSH(lhBand.ulcx, -cblw);
  2975. END;
  2976. IF lhBand.height = 0 THEN
  2977. lhBand.nblocksy := 0;
  2978. ELSE
  2979. (* NOTE: Implicit 'ceil' operation is applied to first term *)
  2980. lhBand.nblocksy := LSH(lhBand.ulcy+lhBand.height + tmpH, -cblh) - LSH(lhBand.ulcy, -cblh);
  2981. END;
  2982. lhBand.magbits := GetNumMagBits(curTile, c, reslevel, J2KU.SUB_LH);
  2983. lhBand.component := c;
  2984. lhBand.reslevel := reslevel;
  2985. lhBand.declevel := declevel;
  2986. subbInfos[curTile][c][curIdx] := lhBand;
  2987. INC(curIdx);
  2988. (* The HH subband *)
  2989. NEW(hhBand);
  2990. hhBand.type := J2KU.SUB_HH;
  2991. hhBand.index := 2;
  2992. hhBand.ulcx := hlBand.ulcx;
  2993. hhBand.ulcy := lhBand.ulcy;
  2994. hhBand.width := hlBand.width;
  2995. hhBand.height := lhBand.height;
  2996. (* Set number of code-blocks for this subband *)
  2997. hhBand.nblocksx := hlBand.nblocksx;
  2998. hhBand.nblocksy := lhBand.nblocksy;
  2999. hhBand.magbits := GetNumMagBits(curTile, c, reslevel, J2KU.SUB_HH);
  3000. hhBand.component := c;
  3001. hhBand.reslevel := reslevel;
  3002. hhBand.declevel := declevel;
  3003. subbInfos[curTile][c][curIdx] := hhBand;
  3004. INC(curIdx);
  3005. (* At last the LL subband for the NEXT LOWER(!) resolution level *)
  3006. ppx := decSpec.GetPPX(curTile, c, reslevel - 1);
  3007. ppy := decSpec.GetPPY(curTile, c, reslevel - 1);
  3008. IF cstyle.cblw > ppx THEN
  3009. cblw := ppx;
  3010. ELSE
  3011. cblw := cstyle.cblw;
  3012. END;
  3013. IF cstyle.cblh > ppy THEN
  3014. cblh := ppy;
  3015. ELSE
  3016. cblh := cstyle.cblh;
  3017. END;
  3018. (* Values used for implicit 'ceil' operation after division (i.e. shifting) *)
  3019. tmpW := LSH(SYSTEM.VAL(LONGINT, 1), cblw) - 1;
  3020. tmpH := LSH(SYSTEM.VAL(LONGINT, 1), cblh) - 1;
  3021. NEW(llBand);
  3022. llBand.type := J2KU.SUB_LL;
  3023. llBand.index := 0;
  3024. llBand.ulcx := lhBand.ulcx;
  3025. llBand.ulcy := hlBand.ulcy;
  3026. llBand.width := lhBand.width;
  3027. llBand.height := hlBand.height;
  3028. (* Set number of code-blocks for this subband *)
  3029. (* NOTE: Implicit 'ceil' operation is applied to first term *)
  3030. IF llBand.width = 0 THEN
  3031. llBand.nblocksx := 0;
  3032. ELSE
  3033. (* NOTE: Implicit 'ceil' operation is applied to first term *)
  3034. llBand.nblocksx := LSH(llBand.ulcx+llBand.width + tmpW, -cblw) - LSH(llBand.ulcx, -cblw);
  3035. END;
  3036. IF llBand.height = 0 THEN
  3037. llBand.nblocksy := 0;
  3038. ELSE
  3039. (* NOTE: Implicit 'ceil' operation is applied to first term *)
  3040. llBand.nblocksy := LSH(llBand.ulcy+llBand.height + tmpH, -cblh) - LSH(llBand.ulcy, -cblh);
  3041. END;
  3042. (*
  3043. The number of magnitude bits of any LL band shall be the
  3044. number of magnitude bits of the LL band of the lowest resolution level.
  3045. NOTE: This is not specified by the standard but is just a convention
  3046. of this implementation.
  3047. *)
  3048. llBand.magbits := GetNumMagBits(curTile, c, 0, J2KU.SUB_LL);
  3049. llBand.component := c;
  3050. llBand.reslevel := reslevel - 1;
  3051. llBand.declevel := declevel;
  3052. subbInfos[curTile][c][curIdx] := llBand;
  3053. INC(curIdx);
  3054. (* Now set the coordinates in the subband decomposition domain *)
  3055. llBand.ulsx := parentBand.ulsx;
  3056. llBand.ulsy := parentBand.ulsy;
  3057. hlBand.ulsx := parentBand.ulsx + llBand.width;
  3058. hlBand.ulsy := parentBand.ulsy;
  3059. lhBand.ulsx := parentBand.ulsx;
  3060. lhBand.ulsy := parentBand.ulsy + llBand.height;
  3061. hhBand.ulsx := hlBand.ulsx;
  3062. hhBand.ulsy := lhBand.ulsy;
  3063. parentBand := llBand;
  3064. INC(declevel);
  3065. END;
  3066. END;
  3067. END CreateSubbandInfos;
  3068. (**
  3069. Gets the number of magnitude bits for all samples in a specific subband.
  3070. *)
  3071. PROCEDURE GetNumMagBits (tile, comp, reslevel, subband : LONGINT) : LONGINT;
  3072. VAR
  3073. exp, idx : LONGINT;
  3074. quant : Quantization;
  3075. BEGIN
  3076. quant := decSpec.quant[tile][comp];
  3077. IF (quant.style = NOQUANT) OR (quant.style = QUANT_EXP) THEN
  3078. IF reslevel = 0 THEN
  3079. idx := 0;
  3080. ELSE
  3081. idx := 3 * (reslevel - 1) + 1 + J2KU.SubbandToSubbandIndex(subband);
  3082. END;
  3083. exp := quant.stepsiz[idx].exp;
  3084. ELSIF quant.style = QUANT_DER THEN
  3085. IF reslevel = 0 THEN
  3086. exp := quant.stepsiz[0].exp;
  3087. ELSE
  3088. exp := quant.stepsiz[0].exp - (reslevel - 1);
  3089. END;
  3090. END;
  3091. RETURN quant.nguardb + exp - 1;
  3092. END GetNumMagBits;
  3093. PROCEDURE CreatePrecCounter;
  3094. VAR
  3095. c, r, ndec, ncomp, nl : LONGINT;
  3096. cstyle : CodingStyle;
  3097. BEGIN
  3098. ncomp := decSpec.imgInfo.ncomp;
  3099. NEW(curPrec, ncomp);
  3100. nl := decSpec.cics[curTile].nl;
  3101. FOR c := 0 TO ncomp - 1 DO
  3102. cstyle := decSpec.cstyle[curTile][c];
  3103. ndec := cstyle.ndec;
  3104. NEW(curPrec[c], ndec + 1);
  3105. FOR r := 0 TO ndec DO
  3106. NEW(curPrec[c][r], nl);
  3107. (*Machine.Fill32(ADDRESSOF(curPrec[c][r][0]), nl*SIZEOF(LONGINT), 0);*)
  3108. END;
  3109. END;
  3110. END CreatePrecCounter;
  3111. (**
  3112. Gets the subband information objects for a specific subband
  3113. *)
  3114. PROCEDURE GetSubbandInfo* (tile, comp, reslevel, subband : LONGINT) : J2KU.SubbandInfo;
  3115. VAR
  3116. ndec : LONGINT;
  3117. subbOff : LONGINT;
  3118. BEGIN
  3119. ndec := decSpec.cstyle[tile][comp].ndec;
  3120. IF subband = J2KU.SUB_LL THEN
  3121. subbOff := 0;
  3122. ELSE
  3123. subbOff := 1;
  3124. END;
  3125. RETURN subbInfos[tile][comp][(ndec - reslevel)*4 + J2KU.SubbandToSubbandIndex(subband) + subbOff];
  3126. END GetSubbandInfo;
  3127. (*
  3128. Reads the next 2 bytes in the stream, without advancing
  3129. *)
  3130. PROCEDURE Peek16 () : LONGINT;
  3131. BEGIN
  3132. IF ~buf8Valid THEN
  3133. buf8 := ORD(s.Get());
  3134. buf8Valid := TRUE;
  3135. END;
  3136. RETURN
  3137. SYSTEM.VAL(LONGINT,
  3138. SYSTEM.VAL(SET, LSH(buf8, 8))
  3139. + SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, s.Peek()))
  3140. );
  3141. END Peek16;
  3142. PROCEDURE ReadByte (VAR byte : CHAR);
  3143. BEGIN
  3144. IF buf8Valid THEN
  3145. byte := CHR(buf8);
  3146. buf8Valid := FALSE;
  3147. ELSE
  3148. s.Char(byte);
  3149. END;
  3150. END ReadByte;
  3151. PROCEDURE ReadBytes(VAR bytes : ARRAY OF CHAR; nbytes : LONGINT);
  3152. VAR
  3153. len, off : LONGINT;
  3154. BEGIN
  3155. IF buf8Valid THEN
  3156. bytes[0] := CHR(buf8);
  3157. buf8Valid := FALSE;
  3158. off := 1;
  3159. DEC(nbytes);
  3160. ELSE
  3161. off := 0;
  3162. END;
  3163. (* TODO: Maybe check that nbytes have been read *)
  3164. s.Bytes(bytes, off, nbytes, len);
  3165. END ReadBytes;
  3166. (**
  3167. Returns the index of the tile for which currently data is being read. Usually used to
  3168. find out the tile index to which the last read tile-part header belongs to.
  3169. RETURN: The index of the current tile
  3170. *)
  3171. PROCEDURE CurrentTile* () : LONGINT;
  3172. BEGIN
  3173. RETURN curTile;
  3174. END CurrentTile;
  3175. (**
  3176. Returns the index of the tile-part (of the current tile) for which currently data is being read. Usually used to
  3177. find out the tile-part index to which the last read tile-part header belongs to.
  3178. RETURN: The index of the current tile-part
  3179. *)
  3180. PROCEDURE CurrentTilePart* () : LONGINT;
  3181. BEGIN
  3182. RETURN curPart;
  3183. END CurrentTilePart;
  3184. (**
  3185. TRUE if the current tile-part has not been read entirely, FALSE otherwise.
  3186. *)
  3187. PROCEDURE TilePartAvailable* () : BOOLEAN;
  3188. BEGIN
  3189. IF ppmUsed THEN
  3190. RETURN (ncblkInBuf > cblkBufPos) OR (partRem > 0) OR pktDec.PPHMainAvailable();
  3191. ELSIF pktDec.PPHTileUsed() & (ntilePartsRead[curTile] >= ntilePartsAvailable[curTile]) THEN
  3192. RETURN (ncblkInBuf > cblkBufPos) OR (partRem > 0) OR pktDec.PPHTileAvailable();
  3193. ELSE
  3194. RETURN (ncblkInBuf > cblkBufPos) OR (partRem > 0);
  3195. END;
  3196. END TilePartAvailable;
  3197. (**
  3198. TRUE if all tile-parts for a given tile have been read, i.e. there is no more data
  3199. for that tile, FALSE otherwise
  3200. *)
  3201. PROCEDURE AllTilePartsRead* () : BOOLEAN;
  3202. VAR
  3203. progVol, ncomps, nlayers, c, r : LONGINT;
  3204. BEGIN
  3205. IF TilePartAvailable() THEN
  3206. RETURN FALSE;
  3207. ELSIF ntilePartsAvailable[curTile] # 0 THEN
  3208. RETURN ntilePartsRead[curTile] >= ntilePartsAvailable[curTile];
  3209. ELSE
  3210. (*
  3211. Compute the overall progression volume, subtract the
  3212. progression volume still to come. If it's not 0, there
  3213. are still more tile-parts
  3214. *)
  3215. progVol := 0;
  3216. ncomps := decSpec.imgInfo.ncomp;
  3217. nlayers := decSpec.cics[curTile].nl;
  3218. FOR c := 0 TO decSpec.imgInfo.ncomp - 1 DO
  3219. INC(progVol, nlayers*(decSpec.cstyle[curTile][c].ndec + 1));
  3220. END;
  3221. (* Now we subtract the progression volumes already read *)
  3222. FOR c := 0 TO ncomps - 1 DO
  3223. FOR r := 0 TO decSpec.cstyle[curTile][c].ndec DO
  3224. DEC(progVol, lmin[c][r]);
  3225. END;
  3226. END;
  3227. RETURN progVol <= 0;
  3228. END;
  3229. END AllTilePartsRead;
  3230. (**
  3231. Frees all resources not needed in rebuild mode
  3232. *)
  3233. PROCEDURE FreeNonRebuildResources*;
  3234. BEGIN
  3235. (* No rebuild allowed (and therefore this procedure shall not be called either) *)
  3236. HALT(99);
  3237. END FreeNonRebuildResources;
  3238. (**
  3239. Frees all resources
  3240. *)
  3241. PROCEDURE FreeResources*;
  3242. BEGIN
  3243. s := NIL;
  3244. ntilePartsRead := NIL;
  3245. ntilePartsAvailable := NIL;
  3246. pktDec := NIL;
  3247. cblkBuf := NIL;
  3248. cblkInfoBuf := NIL;
  3249. progChanges := NIL;
  3250. progStates := NIL;
  3251. curPrec := NIL;
  3252. END FreeResources;
  3253. PROCEDURE ReadSOTSegment() : BOOLEAN;
  3254. VAR
  3255. lsot, psot, sPos, ePos, comp, i : LONGINT;
  3256. ncod, nqcd, npoc, nmax : LONGINT; (* Counter variables used for constraint checking *)
  3257. ncoc, nqcc, nrgn : J2KU.LongIntArrayPtr;
  3258. tileIdx, partIdx, nparts, ncomp, nt : LONGINT;
  3259. ch : CHAR;
  3260. ok : BOOLEAN;
  3261. cstyle : CodingStyle;
  3262. cics : CICodingStyle;
  3263. quant : Quantization;
  3264. roiShift : LONGINT;
  3265. pptFirst, pptLast : DataListElement;
  3266. pptUsed : BOOLEAN;
  3267. changes : ProgChangeArrayPtr;
  3268. BEGIN
  3269. (*
  3270. IF s.Available() < 10 THEN
  3271. KernelLog.String("ERROR: SOT segment shorter than 10 bytes");
  3272. KernelLog.Ln();
  3273. RETURN FALSE;
  3274. END;
  3275. *)
  3276. ok := TRUE;
  3277. (* Initialize local variables *)
  3278. ncod := 0;
  3279. nqcd := 0;
  3280. npoc := 0;
  3281. ncomp := decSpec.imgInfo.ncomp;
  3282. NEW(ncoc, ncomp);
  3283. NEW(nqcc, ncomp);
  3284. NEW(nrgn, ncomp);
  3285. Machine.Fill32(ADDRESSOF(ncoc[0]), ncomp*SIZEOF(LONGINT), 0);
  3286. Machine.Fill32(ADDRESSOF(nqcc[0]), ncomp*SIZEOF(LONGINT), 0);
  3287. Machine.Fill32(ADDRESSOF(nrgn[0]), ncomp*SIZEOF(LONGINT), 0);
  3288. pptUsed := FALSE;
  3289. pptFirst := NIL;
  3290. pptLast := NIL;
  3291. (* Start position of this SOT segment (before marker) *)
  3292. sPos := s.Pos() - 2;
  3293. lsot := s.Net16();
  3294. tileIdx := s.Net16(); (* isot *)
  3295. psot := s.Net32(); (* TODO: Problem occurs if psot >= 2^31 *)
  3296. s.Char(ch);
  3297. partIdx := ORD(ch); (* tpsot *)
  3298. s.Char(ch);
  3299. nparts := ORD(ch); (* tnsot *)
  3300. IF (ntilePartsAvailable[tileIdx] = 0) & (nparts # 0) THEN
  3301. ntilePartsAvailable[tileIdx] := nparts;
  3302. END;
  3303. (* Check segment length *)
  3304. (*
  3305. NOTE: sPos + 2 is the position after the SOT marker
  3306. *)
  3307. IF (s.Pos() - (sPos + 2)) # lsot THEN
  3308. (* The segment length signalled was not correct *)
  3309. KernelLog.String("WARNING: Segment length signalled in SOT segment was wrong. ");
  3310. KernelLog.String("Trying to read further anyway");
  3311. KernelLog.Ln();
  3312. END;
  3313. curMarker := s.Net16();
  3314. WHILE ok & (curMarker # SOD) DO
  3315. CASE curMarker OF
  3316. | COD :
  3317. ok := ReadCODSegment(cstyle, cics);
  3318. decSpec.cics[tileIdx] := cics;
  3319. FOR i := 0 TO ncomp - 1 DO
  3320. IF ncoc[i] = 0 THEN
  3321. decSpec.cstyle[tileIdx][i] := cstyle;
  3322. END;
  3323. END;
  3324. INC(ncod);
  3325. | COC :
  3326. ok := ReadCOCSegment(cstyle, comp);
  3327. (* We need to add the check here, since 'comp' could be beyond of the valid range *)
  3328. IF ok THEN
  3329. decSpec.cstyle[tileIdx][comp] := cstyle;
  3330. INC(ncoc[comp]);
  3331. END;
  3332. | RGN :
  3333. ok := ReadRGNSegment(roiShift, comp);
  3334. (* We need to add the check here, since 'comp' could be beyond of the valid range *)
  3335. IF ok THEN
  3336. decSpec.roiShift[tileIdx][comp] := roiShift;
  3337. INC(nrgn[comp]);
  3338. END;
  3339. | QCD :
  3340. ok := ReadQCDSegment(quant);
  3341. FOR i := 0 TO ncomp - 1 DO
  3342. IF nqcc[i] = 0 THEN
  3343. decSpec.quant[tileIdx][i] := quant;
  3344. END;
  3345. END;
  3346. INC(nqcd);
  3347. | QCC :
  3348. ok := ReadQCCSegment(quant, comp);
  3349. (* We need to add the check here, since 'comp' could be beyond of the valid range *)
  3350. IF ok THEN
  3351. decSpec.quant[tileIdx][comp] := quant;
  3352. INC(nqcc[comp]);
  3353. END;
  3354. | POC :
  3355. ok := ReadPOCSegment(changes);
  3356. (* Set the new end values for the current progression (= start values of new progression) *)
  3357. IF progChanges = NIL THEN
  3358. nt := decSpec.imgInfo.nt;
  3359. NEW(progChanges, nt);
  3360. END;
  3361. progChanges[tileIdx] := changes;
  3362. INC(npoc);
  3363. | PLT :
  3364. ok := ReadPLTSegment();
  3365. | PPT :
  3366. ok := ReadPPTSegment(pptFirst, pptLast);
  3367. pptUsed := TRUE;
  3368. | COM :
  3369. ok := ReadCOMSegment();
  3370. ELSE
  3371. KernelLog.String("Unexpected/Invalid marker found in tile-part header (0x");
  3372. KernelLog.Hex(curMarker, 0);
  3373. KernelLog.String(")");
  3374. KernelLog.Ln();
  3375. ok := FALSE;
  3376. END;
  3377. curMarker := s.Net16();
  3378. END;
  3379. IF partIdx = 0 THEN
  3380. nmax := 1;
  3381. ELSE
  3382. nmax := 0;
  3383. END;
  3384. (* Constraint checks *)
  3385. IF ncod > nmax THEN
  3386. KernelLog.String("ERROR: Found ");
  3387. KernelLog.Int(ncod, 0);
  3388. KernelLog.String(" COD segments in header of tile-part ");
  3389. KernelLog.Int(partIdx, 0);
  3390. KernelLog.String(" of tile ");
  3391. KernelLog.Int(tileIdx, 0);
  3392. KernelLog.String(" (at most ");
  3393. KernelLog.Int(nmax, 0);
  3394. KernelLog.String(" allowed)");
  3395. KernelLog.Ln();
  3396. ok := FALSE;
  3397. END;
  3398. IF nqcd > nmax THEN
  3399. KernelLog.String("ERROR: Found ");
  3400. KernelLog.Int(nqcd, 0);
  3401. KernelLog.String(" QCD segments in header of tile-part ");
  3402. KernelLog.Int(partIdx, 0);
  3403. KernelLog.String(" of tile ");
  3404. KernelLog.Int(tileIdx, 0);
  3405. KernelLog.String(" (at most ");
  3406. KernelLog.Int(nmax, 0);
  3407. KernelLog.String(" allowed)");
  3408. KernelLog.Ln();
  3409. ok := FALSE;
  3410. END;
  3411. IF npoc > 1 THEN
  3412. KernelLog.String("ERROR: Found ");
  3413. KernelLog.Int(npoc, 0);
  3414. KernelLog.String(" POC segments in header of tile-part ");
  3415. KernelLog.Int(partIdx, 0);
  3416. KernelLog.String(" of tile ");
  3417. KernelLog.Int(tileIdx, 0);
  3418. KernelLog.String(" (at most 1 allowed)");
  3419. KernelLog.Ln();
  3420. ok := FALSE;
  3421. END;
  3422. (* Check cardinality constraints of component-specific segments *)
  3423. FOR i := 0 TO ncomp - 1 DO
  3424. IF ncoc[i] > nmax THEN
  3425. KernelLog.String("ERROR: Found ");
  3426. KernelLog.Int(ncoc[i], 0);
  3427. KernelLog.String(" COC segments for component ");
  3428. KernelLog.Int(i, 0);
  3429. KernelLog.String(" in header of tile-part ");
  3430. KernelLog.Int(partIdx, 0);
  3431. KernelLog.String(" of tile ");
  3432. KernelLog.Int(tileIdx, 0);
  3433. KernelLog.String(" (at most ");
  3434. KernelLog.Int(nmax, 0);
  3435. KernelLog.String(" per component allowed )");
  3436. KernelLog.Ln();
  3437. ok := FALSE;
  3438. END;
  3439. IF nqcc[i] > nmax THEN
  3440. KernelLog.String("ERROR: Found ");
  3441. KernelLog.Int(nqcc[i], 0);
  3442. KernelLog.String(" QCC segments for component ");
  3443. KernelLog.Int(i, 0);
  3444. KernelLog.String(" in header of tile-part ");
  3445. KernelLog.Int(partIdx, 0);
  3446. KernelLog.String(" of tile ");
  3447. KernelLog.Int(tileIdx, 0);
  3448. KernelLog.String(" (at most ");
  3449. KernelLog.Int(nmax, 0);
  3450. KernelLog.String(" per component allowed )");
  3451. KernelLog.Ln();
  3452. ok := FALSE;
  3453. END;
  3454. IF nrgn[i] > nmax THEN
  3455. KernelLog.String("ERROR: Found ");
  3456. KernelLog.Int(nrgn[i], 0);
  3457. KernelLog.String(" RGN segments for component ");
  3458. KernelLog.Int(i, 0);
  3459. KernelLog.String(" in header of tile-part ");
  3460. KernelLog.Int(partIdx, 0);
  3461. KernelLog.String(" of tile ");
  3462. KernelLog.Int(tileIdx, 0);
  3463. KernelLog.String(" (at most ");
  3464. KernelLog.Int(nmax, 0);
  3465. KernelLog.String(" per component allowed )");
  3466. KernelLog.Ln();
  3467. ok := FALSE;
  3468. END;
  3469. END;
  3470. IF pptUsed & ppmUsed THEN
  3471. KernelLog.String("ERROR: Both PPM and PPT marker segments used in codestream");
  3472. KernelLog.Ln();
  3473. ok := FALSE;
  3474. END;
  3475. IF ok THEN
  3476. (* End position of this SOT segment (just after the SOD marker has been read) *)
  3477. ePos := s.Pos();
  3478. IF psot = 0 THEN
  3479. (*
  3480. The standard states that if psot = 0 then it is supposed that
  3481. all remaining data in the codestream (except the EOC marker)
  3482. belongs to this tile-part
  3483. *)
  3484. partRem := s.Available() - 2; (* TODO: maybe s.Available() < stream length ? *)
  3485. ELSE
  3486. partRem := psot - (ePos - sPos);
  3487. END;
  3488. (* Set values *)
  3489. SELF.curTile := tileIdx;
  3490. SELF.curPart := partIdx;
  3491. IF pptUsed THEN
  3492. pktDec.SetPPHeadersTile (pptFirst, pptLast, curTile);
  3493. END;
  3494. END;
  3495. RETURN ok;
  3496. END ReadSOTSegment;
  3497. PROCEDURE ReadSIZSegment(VAR imgInfo : ImageInfo) : BOOLEAN;
  3498. VAR
  3499. rsiz, lsiz, i, ssizInt, sPos, ePos : LONGINT;
  3500. ssiz, ch : CHAR;
  3501. BEGIN
  3502. (*
  3503. IF s.Available() < 36 THEN
  3504. KernelLog.String("ERROR: SIZ segment shorter than 38 bytes");
  3505. KernelLog.Ln();
  3506. RETURN FALSE;
  3507. END;
  3508. *)
  3509. sPos := s.Pos();
  3510. lsiz := s.Net16();
  3511. rsiz := s.Net16();
  3512. IF rsiz # 0000H THEN
  3513. KernelLog.String("ERROR: Decoder currently only has capabilities specified in JPEG 2000 - Part 1");
  3514. KernelLog.Ln();
  3515. RETURN FALSE;
  3516. END;
  3517. NEW(imgInfo);
  3518. imgInfo.xsiz := s.Net32(); (* TODO: Problem occurs if xsiz >= 2^31 *)
  3519. imgInfo.ysiz := s.Net32();
  3520. imgInfo.xos := s.Net32();
  3521. imgInfo.yos := s.Net32();
  3522. imgInfo.xt := s.Net32();
  3523. imgInfo.yt := s.Net32();
  3524. imgInfo.xtos := s.Net32();
  3525. imgInfo.ytos := s.Net32();
  3526. imgInfo.ncomp := s.Net16();
  3527. imgInfo.nxt := (imgInfo.xsiz - imgInfo.xtos + imgInfo.xt - 1) DIV imgInfo.xt;
  3528. imgInfo.nyt := (imgInfo.ysiz - imgInfo.ytos + imgInfo.yt - 1) DIV imgInfo.yt;
  3529. imgInfo.nt := imgInfo.nyt*imgInfo.nxt;
  3530. (* Do some checks *)
  3531. IF imgInfo.GetImgWidth(0) > MAX_IMG_WIDTH THEN
  3532. KernelLog.String("ERROR: Image width too large");
  3533. KernelLog.Ln();
  3534. RETURN FALSE;
  3535. END;
  3536. IF imgInfo.GetImgHeight(0) > MAX_IMG_HEIGHT THEN
  3537. KernelLog.String("ERROR: Image height too large");
  3538. KernelLog.Ln();
  3539. RETURN FALSE;
  3540. END;
  3541. IF imgInfo.GetNumTiles() > MAX_TILES THEN
  3542. KernelLog.String("ERROR: Too many tiles");
  3543. KernelLog.Ln();
  3544. RETURN FALSE;
  3545. END;
  3546. IF imgInfo.GetNumComponents() > MAX_COMPONENTS THEN
  3547. KernelLog.String("ERROR: Too many image components");
  3548. KernelLog.Ln();
  3549. RETURN FALSE;
  3550. END;
  3551. NEW(imgInfo.comps, imgInfo.ncomp);
  3552. FOR i := 0 TO imgInfo.ncomp - 1 DO
  3553. NEW(imgInfo.comps[i]);
  3554. s.Char(ssiz);
  3555. ssizInt := ORD(ssiz);
  3556. IF (SYSTEM.VAL(SET, ssizInt) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 00000080H))) # {} THEN
  3557. imgInfo.comps[i].signed := TRUE;
  3558. ELSE
  3559. imgInfo.comps[i].signed := FALSE;
  3560. END;
  3561. imgInfo.comps[i].depth := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ssizInt) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0000007FH))) + 1;
  3562. s.Char(ch);
  3563. imgInfo.comps[i].subsx := ORD(ch);
  3564. s.Char(ch);
  3565. imgInfo.comps[i].subsy := ORD(ch);
  3566. END;
  3567. ePos := s.Pos();
  3568. (* Check segment length *)
  3569. IF (ePos - sPos) # lsiz THEN
  3570. (* The segment length signalled was not correct *)
  3571. KernelLog.String("WARNING: Segment length signalled in SIZ segment was wrong. ");
  3572. KernelLog.String("Trying to read further anyway");
  3573. KernelLog.Ln();
  3574. END;
  3575. RETURN TRUE;
  3576. END ReadSIZSegment;
  3577. PROCEDURE ReadCODSegment (VAR cod : CodingStyle; VAR cics : CICodingStyle) : BOOLEAN;
  3578. VAR
  3579. lcod, nl, i, scodInt, cblsInt, precsizInt, sPos, ePos : LONGINT;
  3580. scod, prog, mct, ndec, cblw, cblh, cbls, trans, precsiz: CHAR;
  3581. tmpCod : CodingStyle;
  3582. tmpCics : CICodingStyle;
  3583. BEGIN
  3584. (*
  3585. IF s.Available() < 12 THEN
  3586. KernelLog.String("ERROR: COD segment shorter than 12 bytes");
  3587. KernelLog.Ln();
  3588. RETURN FALSE;
  3589. END;
  3590. *)
  3591. sPos := s.Pos();
  3592. lcod := s.Net16();
  3593. s.Char(scod);
  3594. (* --- SGcod --- *)
  3595. s.Char(prog);
  3596. nl := s.Net16();
  3597. (* Check number of layers *)
  3598. IF nl > MAX_LAYERS THEN
  3599. KernelLog.String("ERROR: Too many layers");
  3600. KernelLog.Ln();
  3601. RETURN FALSE;
  3602. END;
  3603. s.Char(mct);
  3604. (* --- SPcod --- *)
  3605. s.Char(ndec);
  3606. s.Char(cblw);
  3607. s.Char(cblh);
  3608. s.Char(cbls);
  3609. s.Char(trans);
  3610. NEW(tmpCics);
  3611. NEW(tmpCod);
  3612. tmpCics.po := ORD(prog);
  3613. tmpCics.nl := nl;
  3614. IF tmpCics.po > 5 THEN
  3615. KernelLog.String("ERROR: Invalid progression order: 0x");
  3616. KernelLog.Hex(tmpCics.po, -1);
  3617. KernelLog.Ln();
  3618. RETURN FALSE;
  3619. END;
  3620. tmpCics.mct := ORD(mct);
  3621. IF tmpCics.mct > 1 THEN
  3622. KernelLog.String("ERROR: Invalid value for multiple component transformation: 0x");
  3623. KernelLog.Hex(tmpCics.mct, -1);
  3624. KernelLog.Ln();
  3625. RETURN FALSE;
  3626. END;
  3627. scodInt := ORD(scod);
  3628. tmpCod.maxps := ~ODD(scodInt);
  3629. tmpCics.sop := ODD(LSH(scodInt, -1));
  3630. tmpCics.eph := ODD(LSH(scodInt, -2));
  3631. tmpCod.ndec := ORD(ndec);
  3632. IF tmpCod.ndec > 32 THEN
  3633. KernelLog.String("ERROR: Invalid number of decomposition levels");
  3634. KernelLog.Ln();
  3635. RETURN FALSE;
  3636. END;
  3637. tmpCod.cblw := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ORD(cblw)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0000000FH))) + 2;
  3638. tmpCod.cblh := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ORD(cblh)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0000000FH))) + 2;
  3639. IF ((tmpCod.cblw > 10) OR (tmpCod.cblh > 10)) OR (tmpCod.cblw + tmpCod.cblh > 12) THEN
  3640. KernelLog.String("ERROR: Invalid code-block width or height exponent: width exp. = ");
  3641. KernelLog.Int(tmpCod.cblw, 0);
  3642. KernelLog.String(", heigth exp. = ");
  3643. KernelLog.Int(tmpCod.cblh, 0);
  3644. KernelLog.Ln();
  3645. RETURN FALSE;
  3646. END;
  3647. cblsInt := ORD(cbls);
  3648. tmpCod.selcb := ODD(cblsInt);
  3649. tmpCod.rescp := ODD(LSH(cblsInt, -1));
  3650. tmpCod.term := ODD(LSH(cblsInt, -2));
  3651. tmpCod.vert := ODD(LSH(cblsInt, -3));
  3652. tmpCod.pred := ODD(LSH(cblsInt, -4));
  3653. tmpCod.segs := ODD(LSH(cblsInt, -5));
  3654. tmpCod.trans := ORD(trans);
  3655. IF ~tmpCod.maxps THEN
  3656. NEW(tmpCod.precs, tmpCod.ndec + 1);
  3657. (* precinct sizes are defined next in the codestream *)
  3658. FOR i := 0 TO tmpCod.ndec DO
  3659. s.Char(precsiz);
  3660. precsizInt := ORD(precsiz);
  3661. tmpCod.precs[i].ppx := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, precsizInt) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0000000FH)));
  3662. tmpCod.precs[i].ppy := LSH(precsizInt, -4);
  3663. END;
  3664. END;
  3665. cics := tmpCics;
  3666. cod := tmpCod;
  3667. ePos := s.Pos();
  3668. (* Check segment length *)
  3669. IF (ePos - sPos) # lcod THEN
  3670. (* The segment length signalled was not correct *)
  3671. KernelLog.String("WARNING: Segment length signalled in COD segment was wrong. ");
  3672. KernelLog.String("Trying to read further anyway");
  3673. KernelLog.Ln();
  3674. END;
  3675. RETURN TRUE;
  3676. END ReadCODSegment;
  3677. PROCEDURE ReadCOCSegment(VAR coc : CodingStyle; VAR comp : LONGINT) : BOOLEAN;
  3678. VAR
  3679. lcoc, ccoc, i, scocInt, cblsInt, precsizInt, sPos, ePos, ncomp : LONGINT;
  3680. ccocByte, scoc, ndec, cblw, cblh, cbls, trans, precsiz: CHAR;
  3681. tmpCoc : CodingStyle;
  3682. BEGIN
  3683. (*
  3684. IF s.Available() < 9 THEN
  3685. KernelLog.String("ERROR: COC segment shorter than 9 bytes");
  3686. KernelLog.Ln();
  3687. RETURN FALSE;
  3688. END;
  3689. *)
  3690. ncomp := decSpec.imgInfo.ncomp;
  3691. sPos := s.Pos();
  3692. lcoc := s.Net16();
  3693. (* --- Ccoc --- *)
  3694. IF ncomp < 257 THEN
  3695. s.Char(ccocByte);
  3696. ccoc := ORD(ccocByte);
  3697. ELSE
  3698. ccoc := s.Net16();
  3699. END;
  3700. IF ccoc >= ncomp THEN
  3701. KernelLog.String("ERROR (CodeStreamReader.ReadCOCSegment) : Ccoc parameter out of valid range");
  3702. KernelLog.Ln();
  3703. RETURN FALSE;
  3704. END;
  3705. (* --- Scoc --- *)
  3706. s.Char(scoc);
  3707. (* --- SPcoc --- *)
  3708. s.Char(ndec);
  3709. s.Char(cblw);
  3710. s.Char(cblh);
  3711. s.Char(cbls);
  3712. s.Char(trans);
  3713. NEW(tmpCoc);
  3714. scocInt := ORD(scoc);
  3715. IF scocInt = 0 THEN
  3716. tmpCoc.maxps := TRUE;
  3717. ELSIF scocInt = 1 THEN
  3718. tmpCoc.maxps := FALSE;
  3719. ELSE
  3720. KernelLog.String( "ERROR (CodestreamReader.ReadCOCSegment) : Invalid value for coding style parameter read (concerning precinct sizes)");
  3721. KernelLog.Ln();
  3722. RETURN FALSE;
  3723. END;
  3724. tmpCoc.ndec := ORD(ndec);
  3725. IF tmpCoc.ndec > 32 THEN
  3726. KernelLog.String("ERROR (CodestreamReader.ReadCOCSegment) : Invalid number of decomposition levels");
  3727. KernelLog.Ln();
  3728. RETURN FALSE;
  3729. END;
  3730. tmpCoc.cblw := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ORD(cblw)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0000000FH))) + 2;
  3731. tmpCoc.cblh := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ORD(cblh)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0000000FH))) + 2;
  3732. IF ((tmpCoc.cblw > 10) OR (tmpCoc.cblh > 10)) OR (tmpCoc.cblw + tmpCoc.cblh > 12) THEN
  3733. KernelLog.String("ERROR (CodestreamReader.ReadCOCSegment) : Invalid code-block width or height exponent: width exp. = ");
  3734. KernelLog.Int(tmpCoc.cblw, 0);
  3735. KernelLog.String(", heigth exp. = ");
  3736. KernelLog.Int(tmpCoc.cblh, 0);
  3737. KernelLog.Ln();
  3738. RETURN FALSE;
  3739. END;
  3740. cblsInt := ORD(cbls);
  3741. tmpCoc.selcb := ODD(cblsInt);
  3742. tmpCoc.rescp := ODD(LSH(cblsInt, -1));
  3743. tmpCoc.term := ODD(LSH(cblsInt, -2));
  3744. tmpCoc.vert := ODD(LSH(cblsInt, -3));
  3745. tmpCoc.pred := ODD(LSH(cblsInt, -4));
  3746. tmpCoc.segs := ODD(LSH(cblsInt, -5));
  3747. tmpCoc.trans := ORD(trans);
  3748. IF ~tmpCoc.maxps THEN
  3749. NEW(tmpCoc.precs, tmpCoc.ndec + 1);
  3750. (* precinct sizes are defined next in the codestream *)
  3751. FOR i := 0 TO tmpCoc.ndec DO
  3752. s.Char(precsiz);
  3753. precsizInt := ORD(precsiz);
  3754. tmpCoc.precs[i].ppx := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, precsizInt) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0000000FH)));
  3755. tmpCoc.precs[i].ppy := LSH(precsizInt, -4);
  3756. END;
  3757. END;
  3758. comp := ccoc;
  3759. coc := tmpCoc;
  3760. ePos := s.Pos();
  3761. (* Check segment length *)
  3762. IF (ePos - sPos) # lcoc THEN
  3763. (* The segment length signalled was not correct *)
  3764. KernelLog.String("WARNING: Segment length signalled in COC segment was wrong. ");
  3765. KernelLog.String("Trying to read further anyway");
  3766. KernelLog.Ln();
  3767. END;
  3768. RETURN TRUE;
  3769. END ReadCOCSegment;
  3770. PROCEDURE ReadRGNSegment(VAR roiShift, comp : LONGINT) : BOOLEAN;
  3771. VAR
  3772. lrgn, crgn, sPos, ePos, ncomp : LONGINT;
  3773. crgnByte, srgn, sprgn : CHAR;
  3774. BEGIN
  3775. (*
  3776. IF s.Available() < 5 THEN
  3777. KernelLog.String("ERROR: RGN segment shorter than 4 bytes");
  3778. KernelLog.Ln();
  3779. RETURN FALSE;
  3780. END;
  3781. *)
  3782. ncomp := decSpec.imgInfo.ncomp;
  3783. sPos := s.Pos();
  3784. lrgn := s.Net16();
  3785. IF ncomp < 257 THEN
  3786. s.Char(crgnByte);
  3787. crgn := ORD(crgnByte);
  3788. ELSE
  3789. crgn := s.Net16();
  3790. END;
  3791. IF crgn >= ncomp THEN
  3792. KernelLog.String("ERROR (CodeStreamReader.ReadRGNSegment) : Crgn parameter out of valid range");
  3793. KernelLog.Ln();
  3794. RETURN FALSE;
  3795. END;
  3796. s.Char(srgn);
  3797. IF ORD(srgn) # 0 THEN
  3798. KernelLog.String("ERROR (CodestreamReader.ReadRGNSegment): Invalid ROI style");
  3799. KernelLog.Ln();
  3800. RETURN FALSE;
  3801. END;
  3802. s.Char(sprgn);
  3803. roiShift := ORD(sprgn);
  3804. comp := crgn;
  3805. ePos := s.Pos();
  3806. (* Check segment length *)
  3807. IF (ePos - sPos) # lrgn THEN
  3808. (* The segment length signalled was not correct *)
  3809. KernelLog.String("WARNING: Segment length signalled in RGN segment was wrong. ");
  3810. KernelLog.String("Trying to read further anyway");
  3811. KernelLog.Ln();
  3812. END;
  3813. RETURN TRUE;
  3814. END ReadRGNSegment;
  3815. PROCEDURE ReadQCDSegment(VAR quant : Quantization) : BOOLEAN;
  3816. VAR
  3817. lqcd, ssize, i, sqcdInt, sPos, ePos : LONGINT;
  3818. sqcd, ch : CHAR;
  3819. tmp : Quantization;
  3820. BEGIN
  3821. (*
  3822. IF s.Available() < 4 THEN
  3823. KernelLog.String("ERROR: QCD segment shorter than 4 bytes");
  3824. KernelLog.Ln();
  3825. RETURN FALSE;
  3826. END;
  3827. *)
  3828. sPos := s.Pos();
  3829. lqcd := s.Net16();
  3830. s.Char(sqcd);
  3831. sqcdInt := ORD(sqcd);
  3832. NEW(tmp);
  3833. tmp.style := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, sqcdInt) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0000001FH)));
  3834. tmp.nguardb := LSH(sqcdInt, -5);
  3835. CASE tmp.style OF
  3836. NOQUANT :
  3837. (* We just have an exponent, no mantissa *)
  3838. tmp.nstepsiz := lqcd-3;
  3839. NEW(tmp.stepsiz, tmp.nstepsiz);
  3840. FOR i := 0 TO tmp.nstepsiz - 1 DO
  3841. NEW(tmp.stepsiz[i]);
  3842. tmp.stepsiz[i].mant := 0;
  3843. s.Char(ch);
  3844. tmp.stepsiz[i].exp := LSH(ORD(ch), -3);
  3845. END;
  3846. | QUANT_DER :
  3847. (* Only the values for the NL-LL subband are signalled *)
  3848. tmp.nstepsiz := 1;
  3849. NEW(tmp.stepsiz, 1);
  3850. NEW(tmp.stepsiz[0]);
  3851. ssize := s.Net16();
  3852. tmp.stepsiz[0].mant := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ssize) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 000007FFH)));
  3853. tmp.stepsiz[0].exp := LSH(ssize, -11);
  3854. | QUANT_EXP :
  3855. (* There are as many step sizes signalled as there ae subbands *)
  3856. tmp.nstepsiz := (lqcd-3) DIV 2;
  3857. NEW(tmp.stepsiz, tmp.nstepsiz);
  3858. FOR i := 0 TO tmp.nstepsiz - 1 DO
  3859. NEW(tmp.stepsiz[i]);
  3860. ssize := s.Net16();
  3861. tmp.stepsiz[i].mant := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ssize) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 000007FFH)));
  3862. tmp.stepsiz[i].exp := LSH(ssize, -11);
  3863. END;
  3864. ELSE
  3865. KernelLog.String("ERROR: Invalid quantization style in QCD segment : 0x");
  3866. KernelLog.Hex(tmp.style, -1);
  3867. KernelLog.Ln();
  3868. RETURN FALSE;
  3869. END;
  3870. quant := tmp;
  3871. ePos := s.Pos();
  3872. (* Check segment length *)
  3873. IF (ePos - sPos) # lqcd THEN
  3874. (* The segment length signalled was not correct *)
  3875. KernelLog.String("WARNING: Segment length signalled in QCD segment was wrong. ");
  3876. KernelLog.String("Trying to read further anyway");
  3877. KernelLog.Ln();
  3878. END;
  3879. RETURN TRUE;
  3880. END ReadQCDSegment;
  3881. PROCEDURE ReadQCCSegment(VAR quant : Quantization; VAR comp : LONGINT) : BOOLEAN;
  3882. VAR
  3883. lqcc, ssize, i, sqccInt, cqcc, cqccLen, sPos, ePos, ncomp : LONGINT;
  3884. sqcc, cqccByte, ch : CHAR;
  3885. tmp : Quantization;
  3886. BEGIN
  3887. (*
  3888. IF s.Available() < 5 THEN
  3889. KernelLog.String("ERROR: QCC segment shorter than 5 bytes");
  3890. KernelLog.Ln();
  3891. RETURN FALSE;
  3892. END;
  3893. *)
  3894. ncomp := decSpec.imgInfo.ncomp;
  3895. sPos := s.Pos();
  3896. lqcc := s.Net16();
  3897. (* --- Cqcc --- *)
  3898. IF decSpec.imgInfo.ncomp < 257 THEN
  3899. s.Char(cqccByte);
  3900. cqcc := ORD(cqccByte);
  3901. cqccLen := 1;
  3902. ELSE
  3903. cqcc := s.Net16();
  3904. cqccLen := 2;
  3905. END;
  3906. IF cqcc >= ncomp THEN
  3907. KernelLog.String("ERROR (CodeStreamReader.ReadQCCSegment) : Cqcc parameter out of valid range");
  3908. KernelLog.Ln();
  3909. RETURN FALSE;
  3910. END;
  3911. s.Char(sqcc);
  3912. sqccInt := ORD(sqcc);
  3913. NEW(tmp);
  3914. tmp.style := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, sqccInt) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0000001FH)));
  3915. tmp.nguardb := LSH(sqccInt, -5);
  3916. CASE tmp.style OF
  3917. NOQUANT :
  3918. (* We just have an exponent, no mantissa *)
  3919. tmp.nstepsiz := lqcc - (3 + cqccLen);
  3920. NEW(tmp.stepsiz, tmp.nstepsiz);
  3921. FOR i := 0 TO tmp.nstepsiz - 1 DO
  3922. NEW(tmp.stepsiz[i]);
  3923. tmp.stepsiz[i].mant := 0;
  3924. s.Char(ch);
  3925. tmp.stepsiz[i].exp := LSH(ORD(ch), -3);
  3926. END;
  3927. | QUANT_DER :
  3928. (* Only the values for the NL-LL subband are signalled *)
  3929. tmp.nstepsiz := 1;
  3930. NEW(tmp.stepsiz, 1);
  3931. NEW(tmp.stepsiz[0]);
  3932. ssize := s.Net16();
  3933. tmp.stepsiz[0].mant := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ssize) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 000007FFH)));
  3934. tmp.stepsiz[0].exp := LSH(ssize, -11);
  3935. | QUANT_EXP :
  3936. (* There are as many step sizes signalled as there ae subbands *)
  3937. tmp.nstepsiz := (lqcc - (3 + cqccLen)) DIV 2;
  3938. NEW(tmp.stepsiz, tmp.nstepsiz);
  3939. FOR i := 0 TO tmp.nstepsiz - 1 DO
  3940. NEW(tmp.stepsiz[i]);
  3941. ssize := s.Net16();
  3942. tmp.stepsiz[i].mant := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ssize) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 000007FFH)));
  3943. tmp.stepsiz[i].exp := LSH(ssize, -11);
  3944. END;
  3945. ELSE
  3946. KernelLog.String("ERROR: Invalid quantization style in QCC segment : 0x");
  3947. KernelLog.Hex(tmp.style, -1);
  3948. KernelLog.Ln();
  3949. RETURN FALSE;
  3950. END;
  3951. comp := cqcc;
  3952. quant := tmp;
  3953. ePos := s.Pos();
  3954. (* Check segment length *)
  3955. IF (ePos - sPos) # lqcc THEN
  3956. (* The segment length signalled was not correct *)
  3957. KernelLog.String("WARNING: Segment length signalled in QCC segment was wrong. ");
  3958. KernelLog.String("Trying to read further anyway");
  3959. KernelLog.Ln();
  3960. END;
  3961. RETURN TRUE;
  3962. END ReadQCCSegment;
  3963. PROCEDURE ReadPOCSegment(VAR changes : ProgChangeArrayPtr) : BOOLEAN;
  3964. VAR
  3965. nchanges, lpoc, i, sPos, ePos : LONGINT;
  3966. rspoc, repoc, cspocByte, cepocByte, ppoc : CHAR;
  3967. twoBytes : BOOLEAN;
  3968. BEGIN
  3969. (*
  3970. IF s.Available() < 2 THEN
  3971. KernelLog.String("ERROR: POC segment shorter than 2 bytes");
  3972. KernelLog.Ln();
  3973. RETURN FALSE;
  3974. END;
  3975. *)
  3976. sPos := s.Pos();
  3977. lpoc := s.Net16();
  3978. IF decSpec.imgInfo.ncomp < 257 THEN
  3979. nchanges := (lpoc - 2) DIV 7;
  3980. twoBytes := FALSE;
  3981. ELSE
  3982. nchanges := (lpoc - 2) DIV 9;
  3983. twoBytes := TRUE;
  3984. END;
  3985. NEW(changes, nchanges);
  3986. FOR i := 0 TO nchanges - 1 DO
  3987. (* --- RSpoc i --- *)
  3988. s.Char(rspoc);
  3989. changes[i].startRes := ORD(rspoc);
  3990. (* --- CSpoc i --- *)
  3991. IF twoBytes THEN
  3992. changes[i].startComp := s.Net16();
  3993. ELSE
  3994. s.Char(cspocByte);
  3995. changes[i].startComp := ORD(cspocByte);
  3996. END;
  3997. (* --- LYEpoc i --- *)
  3998. changes[i].endLay := s.Net16();
  3999. (* --- REpoc i --- *)
  4000. s.Char(repoc);
  4001. changes[i].endRes := ORD(repoc);
  4002. (* --- CEpoc i --- *)
  4003. IF twoBytes THEN
  4004. changes[i].endComp := s.Net16();
  4005. ELSE
  4006. s.Char(cepocByte);
  4007. changes[i].endComp := ORD(cepocByte);
  4008. END;
  4009. (* --- Ppoc i --- *)
  4010. s.Char(ppoc);
  4011. changes[i].progOrder := ORD(ppoc);
  4012. END;
  4013. ePos := s.Pos();
  4014. (* Check segment length *)
  4015. IF (ePos - sPos) # lpoc THEN
  4016. (* The segment length signalled was not correct *)
  4017. KernelLog.String("WARNING: Segment length signalled in POC segment was wrong. ");
  4018. KernelLog.String("Trying to read further anyway");
  4019. KernelLog.Ln();
  4020. END;
  4021. RETURN TRUE;
  4022. END ReadPOCSegment;
  4023. (* NOTE: We just skip this segment *)
  4024. PROCEDURE ReadTLMSegment() : BOOLEAN;
  4025. VAR
  4026. ltlm : LONGINT;
  4027. BEGIN
  4028. (*
  4029. IF s.Available() < 4 THEN
  4030. KernelLog.String("ERROR: TLM segment shorter than 4 bytes");
  4031. KernelLog.Ln();
  4032. RETURN FALSE;
  4033. END;
  4034. *)
  4035. ltlm := s.Net16();
  4036. (* Skip the segment *)
  4037. s.SkipBytes(ltlm - 2);
  4038. KernelLog.String("NOTICE: Found a TLM segment -> skipping it");
  4039. KernelLog.Ln();
  4040. RETURN TRUE;
  4041. END ReadTLMSegment;
  4042. (* NOTE: We just skip this segment *)
  4043. PROCEDURE ReadPLMSegment() : BOOLEAN;
  4044. VAR
  4045. lplm : LONGINT;
  4046. BEGIN
  4047. (*
  4048. IF s.Available() < 3 THEN
  4049. KernelLog.String("ERROR: PLM segment shorter than 3 bytes");
  4050. KernelLog.Ln();
  4051. RETURN FALSE;
  4052. END;
  4053. *)
  4054. lplm := s.Net16();
  4055. (* Skip the segment *)
  4056. s.SkipBytes(lplm - 2);
  4057. KernelLog.String("NOTICE: Found a PLM segment -> skipping it");
  4058. KernelLog.Ln();
  4059. RETURN TRUE;
  4060. END ReadPLMSegment;
  4061. (* NOTE: We just skip this segment *)
  4062. PROCEDURE ReadPLTSegment() : BOOLEAN;
  4063. VAR
  4064. lplt : LONGINT;
  4065. BEGIN
  4066. (*
  4067. IF s.Available() < 3 THEN
  4068. KernelLog.String("ERROR: PLT segment shorter than 3 bytes");
  4069. KernelLog.Ln();
  4070. RETURN FALSE;
  4071. END;
  4072. *)
  4073. lplt := s.Net16();
  4074. (* Skip the segment *)
  4075. s.SkipBytes(lplt - 2);
  4076. KernelLog.String("NOTICE: Found a PLT segment -> skipping it");
  4077. KernelLog.Ln();
  4078. RETURN TRUE;
  4079. END ReadPLTSegment;
  4080. PROCEDURE ReadPPMSegment(VAR first, last : DataListElement; VAR nppmLeft, nppmRead : LONGINT) : BOOLEAN;
  4081. VAR
  4082. lppm, len, actLen, sPos, ePos, bytesLeft : LONGINT;
  4083. dummy, curElem, newElem : DataListElement;
  4084. zppm : CHAR;
  4085. BEGIN
  4086. (*
  4087. IF s.Available() < 3 THEN
  4088. KernelLog.String("ERROR: PPM segment shorter than 3 bytes");
  4089. KernelLog.Ln();
  4090. RETURN FALSE;
  4091. END;
  4092. *)
  4093. sPos := s.Pos();
  4094. lppm := s.Net16();
  4095. s.Char(zppm);
  4096. IF first = NIL THEN
  4097. NEW(dummy);
  4098. dummy.next := NIL;
  4099. curElem := dummy;
  4100. ELSE
  4101. curElem := last;
  4102. END;
  4103. bytesLeft := lppm - 3;
  4104. WHILE bytesLeft > 0 DO
  4105. (* We have to check wether all packet headers for the last tile-part have been read in the preceding PPM segment *)
  4106. IF nppmLeft <= 0 THEN
  4107. (* The next 4 bytes contain information on how many bytes are used to represent all packet headers of the next tile-part *)
  4108. nppmLeft := s.Net32();
  4109. NEW(newElem);
  4110. NEW(newElem.data, nppmLeft);
  4111. newElem.next := NIL;
  4112. curElem.next := newElem;
  4113. curElem := newElem;
  4114. nppmRead := 0;
  4115. DEC(bytesLeft, 4);
  4116. END;
  4117. IF bytesLeft < nppmLeft THEN
  4118. len := bytesLeft;
  4119. ELSE
  4120. len := nppmLeft;
  4121. END;
  4122. s.Bytes(curElem.data^, nppmRead, len, actLen);
  4123. INC(nppmRead, actLen);
  4124. DEC(nppmLeft, actLen);
  4125. DEC(bytesLeft, actLen);
  4126. END;
  4127. IF first = NIL THEN
  4128. first := dummy.next;
  4129. END;
  4130. last := curElem;
  4131. ePos := s.Pos();
  4132. (* Check segment length *)
  4133. IF (ePos - sPos) # lppm THEN
  4134. (* The segment length signalled was not correct *)
  4135. KernelLog.String("WARNING: Segment length signalled in PPM segment was wrong. ");
  4136. KernelLog.String("Trying to read further anyway");
  4137. KernelLog.Ln();
  4138. END;
  4139. RETURN TRUE;
  4140. END ReadPPMSegment;
  4141. PROCEDURE ReadPPTSegment(VAR first, last : DataListElement) : BOOLEAN;
  4142. VAR
  4143. lppt, actLen, sPos, ePos, bytesLeft : LONGINT;
  4144. zppt : CHAR;
  4145. newElem : DataListElement;
  4146. BEGIN
  4147. (*
  4148. IF s.Available() < 3 THEN
  4149. KernelLog.String("ERROR: PPT segment shorter than 3 bytes");
  4150. KernelLog.Ln();
  4151. RETURN FALSE;
  4152. END;
  4153. *)
  4154. sPos := s.Pos();
  4155. lppt := s.Net16();
  4156. s.Char(zppt);
  4157. IF first = NIL THEN
  4158. NEW(first);
  4159. last := first;
  4160. newElem := first;
  4161. ELSE
  4162. NEW(last.next);
  4163. last := last.next;
  4164. newElem := last;
  4165. END;
  4166. bytesLeft := lppt - 3;
  4167. NEW(newElem.data, bytesLeft);
  4168. newElem.next := NIL;
  4169. WHILE bytesLeft > 0 DO
  4170. s.Bytes(newElem.data^, 0, bytesLeft, actLen);
  4171. DEC(bytesLeft, actLen);
  4172. END;
  4173. ePos := s.Pos();
  4174. (* Check segment length *)
  4175. IF (ePos - sPos) # lppt THEN
  4176. (* The segment length signalled was not correct *)
  4177. KernelLog.String("WARNING: Segment length signalled in PPT segment was wrong. ");
  4178. KernelLog.String("Trying to read further anyway");
  4179. KernelLog.Ln();
  4180. END;
  4181. RETURN TRUE;
  4182. END ReadPPTSegment;
  4183. (* NOTE: We just skip this segment *)
  4184. PROCEDURE ReadCRGSegment() : BOOLEAN;
  4185. VAR
  4186. lcrg : LONGINT;
  4187. BEGIN
  4188. (*
  4189. IF s.Available() < 2 THEN
  4190. KernelLog.String("ERROR: CRG segment shorter than 2 bytes");
  4191. KernelLog.Ln();
  4192. RETURN FALSE;
  4193. END;
  4194. *)
  4195. lcrg := s.Net16();
  4196. (* Skip the segment *)
  4197. s.SkipBytes(lcrg - 2);
  4198. KernelLog.String("NOTICE: Found a CRG segment -> skipping it");
  4199. KernelLog.Ln();
  4200. RETURN TRUE;
  4201. END ReadCRGSegment;
  4202. PROCEDURE ReadCOMSegment () : BOOLEAN;
  4203. VAR
  4204. lcom, rcom, i : LONGINT;
  4205. com : J2KU.ByteArrayPtr;
  4206. BEGIN
  4207. lcom := s.Net16();
  4208. rcom := s.Net16();
  4209. NEW(com, lcom - 3);
  4210. FOR i := 0 TO lcom - 5 DO
  4211. s.Char(com[i]);
  4212. END;
  4213. com[LEN(com)-1] := 0X;
  4214. IF printCOM THEN
  4215. KernelLog.String("JPEG2000 codestream comment [");
  4216. KernelLog.Ln();
  4217. KernelLog.String(" ");
  4218. KernelLog.String(com^);
  4219. KernelLog.Ln();
  4220. KernelLog.String("]");
  4221. KernelLog.Ln();
  4222. END;
  4223. RETURN TRUE;
  4224. END ReadCOMSegment;
  4225. END CodestreamReader;
  4226. (**
  4227. A buffered version of the codestream readers.
  4228. Buffered in this context means, that we buffer layers for the same
  4229. code-block and only deliver the code-block, if the requested
  4230. number of layers has been obtained, or there are no more layers
  4231. for that code-block.
  4232. *)
  4233. BufferedCodestreamReader* = OBJECT(CodestreamReader)
  4234. VAR
  4235. (*
  4236. Pointer to buffered coded code-blocks off the image:
  4237. 1st dim: tile index
  4238. 2nd dim: component
  4239. 3rd dim: resolution level
  4240. 4th dim: subband (NOTE: 0 = LL at lowest resolution level; 0 = HL, 1 = LH, 2 = HH otherwise)
  4241. 5th dim: code-block index in the subband (in raster order)
  4242. *)
  4243. bufferedBlocks : POINTER TO ARRAY OF ARRAY OF POINTER TO ARRAY OF POINTER TO ARRAY OF POINTER TO ARRAY OF J2KU.CodedCblk;
  4244. reBuildMode : BOOLEAN; (* TRUE, if we are in rebuild mode *)
  4245. curSubbIdx, curSubbCblk : LONGINT;
  4246. maxSubbIdx, maxSubbCblk : LONGINT;
  4247. getAllLayers : BOOLEAN; (* TRUE, if for a tile all layers shall be delivered (which is much easier
  4248. than having to determine which data is contained in the requested
  4249. layer range, and which not)
  4250. *)
  4251. PROCEDURE &InitNew* (crOpt : J2KU.CodestreamReaderOptions;
  4252. stream : Streams.Reader);
  4253. BEGIN
  4254. ReInit(crOpt, stream);
  4255. END InitNew;
  4256. PROCEDURE ReInit* (crOpt : J2KU.CodestreamReaderOptions;
  4257. stream : Streams.Reader);
  4258. BEGIN
  4259. ReInit^(crOpt, stream);
  4260. IF ~initError THEN
  4261. NEW(bufferedBlocks, decSpec.imgInfo.nt, decSpec.imgInfo.ncomp);
  4262. reBuildMode := FALSE;
  4263. END;
  4264. END ReInit;
  4265. PROCEDURE InitTile () : BOOLEAN;
  4266. VAR
  4267. c, r, nblocks, subband, nband, ndec : LONGINT;
  4268. cstyle : CodingStyle;
  4269. subbInfo : J2KU.SubbandInfo;
  4270. BEGIN
  4271. (* Super call *)
  4272. IF ~InitTile^() THEN
  4273. RETURN FALSE;
  4274. END;
  4275. IF curPart = 0 THEN
  4276. (* Loop on components *)
  4277. FOR c := 0 TO decSpec.imgInfo.ncomp - 1 DO
  4278. cstyle := decSpec.cstyle[curTile][c];
  4279. (* Instantiate new arrays for each tile-component *)
  4280. NEW(bufferedBlocks[curTile][c], cstyle.ndec + 1);
  4281. (* Loop on resolution levels *)
  4282. FOR r := 0 TO cstyle.ndec DO
  4283. IF r = 0 THEN
  4284. nband := 1;
  4285. ELSE
  4286. nband := 3;
  4287. END;
  4288. NEW(bufferedBlocks[curTile][c][r], nband);
  4289. FOR subband := 0 TO nband - 1 DO
  4290. subbInfo := GetSubbandInfo(curTile, c, r, J2KU.SubbandIndexToSubband(r, subband));
  4291. nblocks := subbInfo.nblocksx * subbInfo.nblocksy;
  4292. IF nblocks > 0 THEN
  4293. NEW(bufferedBlocks[curTile][c][r][subband], nblocks);
  4294. Machine.Fill32(ADDRESSOF(bufferedBlocks[curTile][c][r][subband][0]), nblocks*SIZEOF(J2KU.CodedCblk), 0);
  4295. END;
  4296. END;
  4297. END;
  4298. END;
  4299. ELSIF reBuildMode THEN
  4300. (* Set component range *)
  4301. curComp := 0;
  4302. cmax := decSpec.imgInfo.GetNumComponents() - 1;
  4303. (* Set minimum/maximum resolution levels for the new component *)
  4304. ndec := decSpec.GetNumDecLevels(curTile, 0);
  4305. (*
  4306. If the start decomposition level is greater than the number of
  4307. decomposition levels for the current tile-component, we start from
  4308. the minimum resolution level available.
  4309. *)
  4310. IF startDecLvl > ndec THEN
  4311. curRes := 0;
  4312. ELSE
  4313. (* The start decomposition level is not the maxim decomposition level *)
  4314. curRes := ndec - startDecLvl;
  4315. END;
  4316. (*
  4317. Need to check wether the current tile-component has data for
  4318. the decomposition level range.
  4319. *)
  4320. IF endDecLvl > ndec THEN
  4321. (*
  4322. The minimum decomposition level is greater than the number
  4323. of decomposition levels for this tile-component -> don't deliver
  4324. any data
  4325. *)
  4326. rmax := -1;
  4327. ELSE
  4328. rmax := ndec - endDecLvl;
  4329. END;
  4330. curSubbIdx := 0;
  4331. curSubbCblk := 0;
  4332. END;
  4333. (* Need to see if we can get all the layers for this tile, or if we have to return a specific layer range *)
  4334. IF (startLayer = 0) & (endLayer >= decSpec.cics[curTile].nl - 1) THEN
  4335. getAllLayers := TRUE;
  4336. ELSE
  4337. getAllLayers := FALSE;
  4338. END;
  4339. RETURN TRUE;
  4340. END InitTile;
  4341. (**
  4342. Goes into the rebuil mode. This is used to reconstruct a previously decoded image
  4343. at a lower/higher resolution level or in better/worse quality.
  4344. NOTE: The rebuild mode may NOT be supported by some components in the decoding chain.
  4345. IMPORTANT: This procedure MUST NOT be called before the image has been
  4346. reconstructed once.
  4347. *)
  4348. PROCEDURE SetReBuildMode*;
  4349. BEGIN
  4350. reBuildMode := TRUE;
  4351. curTile := -1;
  4352. curPart := REBUILD_TILEPART;
  4353. END SetReBuildMode;
  4354. (* Aadds a coded code-block to the output buffer *)
  4355. PROCEDURE AddBlock (VAR cblock : J2KU.CodedCblk; cblockInfo : J2KU.CblkInfo);
  4356. VAR
  4357. i, j : LONGINT;
  4358. tmpSegLen : J2KU.LongIntArrayPtr;
  4359. totSegLen, firstSegLen, lastSegLen : LONGINT;
  4360. dataEndPos : LONGINT;
  4361. nseg : LONGINT;
  4362. locComp, locRes, locSubb, locSubbCblk : LONGINT;
  4363. BEGIN
  4364. (* Buffer variables locally, so the compiler won't get in trouble ;-) *)
  4365. locComp := cblockInfo.subbinfo.component;
  4366. locRes := cblockInfo.subbinfo.reslevel;
  4367. locSubb := cblockInfo.subbinfo.index;
  4368. locSubbCblk := cblockInfo.index;
  4369. cblock.data := bufferedBlocks[curTile][locComp][locRes][locSubb][locSubbCblk].data;
  4370. nseg := bufferedBlocks[curTile][locComp][locRes][locSubb][locSubbCblk].nseg;
  4371. tmpSegLen := bufferedBlocks[curTile][locComp][locRes][locSubb][locSubbCblk].segLen;
  4372. IF startLayer = 0 THEN
  4373. (* Adjust data offset and length *)
  4374. cblock.dataOffset := 0;
  4375. cblock.dataLen := cblockInfo.datalenlyr[endLayer];
  4376. (* Adjust number of coding passes *)
  4377. cblock.cpasses := cblockInfo.cpasseslyr[endLayer];
  4378. cblockInfo.curbp := J2KU.LONGINT_BITS - 2 - cblockInfo.zerobp;
  4379. ELSE
  4380. (* Adjust data offset and length *)
  4381. cblock.dataOffset := cblockInfo.datalenlyr[startLayer - 1];
  4382. cblock.dataLen := cblockInfo.datalenlyr[endLayer] - cblockInfo.datalenlyr[startLayer - 1];
  4383. (* Adjust number of coding passes *)
  4384. cblock.cpasses := cblockInfo.cpasseslyr[endLayer] - cblockInfo.cpasseslyr[startLayer - 1];
  4385. cblockInfo.curbp := J2KU.LONGINT_BITS - 2 - cblockInfo.zerobp
  4386. - ((cblockInfo.cpasseslyr[startLayer - 1] + 2) DIV 3);
  4387. END;
  4388. (* Now we need to adjust the segment lengths *)
  4389. IF tmpSegLen # NIL THEN
  4390. (*
  4391. We need to get the first and last terminated segments for which this coded code-block
  4392. contains data. Then we need to find out, how much of the segments actually
  4393. belongs to the layer range of this coded code-block (since start or end
  4394. segments of a layer may be unterminated)
  4395. *)
  4396. i := -1;
  4397. totSegLen := 0;
  4398. REPEAT
  4399. INC(i);
  4400. INC(totSegLen, tmpSegLen[i]);
  4401. UNTIL totSegLen > cblock.dataOffset;
  4402. (* i now contains the index of the first terminated segment to which the start layer contributes data *)
  4403. (* Compute length of first segment for this coded code-block *)
  4404. firstSegLen := totSegLen - cblock.dataOffset;
  4405. (* Now find the end index *)
  4406. j := i;
  4407. dataEndPos := cblock.dataOffset + cblock.dataLen;
  4408. WHILE (totSegLen <= dataEndPos) & (j < LEN(tmpSegLen^) - 1) DO
  4409. INC(j);
  4410. INC(totSegLen, tmpSegLen[j]);
  4411. END;
  4412. (*
  4413. NOTE:
  4414. j now contains either the index of the last terminated segment to which the end layer contributes,
  4415. or one segment beyond that (that's the case if the last terminated segment does not contain
  4416. any data after the requested end layer). The latter case does not cause any problems, because the
  4417. number of coding passes ensures that we don't decode the extra segments that belong to layers
  4418. after the requested end layer.
  4419. *)
  4420. (*
  4421. We only have to allocate a segment length array if there is more than 1 segment
  4422. *)
  4423. IF j > i THEN
  4424. cblock.nseg := j-i+1;
  4425. (* Compute length of last segment for this coded code-block *)
  4426. lastSegLen := tmpSegLen[j] - (totSegLen - dataEndPos);
  4427. NEW(cblock.segLen, cblock.nseg);
  4428. cblock.segLen[0] := firstSegLen;
  4429. cblock.segLen[cblock.nseg - 1] := lastSegLen;
  4430. (* If there is anything in between the two segments -> move it *)
  4431. IF cblock.nseg > 2 THEN
  4432. SYSTEM.MOVE(ADDRESSOF(tmpSegLen[i+1]), ADDRESSOF(cblock.segLen[1]), (cblock.nseg-2)*SIZEOF(LONGINT));
  4433. END;
  4434. ELSE
  4435. cblock.nseg := 1;
  4436. cblock.segLen := NIL;
  4437. END;
  4438. ELSE
  4439. cblock.nseg := 1;
  4440. cblock.segLen := NIL;
  4441. END;
  4442. END AddBlock;
  4443. (*
  4444. Updates a specific buffered coded code-block (i.e. when data of higher layers has to be added)
  4445. *)
  4446. PROCEDURE UpdateBufferedBlock (VAR cblk : J2KU.CodedCblk; cblkInfo : J2KU.CblkInfo);
  4447. VAR
  4448. newDataLen, newSegs : LONGINT;
  4449. newSize, newSegSize : LONGINT;
  4450. tmpBlock : J2KU.CodedCblk;
  4451. tmpData : J2KU.ByteArrayPtr;
  4452. tmpSegLen : J2KU.LongIntArrayPtr;
  4453. layLeft: LONGINT;
  4454. comp, reslevel, subbIdx, cblkSubbIdx : LONGINT;
  4455. BEGIN
  4456. newDataLen := cblk.dataLen;
  4457. newSegs := cblk.nseg;
  4458. (* Buffer index variables locally, as not to make the compiler unhappy ;-) *)
  4459. comp := cblkInfo.subbinfo.component;
  4460. reslevel := cblkInfo.subbinfo.reslevel;
  4461. subbIdx := cblkInfo.subbinfo.index;
  4462. cblkSubbIdx := cblkInfo.index;
  4463. IF (maxEndLayer < decSpec.cics[curTile].nl - 1) THEN
  4464. layLeft := (maxEndLayer - maxStartLayer) - curLay;
  4465. ELSE
  4466. layLeft := (decSpec.cics[curTile].nl-1 - maxStartLayer) - curLay;
  4467. END;
  4468. IF newDataLen > 0 THEN
  4469. (* Get the corresponding code-block from the internal buffer *)
  4470. tmpBlock := bufferedBlocks[curTile][comp][reslevel][subbIdx][cblkSubbIdx];
  4471. (* If it's the first layer for the code-block we need to allocate space for the data *)
  4472. IF tmpBlock.dataLen = 0 THEN
  4473. (*
  4474. NOTE:
  4475. The specification states that if the code-block truncation points
  4476. associated with each layer are optimal in the rate-distortion sense
  4477. (that's what we assume) then on average each layer contains contributions
  4478. from approximately half the code-blocks. So the assumption now is that
  4479. every code-block is contained in about half of all (remaining) layers (with about the
  4480. same amount of data. This maybe is a naive assumption since it is possible that some
  4481. code-blocks contribute to almost all layers and others to almost none and the data length
  4482. may vary largely. But that's still better than always having to allocate space for data of a
  4483. new layer (isn't it?).
  4484. *)
  4485. newSize := newDataLen + LSH(newDataLen * layLeft, -1);
  4486. NEW(tmpBlock.data, newSize);
  4487. (* See wether the data array of the buffered code-block is large enough or not *)
  4488. ELSIF LEN(tmpBlock.data^) < (newDataLen + tmpBlock.dataLen + tmpBlock.dataOffset) THEN
  4489. tmpData := tmpBlock.data;
  4490. (* NOTE: See reasoning above *)
  4491. newSize := newDataLen + tmpBlock.dataLen + LSH(newDataLen * layLeft, -1);
  4492. NEW(tmpBlock.data, newSize);
  4493. (* Move the existing data to the new array *)
  4494. SYSTEM.MOVE(ADDRESSOF(tmpData[0]), ADDRESSOF(tmpBlock.data[0]), tmpBlock.dataLen);
  4495. END;
  4496. (* If we have entropy bypass coding or termination, we store all segment lenghts *)
  4497. IF decSpec.cstyle[curTile][comp].selcb OR decSpec.cstyle[curTile][comp].term THEN
  4498. (* Now do a similar thing for the segment lengths array *)
  4499. IF tmpBlock.segLen = NIL THEN
  4500. newSegSize := newSegs + LSH(newSegs * layLeft, -1);
  4501. NEW(tmpBlock.segLen, newSegSize);
  4502. Machine.Fill32(ADDRESSOF(tmpBlock.segLen[0]), newSegSize*SIZEOF(LONGINT), 0);
  4503. ELSIF LEN(tmpBlock.segLen^) < (newSegs + tmpBlock.nseg) THEN
  4504. tmpSegLen := tmpBlock.segLen;
  4505. (* NOTE: See reasoning above *)
  4506. newSegSize := newSegs + tmpBlock.nseg + LSH(newSegs * layLeft, -1);
  4507. NEW(tmpBlock.segLen, newSegSize);
  4508. (* Move the existing segment lengths to the new array *)
  4509. SYSTEM.MOVE(ADDRESSOF(tmpSegLen[0]), ADDRESSOF(tmpBlock.segLen[0]), LEN(tmpSegLen^) * SIZEOF(LONGINT));
  4510. (* Init the remaining fields with 0 *)
  4511. Machine.Fill32(ADDRESSOF(tmpBlock.segLen[LEN(tmpSegLen^)]), (newSegSize-LEN(tmpSegLen^))*SIZEOF(LONGINT), 0);
  4512. END;
  4513. IF decSpec.cstyle[curTile][comp].term THEN
  4514. IF newSegs > 1 THEN
  4515. SYSTEM.MOVE(ADDRESSOF(cblk.segLen[0]), ADDRESSOF(tmpBlock.segLen[tmpBlock.nseg]), newSegs * SIZEOF(LONGINT));
  4516. INC(tmpBlock.nseg, newSegs);
  4517. ELSE
  4518. tmpBlock.segLen[tmpBlock.nseg] := cblk.dataLen;
  4519. INC(tmpBlock.nseg);
  4520. END;
  4521. (* If we have bypass coding, we need to calculate the number of terminated segments *)
  4522. ELSE (* Bypass coding used *)
  4523. IF newSegs > 1 THEN
  4524. (* We must have passed the first bypass index, else we would have had only 1 segment *)
  4525. tmpSegLen := tmpBlock.segLen;
  4526. (* The first segment may be a completion of an unterminated segment *)
  4527. INC(tmpSegLen[tmpBlock.nseg], cblk.segLen[0]);
  4528. (* Copy the other segment lenghts *)
  4529. SYSTEM.MOVE(ADDRESSOF(cblk.segLen[1]), ADDRESSOF(tmpSegLen[tmpBlock.nseg + 1]), (newSegs-1)*SIZEOF(LONGINT));
  4530. (* If the last segment is terminated we need to increment the number of segments *)
  4531. (* truncpt MOD ENTROPY_NUM_PASSES = 2-> significance propagation pass *)
  4532. IF (cblkInfo.truncpt MOD ENTROPY_NUM_PASSES) # 2 THEN
  4533. (* Last segment is terminated *)
  4534. INC(tmpBlock.nseg, newSegs);
  4535. ELSE
  4536. (* Last segment is un-terminated *)
  4537. INC(tmpBlock.nseg, newSegs - 1);
  4538. END;
  4539. ELSE
  4540. (* Only 1 segment in this layer *)
  4541. INC(tmpBlock.segLen[tmpBlock.nseg], cblk.dataLen);
  4542. (* truncpt MOD ENTROPY_NUM_PASSES = 2-> significance propagation pass *)
  4543. IF (cblkInfo.truncpt >= ENTROPY_FIRST_BYPASS_IDX) &
  4544. ((cblkInfo.truncpt MOD ENTROPY_NUM_PASSES) # 2) THEN
  4545. (* This was the last chunk for this segment -> terminate it *)
  4546. INC(tmpBlock.nseg);
  4547. END;
  4548. END;
  4549. END;
  4550. END;
  4551. SYSTEM.MOVE(ADDRESSOF(cblk.data[cblk.dataOffset]), ADDRESSOF(tmpBlock.data[tmpBlock.dataLen]), newDataLen);
  4552. INC(tmpBlock.dataLen, newDataLen);
  4553. INC(tmpBlock.cpasses, cblk.cpasses);
  4554. bufferedBlocks[curTile][comp][reslevel][subbIdx][cblkSubbIdx] := tmpBlock;
  4555. END;
  4556. END UpdateBufferedBlock;
  4557. (**
  4558. -> See CodestreamReader.GetCodeBlocks
  4559. *)
  4560. PROCEDURE GetCodeBlocks* (VAR cblocks : ARRAY OF J2KU.CodedCblk; VAR cblockInfos : ARRAY OF J2KU.CblkInfo; ncblocks : LONGINT) : LONGINT;
  4561. VAR
  4562. i, j, startPos, tmpCblkInBuf, cblkDecLvl, subbIdx, cblkSubbIdx : LONGINT;
  4563. ok, deliver : BOOLEAN;
  4564. BEGIN
  4565. (* Check if we're in rebuild mode *)
  4566. IF reBuildMode THEN
  4567. RETURN GetBufferedBlocks(cblocks, cblockInfos, ncblocks);
  4568. END;
  4569. i := 0;
  4570. (* See, wether buffer not empty: if not then return max(bufSize, ncblocks) code blocks *)
  4571. WHILE i < ncblocks DO
  4572. IF ~TilePartAvailable^() THEN
  4573. RETURN i;
  4574. END;
  4575. (* See if the code-block buffer has been read entirely *)
  4576. IF ncblkInBuf <= cblkBufPos THEN
  4577. startPos := s.Pos();
  4578. ncblkInBuf := 0;
  4579. deliver := TRUE;
  4580. tmpCblkInBuf := pktDec.DecodePacket(curComp, curRes, curLay, curPrec[curComp][curRes][curLay], cblkBuf^, cblkInfoBuf^);
  4581. (* Need to check if the code-block is in the valid range (decomposition level, layer) *)
  4582. cblkDecLvl := decSpec.cstyle[curTile][curComp].ndec - curRes;
  4583. (* See if have to deliver the code-blocks at all *)
  4584. (* NOTE: If we're outside the maximum decomposition level range, we discard the new code-block totally *)
  4585. IF (cblkDecLvl < endDecLvl)
  4586. OR (cblkDecLvl > startDecLvl)
  4587. THEN
  4588. IF (cblkDecLvl < maxEndDecLvl)
  4589. OR (cblkDecLvl > maxStartDecLvl)
  4590. THEN
  4591. tmpCblkInBuf := 0;
  4592. END;
  4593. deliver := FALSE;
  4594. END;
  4595. IF (curLay < startLayer)
  4596. OR (curLay > endLayer)
  4597. THEN
  4598. IF (curLay < maxStartLayer)
  4599. OR (curLay > maxEndLayer)
  4600. THEN
  4601. tmpCblkInBuf := 0;
  4602. END;
  4603. deliver := FALSE;
  4604. END;
  4605. (* Update the buffered code-blocks *)
  4606. FOR j := 0 TO tmpCblkInBuf - 1 DO
  4607. (* Update the the code-block *)
  4608. UpdateBufferedBlock(cblkBuf[j], cblkInfoBuf[j]);
  4609. END;
  4610. (* See, if we can deliver the code-blocks already *)
  4611. IF deliver &
  4612. ((curLay = endLayer) OR (curLay = decSpec.cics[curTile].nl - 1))
  4613. THEN
  4614. (* Put the blocks in the return buffer *)
  4615. FOR j := 0 TO tmpCblkInBuf - 1 DO
  4616. IF getAllLayers THEN
  4617. (* We need all layers -> Just get code-block from buffer *)
  4618. subbIdx := cblkInfoBuf[j].subbinfo.index;
  4619. cblkSubbIdx := cblkInfoBuf[j].index;
  4620. cblkBuf[ncblkInBuf] := bufferedBlocks[curTile][curComp][curRes][subbIdx][cblkSubbIdx];
  4621. ELSE
  4622. (* We need to calculate which data parts are to be delivered exactly*)
  4623. AddBlock(cblkBuf[ncblkInBuf], cblkInfoBuf[j]);
  4624. END;
  4625. cblkInfoBuf[ncblkInBuf] := cblkInfoBuf[j];
  4626. INC(ncblkInBuf);
  4627. END;
  4628. END;
  4629. CASE progOrder OF
  4630. PROG_LRCP:
  4631. ok := AdvanceLayResComPos();
  4632. | PROG_RLCP:
  4633. ok := AdvanceResLayComPos();
  4634. | PROG_RPCL:
  4635. ok := AdvanceResPosComLay();
  4636. | PROG_PCRL:
  4637. ok := AdvancePosComResLay();
  4638. | PROG_CPRL:
  4639. ok := AdvanceComPosResLay();
  4640. ELSE
  4641. ok := FALSE;
  4642. END;
  4643. IF ~ok THEN
  4644. RETURN i;
  4645. END;
  4646. cblkBufPos := 0;
  4647. partRem := partRem - (s.Pos() - startPos);
  4648. ELSE
  4649. (* Don't deliver code-blocks with no data *)
  4650. IF cblkBuf[cblkBufPos].dataLen > 0 THEN
  4651. cblocks[i] := cblkBuf[cblkBufPos];
  4652. cblockInfos[i] := cblkInfoBuf[cblkBufPos];
  4653. INC(i);
  4654. END;
  4655. INC(cblkBufPos);
  4656. END;
  4657. END;
  4658. RETURN ncblocks;
  4659. END GetCodeBlocks;
  4660. (*
  4661. Same as GetCodeBlocks, but used when in rebuild mode
  4662. *)
  4663. PROCEDURE GetBufferedBlocks (VAR cblocks : ARRAY OF J2KU.CodedCblk; VAR cblockInfos : ARRAY OF J2KU.CblkInfo; ncblocks : LONGINT) : LONGINT;
  4664. VAR
  4665. ncblocksRet: LONGINT;
  4666. ndec, cblkDecLvl : LONGINT;
  4667. curSubbType : LONGINT;
  4668. locCurComp, locCurRes, locCurSubbIdx, locCurSubbCblk : LONGINT;
  4669. BEGIN
  4670. ncblocksRet := 0;
  4671. (*
  4672. Store counter variables locally, so that compiler does not trap when
  4673. it can't find enough registers (i.e. when accessing multi-dimensional arrays)
  4674. *)
  4675. locCurComp := curComp;
  4676. locCurRes := curRes;
  4677. locCurSubbIdx := curSubbIdx;
  4678. locCurSubbCblk := curSubbCblk;
  4679. (* Loop over components *)
  4680. WHILE locCurComp <= cmax DO
  4681. (* Loop over resolution levels *)
  4682. WHILE locCurRes <= rmax DO
  4683. IF locCurRes = 0 THEN
  4684. maxSubbIdx := 0;
  4685. ELSE
  4686. maxSubbIdx := 2;
  4687. END;
  4688. cblkDecLvl := decSpec.cstyle[curTile][locCurComp].ndec - locCurRes;
  4689. (*
  4690. We deliver for the current resolution level only if the code-blocks
  4691. would lie in the requested decomposition level range.
  4692. *)
  4693. IF (cblkDecLvl <= startDecLvl) & (cblkDecLvl >= endDecLvl) THEN
  4694. (* Loop over subbands *)
  4695. WHILE locCurSubbIdx <= maxSubbIdx DO
  4696. curSubbType := J2KU.SubbandIndexToSubband(locCurRes, locCurSubbIdx);
  4697. maxSubbCblk := LEN(bufferedBlocks[curTile][locCurComp][locCurRes][locCurSubbIdx]^) - 1;
  4698. (* Loop over blocks in subband *)
  4699. WHILE locCurSubbCblk <= maxSubbCblk DO
  4700. cblockInfos[ncblocksRet] := pktDec.GetCblkInfo( locCurComp,
  4701. locCurRes,
  4702. curSubbType,
  4703. locCurSubbCblk);
  4704. IF getAllLayers THEN
  4705. (* Just copy from buffer *)
  4706. cblocks[ncblocksRet] := bufferedBlocks[curTile][locCurComp][locCurRes][locCurSubbIdx][locCurSubbCblk];
  4707. cblockInfos[ncblocksRet].curbp := J2KU.LONGINT_BITS - 2 - cblockInfos[ncblocksRet].zerobp;
  4708. ELSE
  4709. (* Need to determine which code-block data is to be delivered (i.e. which data belongs to the requested layer range) *)
  4710. AddBlock(cblocks[ncblocksRet], cblockInfos[ncblocksRet]);
  4711. END;
  4712. (* Don't deliver code-blocks with no data *)
  4713. IF cblocks[ncblocksRet].dataLen > 0 THEN
  4714. INC(ncblocksRet);
  4715. END;
  4716. INC(locCurSubbCblk);
  4717. (* Check if we have enough blocks *)
  4718. IF ncblocksRet = ncblocks THEN
  4719. (* Update counter variables *)
  4720. curComp := locCurComp;
  4721. curRes := locCurRes;
  4722. curSubbIdx := locCurSubbIdx;
  4723. curSubbCblk := locCurSubbCblk;
  4724. RETURN ncblocksRet;
  4725. END;
  4726. END;
  4727. INC(locCurSubbIdx);
  4728. locCurSubbCblk := 0;
  4729. END;
  4730. END;
  4731. INC(locCurRes);
  4732. (* We start over on all subbands *)
  4733. locCurSubbIdx := 0;
  4734. END;
  4735. INC(locCurComp);
  4736. IF locCurComp <= cmax THEN
  4737. (* Set minimum/maximum resolution levels for the new component *)
  4738. ndec := decSpec.GetNumDecLevels(curTile, locCurComp);
  4739. (*
  4740. If the start decomposition level is greater than the number of
  4741. decomposition levels for the current tile-component, we start from
  4742. the minimum resolution level available.
  4743. *)
  4744. IF startDecLvl > ndec THEN
  4745. locCurRes := 0;
  4746. ELSE
  4747. (* The start decomposition level is not the maxim decomposition level *)
  4748. locCurRes := ndec - startDecLvl;
  4749. END;
  4750. (*
  4751. Need to check wether the current tile-component has data for
  4752. the decomposition level range.
  4753. *)
  4754. IF endDecLvl > ndec THEN
  4755. (*
  4756. The minimum decomposition level is greater than the number
  4757. of decomposition levels for this tile-component -> don't deliver
  4758. any data
  4759. *)
  4760. rmax := -1;
  4761. ELSE
  4762. rmax := ndec - endDecLvl;
  4763. END;
  4764. END;
  4765. END;
  4766. (* Update counter variables *)
  4767. curComp := locCurComp;
  4768. curRes := locCurRes;
  4769. curSubbIdx := locCurSubbIdx;
  4770. curSubbCblk := locCurSubbCblk;
  4771. RETURN ncblocksRet;
  4772. END GetBufferedBlocks;
  4773. PROCEDURE TilePartAvailable* () : BOOLEAN;
  4774. BEGIN
  4775. IF reBuildMode THEN
  4776. RETURN (curComp < cmax)
  4777. OR (
  4778. (curComp = cmax)
  4779. & (
  4780. (curRes < rmax)
  4781. OR (curSubbIdx < maxSubbIdx)
  4782. OR (curSubbCblk <= maxSubbCblk)
  4783. )
  4784. );
  4785. ELSE
  4786. RETURN TilePartAvailable^();
  4787. END;
  4788. END TilePartAvailable;
  4789. PROCEDURE JumpToTilePartEnd () : LONGINT;
  4790. BEGIN
  4791. IF reBuildMode THEN
  4792. curComp := cmax + 1;
  4793. curRes := rmax;
  4794. curSubbIdx := maxSubbIdx;
  4795. curSubbCblk := maxSubbCblk + 1;
  4796. RETURN 0;
  4797. ELSE
  4798. RETURN JumpToTilePartEnd^();
  4799. END;
  4800. END JumpToTilePartEnd;
  4801. PROCEDURE NextTilePart*() : BOOLEAN;
  4802. VAR
  4803. imgInfo : ImageInfo;
  4804. ntiles : LONGINT;
  4805. ok : BOOLEAN;
  4806. BEGIN
  4807. IF reBuildMode THEN
  4808. imgInfo := decSpec.GetImageInfo();
  4809. ntiles := imgInfo.GetNumTiles();
  4810. (* We need to ensure there is some data available for the next tile, else we need to skip it *)
  4811. REPEAT
  4812. INC(curTile);
  4813. UNTIL (curTile >= ntiles) OR (ntilePartsRead[curTile] > 0);
  4814. IF curTile < ntiles THEN
  4815. pktDec.SetTile(curTile);
  4816. ok := InitTile();
  4817. ELSE
  4818. (* Just to ensure that TilePartAvailable() returns FALSE *)
  4819. curComp := cmax + 1;
  4820. curRes := rmax;
  4821. curSubbIdx := maxSubbIdx;
  4822. curSubbCblk := maxSubbCblk + 1;
  4823. (* Leave rebuild mode *)
  4824. reBuildMode := FALSE;
  4825. (* If we're not at the end of the codestream, we continue reading from the stream *)
  4826. IF ~EndOfCodestream^() THEN
  4827. ok := NextTilePart^();
  4828. ELSE
  4829. (* We're at the end of the stream too -> no data (neither rebuild nor stream data) *)
  4830. ok := FALSE;
  4831. END;
  4832. END;
  4833. RETURN ok;
  4834. ELSE
  4835. RETURN NextTilePart^();
  4836. END;
  4837. END NextTilePart;
  4838. PROCEDURE EndOfCodestream* () : BOOLEAN;
  4839. VAR
  4840. imgInfo : ImageInfo;
  4841. BEGIN
  4842. IF reBuildMode THEN
  4843. imgInfo := decSpec.GetImageInfo();
  4844. RETURN imgInfo.GetNumTiles() <= curTile;
  4845. ELSE
  4846. RETURN EndOfCodestream^();
  4847. END;
  4848. END EndOfCodestream;
  4849. PROCEDURE FreeNonRebuildResources*;
  4850. BEGIN
  4851. s := NIL;
  4852. progChanges := NIL;
  4853. progStates := NIL;
  4854. curPrec := NIL;
  4855. END FreeNonRebuildResources;
  4856. PROCEDURE FreeResources*;
  4857. BEGIN
  4858. FreeResources^();
  4859. bufferedBlocks := NIL;
  4860. END FreeResources;
  4861. END BufferedCodestreamReader;
  4862. (* --- Utility functions --- *)
  4863. PROCEDURE MarkerToString (marker : LONGINT; VAR str : ARRAY OF CHAR);
  4864. VAR
  4865. i : LONGINT;
  4866. BEGIN
  4867. ASSERT (LEN(str) >= 7);
  4868. CASE marker OF
  4869. | SOC :
  4870. COPY("SOC", str);
  4871. | SOT :
  4872. COPY("SOT", str);
  4873. | SOD :
  4874. COPY("SOD", str);
  4875. | EOC :
  4876. COPY("EOC", str);
  4877. | SIZ :
  4878. COPY("SIZ", str);
  4879. | COD :
  4880. COPY("COC", str);
  4881. | COC :
  4882. COPY("COC", str);
  4883. | RGN :
  4884. COPY("RGN", str);
  4885. | QCD :
  4886. COPY("QCD", str);
  4887. | QCC :
  4888. COPY("QCC", str);
  4889. | POC :
  4890. COPY("POC", str);
  4891. | TLM :
  4892. COPY("TLM", str);
  4893. | PLM :
  4894. COPY("PLM", str);
  4895. | PLT :
  4896. COPY("PLT", str);
  4897. | PPM :
  4898. COPY("PPM", str);
  4899. | PPT :
  4900. COPY("PPT", str);
  4901. | SOP :
  4902. COPY("SOP", str);
  4903. | EPH :
  4904. COPY("EPH", str);
  4905. | CRG :
  4906. COPY("CRG", str);
  4907. | COM :
  4908. COPY("COM", str);
  4909. ELSE
  4910. str[0] := '0';
  4911. str[1] := 'x';
  4912. (* NOTE: No optimizations done here *)
  4913. FOR i := 5 TO 2 BY -1 DO
  4914. str[i] := CHR(marker MOD 10H + 48);
  4915. IF str[i] > "9" THEN
  4916. str[i] := CHR(ORD(str[i]) - 48 + 65 - 10)
  4917. END;
  4918. marker := marker DIV 10H;
  4919. END;
  4920. str[6] := 0X;
  4921. END;
  4922. END MarkerToString;
  4923. END JPEG2000DecoderCS.