JPEG2000Decoder.Mod 235 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165
  1. MODULE JPEG2000Decoder;
  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 main decoding chain (except for the codestream parsing component) *)
  5. (*
  6. TODO:
  7. - "Perfect reconstruction" in the irreversible wavelet filter not done, i.e. the precision somehow is not
  8. very accurate which results in a rounding error that gets propagated from up-left
  9. to down-right in the image.
  10. - Colorspace transformation described in a JP2 file is ignored presently.
  11. - The bit-depths of components that undergo multiple component transformation have to be
  12. calculated (that is, the bit-depths before the inverse mct takes place). The dequantizer needs
  13. those bit-depths (not the ones for the original image components)
  14. -> See also procedure 'ComputeUntransformedBitDepths' in this module (it's commented out)
  15. - Optimization: Inline procedures Renormd, LpsExchange and MpsExchange of MQDecoder.
  16. *)
  17. IMPORT SYSTEM, KernelLog, Streams, J2KCS := JPEG2000DecoderCS, J2KU := JPEG2000DecoderUtil,
  18. Codecs, Raster, Machine;
  19. CONST
  20. (* --- Compile options --- *)
  21. CBLK_BUFSIZE = 5; (* The number of code-blocks that each decoder component can buffer locally *)
  22. (* This means that whenever a component requests code-blocks from the *)
  23. (* underlying component it will get at most as much code-blocks as fit in the buffer *)
  24. (* --- END Compile options --- *)
  25. (* --- Configuration constants --- *)
  26. (* Constants identifying each component (used for options object for each component) *)
  27. ENTROPY_DECODER* = 2;
  28. ROI_DESCALER* = 3;
  29. DEQUANTIZER* = 4;
  30. INVERSE_DWT* = 5;
  31. INVERSE_MCT* = 6;
  32. (* --- END Configuration constants --- *)
  33. (* Used by a component to set the data type it wants to get delivered from the lower component *)
  34. DATA_LONGINT* = 0;
  35. DATA_REAL* = 1;
  36. (* --- JP2 box types --- *)
  37. JP2SIGN = 6A502020H; (* JPEG2000 Signature box *)
  38. JP2FTYP = 66747970H; (* File Type box *)
  39. JP2HEAD = 6A703268H; (* JP2 Header box *)
  40. JP2IHDR = 69686472H; (* Image Header box *)
  41. JP2BPCC = 62706363H; (* Bits Per Component box *)
  42. JP2COLR = 636F6C72H; (* Colour Specification box *)
  43. JP2PCLR = 70636C72H; (* Palette box *)
  44. JP2CMAP = 636D6170H; (* Component Mapping box *)
  45. JP2CDEF = 63646566H; (* Channel Definition box *)
  46. JP2RESL = 72657320H; (* Resolution box *)
  47. JP2RESC = 72657363H; (* Capture Resolution box *)
  48. JP2RESD = 72657364H; (* Default Display Resolution box *)
  49. JP2CCST = 6A703263H; (* Contiguous Codestream box *)
  50. JP2INPR = 6A703269H; (* Intellectual Property box *)
  51. JP2XMLD = 786D6C20H; (* XML box *)
  52. JP2UUID = 75756964H; (* UUID box *)
  53. JP2UINF = 75696E66H; (* UUID Info box *)
  54. JP2ULST = 75637374H; (* UUID List box *)
  55. JP2URLS = 75726C20H; (* URL box *)
  56. (* --- END JP2 box types --- *)
  57. JP2_FTBRAND = 6A703220H; (* File Type brand ('jp2/040') *)
  58. ENTROPY_SEG_MARKER = SYSTEM.VAL(LONGINT, 0AH);
  59. (* --- Constants used in MQ-Decoder --- *)
  60. MQTABSIZ = 47; (* The size of the table which contains the probability estimations, state transitions, nlps, nmps and switch values.*)
  61. (* --- END Constants used in MQ-Decoder --- *)
  62. (* --- Constants used in EntropyDecoder --- *)
  63. (* The number of bits used to represent a specific neighbor state as used in the significance propagation and cleanup coding passes *)
  64. ENTROPY_ZERO_BITS = 8;
  65. (* The number of bits used to represent neighbor states / signs as used in the sign bit decoding *)
  66. ENTROPY_SIGN_BITS = 8;
  67. (*
  68. Masks to see wether a specific neighbor is significant ("1" means "significant"):
  69. We have one "register" to store all information about neighbor significance
  70. The order from most significant bit to least significant bit is the following:
  71. HL (horizontal left) - HR (horizontal right) - VU (vertical up) - VD (vertical down) - <Diagonals>, where the internal order of <Diagonals> is
  72. not specified in more detail
  73. *)
  74. ENTROPY_SIGHL = LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_ZERO_BITS - 1); (* HL: horizontal left neighbor *)
  75. ENTROPY_SIGHR = LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_ZERO_BITS - 2); (* HR: horizontal right neighbor *)
  76. ENTROPY_SIGVU = LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_ZERO_BITS - 3); (* VU: vertical upper neighbor *)
  77. ENTROPY_SIGVD = LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_ZERO_BITS - 4); (* VD: vertical lower neighbor *)
  78. (* Mask to extract the context of the sign lut (and discarding the xor bit) *)
  79. SIGN_LUT_MASK = SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0FH));
  80. (* The separation (in bits) of the two state vectors stored in the same state register *)
  81. STATE_SEP = 16;
  82. (* First-row coefficient values *)
  83. (* Flag for the significane a first-row coefficient (in the state register) *)
  84. STATE_SIG_R1 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), 14));
  85. (* Flag to indicate if a first-row coefficient has been visited in the decoding of the current bit-plane *)
  86. STATE_VISITED_R1 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), 13));
  87. (* Flag to indicate if a first-row coefficient is in the magnitude refinement phase *)
  88. STATE_MAGREF_R1 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), 12));
  89. (* 1 if the horizontal left neighbor has a negative sign, 0 else *)
  90. STATE_H_L_SIGN_R1 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), 11));
  91. (* 1 if the horizontal right neighbor has a negative sign, 0 else *)
  92. STATE_H_R_SIGN_R1 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), 10));
  93. (* 1 if the vertical-up neighbor has a negative sign, 0 else *)
  94. STATE_V_U_SIGN_R1 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), 9));
  95. (* 1 if the vertical_down neighbor has a negative sign, 0 else *)
  96. STATE_V_D_SIGN_R1 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), 8));
  97. (* 1 if the horizontal left neighbor is significant already, 0 else *)
  98. STATE_H_L_R1 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), 7));
  99. (* 1 if the horizontal right neighbor is significant already, 0 else *)
  100. STATE_H_R_R1 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), 6));
  101. (* 1 if the vertical-up neighbor is significant already, 0 else *)
  102. STATE_V_U_R1 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), 5));
  103. (* 1 if the vertical_down neighbor is significant already, 0 else *)
  104. STATE_V_D_R1 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), 4));
  105. (* 1 if the diagonal upper left neighbor is significant already, 0 else *)
  106. STATE_D_UL_R1 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), 3));
  107. (* 1 if the diagonal upper right neighbor is significant already, 0 else *)
  108. STATE_D_UR_R1 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), 2));
  109. (* 1 if the diagonal lower left neighbor is significant already, 0 else *)
  110. STATE_D_DL_R1 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), 1));
  111. (* 1 if the diagonal lower right neighbor is significant already, 0 else *)
  112. STATE_D_DR_R1 = SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1));
  113. (* Mask to extract the zero-bin context vector of a first-row coefficient *)
  114. STATE_VECT_MASK_R1 = SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0FFH));
  115. (* Mask to extract the sign context vector of a first-row coefficient *)
  116. SIGN_VECT_MASK_R1 = SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0FF0H));
  117. (*
  118. How much we need to shift the state vector of a first row coefficient
  119. so that the sign context vector starts at the LSB.
  120. *)
  121. SIGN_VECT_SHIFT_R1 = 4;
  122. (* And the same stuff for the second-row coefficient *)
  123. (* Flag for the significane a second-row coefficient (in the state register) *)
  124. STATE_SIG_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_SIG_R1), STATE_SEP));
  125. (* Flag to indicate if a second-row coefficient has been visited in the decoding of the current bit-plane *)
  126. STATE_VISITED_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_VISITED_R1), STATE_SEP));
  127. (* Flag to indicate if a second-row coefficient is in the magnitude refinement phase *)
  128. STATE_MAGREF_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_MAGREF_R1), STATE_SEP));
  129. (* 1 if the horizontal left neighbor has a negative sign, 0 else *)
  130. STATE_H_L_SIGN_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_H_L_SIGN_R1), STATE_SEP));
  131. (* 1 if the horizontal right neighbor has a negative sign, 0 else *)
  132. STATE_H_R_SIGN_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_H_R_SIGN_R1), STATE_SEP));
  133. (* 1 if the vertical-up neighbor has a negative sign, 0 else *)
  134. STATE_V_U_SIGN_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_V_U_SIGN_R1), STATE_SEP));
  135. (* 1 if the vertical_down neighbor has a negative sign, 0 else *)
  136. STATE_V_D_SIGN_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_V_D_SIGN_R1), STATE_SEP));
  137. (* 1 if the horizontal left neighbor is significant already, 0 else *)
  138. STATE_H_L_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_H_L_R1), STATE_SEP));
  139. (* 1 if the horizontal right neighbor is significant already, 0 else *)
  140. STATE_H_R_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_H_R_R1), STATE_SEP));
  141. (* 1 if the vertical-up neighbor is significant already, 0 else *)
  142. STATE_V_U_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_V_U_R1), STATE_SEP));
  143. (* 1 if the vertical_down neighbor is significant already, 0 else *)
  144. STATE_V_D_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_V_D_R1), STATE_SEP));
  145. (* 1 if the diagonal upper left neighbor is significant already, 0 else *)
  146. STATE_D_UL_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_D_UL_R1), STATE_SEP));
  147. (* 1 if the diagonal upper right neighbor is significant already, 0 else *)
  148. STATE_D_UR_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_D_UR_R1), STATE_SEP));
  149. (* 1 if the diagonal lower left neighbor is significant already, 0 else *)
  150. STATE_D_DL_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_D_DL_R1), STATE_SEP));
  151. (* 1 if the diagonal lower right neighbor is significant already, 0 else *)
  152. STATE_D_DR_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_D_DR_R1), STATE_SEP));
  153. (* Mask to extract the zero-bin context vector of a first-row coefficient *)
  154. STATE_VECT_MASK_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, STATE_VECT_MASK_R1), STATE_SEP));
  155. (* Mask to extract the sign context vector of a first-row coefficient *)
  156. SIGN_VECT_MASK_R2 = SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, SIGN_VECT_MASK_R1), STATE_SEP));
  157. (*
  158. How much we need to shift the state vector of a first row coefficient
  159. so that the sign context vector starts at the LSB.
  160. *)
  161. SIGN_VECT_SHIFT_R2 = 4 + STATE_SEP;
  162. (* The contexts for the magnitude refinement (MR) pass *)
  163. ENTROPY_MR_CTX = 16; (* x neighbors significant, not first refinement for coefficient *)
  164. ENTROPY_MR_FIRSTNZ_CTX = 15; (* >= 1 neighbors significant, first refinement for coefficient *)
  165. ENTROPY_MR_FIRSTZ_CTX = 14; (* 0 neighbors significant, first refinement for coefficient *)
  166. (* The UNIFORM and run-length contexts *)
  167. ENTROPY_UNICTX = 17;
  168. ENTROPY_RUNCTX = 18;
  169. ENTROPY_ARRAYOFF = 1;
  170. ENTROPY_STRIPE_HEIGHT = 4;
  171. ENTROPY_NUM_PASSES = 3;
  172. ENTROPY_NUM_NON_BYPASS_BP = 4;
  173. ENTROPY_FIRST_BYPASS_IDX = 3 * ENTROPY_NUM_PASSES + 1;
  174. (* --- END Constants used in EntropyDecoder --- *)
  175. (* --- Constants used for Inverse multiple component transformation --- *)
  176. MCT_NONE = 0;
  177. MCT_RCT = 1;
  178. MCT_ICT = 2;
  179. (* --- END Constants used for Inverse multiple component transformation --- *)
  180. (* --- Registered filters --- *)
  181. (* Reversible filters (operating on LONGINTs) *)
  182. FILTER_5X3_LIFTING* = 0;
  183. (* Irreversible filters (operating on REALs) *)
  184. FILTER_9X7_LIFTING* = 1;
  185. (* --- END Registered filters --- *)
  186. TYPE
  187. (** This is an interface identifying objects that contain a (2 dimensional) block of data *)
  188. DataBlk = OBJECT
  189. VAR
  190. offset : LONGINT; (* The offset in the data container at which data for this block starts *)
  191. scanw : LONGINT; (* The row scan width, i.e. the distance (in data samples) of the first
  192. data sample of row j to the first data sample of row j+1 *)
  193. END DataBlk;
  194. (** A data block containing data of type LONGINT *)
  195. DataBlkInt = OBJECT(DataBlk)
  196. VAR
  197. data : J2KU.LongIntArrayPtr;
  198. END DataBlkInt;
  199. (** A data block containing data of type REAL *)
  200. DataBlkReal = OBJECT(DataBlk)
  201. VAR
  202. data : J2KU.RealArrayPtr;
  203. END DataBlkReal;
  204. (* --- MQ-Decoder types --- *)
  205. (**
  206. This implementation follows the software conventions for the adaptive entropy decoder
  207. mentioned in the JPEG2000 standard (Annex J.1)
  208. *)
  209. MQDecoder = OBJECT
  210. VAR
  211. a : LONGINT; (* The 'A register' containing the current interval size *)
  212. c : LONGINT; (* The 'C register' containing the current byte of compressed image data being decoded *)
  213. ct : LONGINT; (* The counter which keeps track of how many bits (of the last byte read in) are still in the lower part of c *)
  214. b : LONGINT; (* The current byte to be handled *)
  215. index : J2KU.LongIntArrayPtr; (* For every context the current index is stored here *)
  216. initIdx : J2KU.LongIntArrayPtr; (* For every context the initial index is stored here *)
  217. mps : J2KU.LongIntArrayPtr; (* For every context the current MPS is stored here *)
  218. initMps : J2KU.LongIntArrayPtr; (* For every context the initial MPS is stored here *)
  219. br : J2KU.ByteArrayReader; (* Source from which to get new bytes *)
  220. markerFound : BOOLEAN; (* Indicates if a marker has been found *)
  221. PROCEDURE &InitNew *(initIdx, initMps : J2KU.LongIntArrayPtr);
  222. BEGIN
  223. br := NIL;
  224. ReInit(initIdx, initMps);
  225. END InitNew;
  226. PROCEDURE ReInit (initIdx, initMps : J2KU.LongIntArrayPtr);
  227. BEGIN
  228. ASSERT(LEN(initMps^) = LEN(initIdx^));
  229. SELF.initIdx := initIdx;
  230. SELF.initMps := initMps;
  231. NEW(index, LEN(initIdx^));
  232. NEW(mps, LEN(initMps^));
  233. IF br = NIL THEN
  234. NEW(br, NIL, -1, 0);
  235. ELSE
  236. br.ReInit(NIL, -1, 0);
  237. END;
  238. END ReInit;
  239. (**
  240. This procedure makes new raw coded code-block data available to the MQ-Decoder.
  241. The MQ-Decoder restarts with the new segment (i.e. The 'A' and 'C registers' will be flushed and refilled).
  242. data: The new coded code-block data (by reference)
  243. offset: Where to start reading from the data buffer
  244. len: The length of this segment of coded code-block data
  245. *)
  246. PROCEDURE NextSegment (data : J2KU.ByteArrayPtr; offset, len : LONGINT);
  247. BEGIN
  248. br.SetArray(data, offset, len);
  249. InitDec();
  250. END NextSegment;
  251. PROCEDURE GetByteReader () : J2KU.ByteArrayReader;
  252. BEGIN
  253. RETURN br;
  254. END GetByteReader;
  255. (** Resets the contexts to their initial index and mps values *)
  256. PROCEDURE ResetContexts;
  257. BEGIN
  258. SYSTEM.MOVE(ADDRESSOF(initIdx[0]), ADDRESSOF(index[0]), LEN(initIdx)*SIZEOF(LONGINT));
  259. SYSTEM.MOVE(ADDRESSOF(initMps[0]), ADDRESSOF(mps[0]), LEN(initMps)*SIZEOF(LONGINT));
  260. END ResetContexts;
  261. (**
  262. Returns the next bit of the original data .
  263. cx: The context to use
  264. *)
  265. PROCEDURE Decode (cx : LONGINT) : LONGINT;
  266. VAR
  267. chigh, d : LONGINT;
  268. BEGIN
  269. chigh := LSH(c, -16);
  270. a := a - MQPROB[index[cx]];
  271. IF chigh < a THEN
  272. (* The MPS case *)
  273. IF (SYSTEM.VAL(SET, a) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 00008000H))) = {} THEN
  274. d := MpsExchange(cx);
  275. Renormd();
  276. ELSE
  277. d := mps[cx];
  278. END;
  279. ELSE
  280. (* The LPS case *)
  281. chigh := chigh - a;
  282. (* Update the original 'c register' *)
  283. (* c := (c BITWISE-AND 0x0000FFFF) BITWISE-OR (chigh << 16) *)
  284. c := SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, c) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 0000FFFFH))) + SYSTEM.VAL(SET, LSH(chigh, 16)));
  285. d := LpsExchange(cx);
  286. Renormd();
  287. END;
  288. RETURN d;
  289. END Decode;
  290. (** Renormalization procedure as described in the standartd *)
  291. PROCEDURE Renormd;
  292. BEGIN
  293. REPEAT
  294. IF ct = 0 THEN
  295. ByteIn();
  296. END;
  297. a := LSH(a, 1);
  298. c := LSH(c, 1);
  299. DEC(ct);
  300. UNTIL (SYSTEM.VAL(SET, a) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 00008000H))) # {};
  301. END Renormd;
  302. (**
  303. LPS exchange procedure as described in the standartd
  304. cx: The current context
  305. *)
  306. PROCEDURE LpsExchange (cx : LONGINT) : LONGINT;
  307. VAR
  308. d : LONGINT;
  309. BEGIN
  310. IF a < MQPROB[index[cx]] THEN
  311. a := MQPROB[index[cx]];
  312. d := mps[cx];
  313. index[cx] := MQNMPS[index[cx]];
  314. ELSE
  315. a := MQPROB[index[cx]];
  316. d := SYSTEM.VAL(LONGINT, {0} / SYSTEM.VAL(SET, mps[cx]));
  317. IF MQSWITCH[index[cx]] = 1 THEN
  318. mps[cx] := SYSTEM.VAL(LONGINT, {0} / SYSTEM.VAL(SET, mps[cx]));
  319. END;
  320. index[cx] := MQNLPS[index[cx]];
  321. END;
  322. RETURN d;
  323. END LpsExchange;
  324. (**
  325. MPS exchange procedure as described in the standartd
  326. cx: The current context
  327. *)
  328. PROCEDURE MpsExchange (cx : LONGINT) : LONGINT;
  329. VAR
  330. d : LONGINT;
  331. BEGIN
  332. IF a < MQPROB[index[cx]] THEN
  333. d := SYSTEM.VAL(LONGINT, {0} / SYSTEM.VAL(SET, mps[cx]));
  334. IF MQSWITCH[index[cx]] = 1 THEN
  335. mps[cx] := SYSTEM.VAL(LONGINT, {0} / SYSTEM.VAL(SET, mps[cx]));
  336. END;
  337. index[cx] := MQNLPS[index[cx]];
  338. ELSE
  339. d := mps[cx];
  340. index[cx] := MQNMPS[index[cx]];
  341. END;
  342. RETURN d;
  343. END MpsExchange;
  344. (** Byte input procedure as described in the standartd *)
  345. PROCEDURE ByteIn;
  346. BEGIN
  347. IF ~markerFound THEN
  348. IF b = 255 THEN
  349. b := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, br.Read()) * {0..7}); (* Convert -1 to 0xFF *)
  350. IF b > 8FH THEN
  351. markerFound := TRUE;
  352. ct := 8;
  353. ELSE
  354. c := c + SYSTEM.VAL(LONGINT, 0FE00H) - LSH(b, 9);
  355. ct := 7;
  356. END;
  357. ELSE
  358. b := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, br.Read()) * {0..7}); (* Convert -1 to 0xFF *)
  359. (*
  360. NOTE: The Standard specifies here: c = c + 0xFE00 - (B << 8). But we use an BITWISE-XOR operation instead of the subtraction.
  361. That's ok because no carry overs can occur since we subtract from 0xFF00
  362. *)
  363. c := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, c) + ({8..15} / SYSTEM.VAL(SET, LSH(b, 8))));
  364. ct := 8;
  365. END;
  366. ELSE
  367. ct := 8;
  368. END;
  369. END ByteIn;
  370. (** Decoder initialization procedure as described in the standartd *)
  371. PROCEDURE InitDec;
  372. BEGIN
  373. markerFound := FALSE;
  374. b := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, br.Read()) * {0..7}); (* Converts -1 to 0xFF *)
  375. (* c := (b BITWISE-XOR 0xFF) << 16 *)
  376. c := LSH(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, b) / {0..7}), 16);
  377. ByteIn();
  378. c := LSH(c, 7);
  379. ct := ct - 7;
  380. a := SYSTEM.VAL(LONGINT, 00008000H);
  381. END InitDec;
  382. (** Checks the remainder of the segment (used when predictable termination coding is used) *)
  383. PROCEDURE CheckPredTerm () : BOOLEAN;
  384. VAR
  385. k : LONGINT; (* The number of bits that were added in the termination process *)
  386. q : LONGINT;
  387. BEGIN
  388. (*
  389. (1)
  390. If everything went normal, the current byte must be 0xFF if a terminating marker
  391. has not been found yet.
  392. *)
  393. IF (b # 255) & ~markerFound THEN
  394. RETURN FALSE;
  395. END;
  396. (*
  397. (2)
  398. If 'ct' is not 0 we must have reached the terminating marker already
  399. *)
  400. IF (ct # 0) & ~markerFound THEN
  401. RETURN FALSE;
  402. END;
  403. (*
  404. (3)
  405. If 'ct' is 1 there were no spare bits at the encoder, this is all we can check
  406. *)
  407. IF ct = 1 THEN
  408. RETURN TRUE;
  409. END;
  410. (*
  411. (4)
  412. If 'ct' is 0, then the next byte must be the second byte of a terminating
  413. marker (i.e. larger than 0x8F) if the terminating marker has not beed
  414. read yet
  415. *)
  416. IF ct = 0 THEN
  417. IF ~markerFound THEN
  418. b := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, br.Read()) * {0..7});
  419. IF b <= 8FH THEN
  420. RETURN FALSE;
  421. END;
  422. END;
  423. (* Adjust 'ct' for last byte *)
  424. ct := 8;
  425. END;
  426. (*
  427. (5)
  428. Now we can calculate the 'k', the number of bits having
  429. error resilience information. 'k' is the number of bits left
  430. to normalization in the 'C register', minus 1
  431. *)
  432. k := ct - 1;
  433. (*
  434. (6)
  435. The predictable termination policy is as if an LPS interval was
  436. coded, and a renormalization of 'k' bits was caused, before the
  437. termination marker started
  438. *)
  439. (*
  440. We first check if an LPS is decoded, that causes a renormalization
  441. of 'k' bits. Worst case is smallest LPS probability 'q' that causes
  442. a renormalization of 'k' bits
  443. *)
  444. q := LSH(8000H, -k);
  445. (* Check that we can decode an LPS interval of probability 'q' *)
  446. DEC(a, q);
  447. IF LSH(c, -16) < a THEN
  448. (* Error: MPS interval decoded *)
  449. RETURN FALSE;
  450. END;
  451. (* OK: LPS interval decoded *)
  452. c := c - LSH(a, 16);
  453. (*
  454. Here 'a' can not be smaller than 'q' because the minimum value
  455. for 'a' is 0x8000-0x4000 = 0x4000 and 'q' is set to a value equal
  456. or smaller than that
  457. *)
  458. a := q;
  459. Renormd();
  460. (*
  461. (7)
  462. Everything seems OK, we have checked the 'C register' for the LPS
  463. symbols and ensured that it is followed by bits synthesized by the
  464. termination marker
  465. *)
  466. RETURN TRUE;
  467. END CheckPredTerm;
  468. END MQDecoder;
  469. (* --- END MQ-Decoder types --- *)
  470. (* --- Entropy decoder types --- *)
  471. EntropyDecoder = OBJECT
  472. VAR
  473. cr : J2KCS.CodestreamReader;
  474. decSpec : J2KCS.DecoderSpecs;
  475. (*
  476. CONCEPT:
  477. The state array for entropy coding. Each element of the state array
  478. stores the state of two coefficients. The lower 16 bits store the state
  479. of a coefficient in row 'i' and column 'j', while the upper 16 bits
  480. store the state of a coefficient in row 'i+1' and column 'j'. The 'i'
  481. row is either the first or the third row of a stripe. This packing of
  482. the states into 32 bit words allows a faster scan of all coefficients
  483. on each coding pass and diminishes the amount of data transferred. The
  484. size of the state array is increased by 1 on each side (top, bottom,
  485. left, right) to handle boundary conditions without any special logic.
  486. The state of a coefficient is stored in the following way in the
  487. lower 16 bits, where bit 0 is the least significant bit. Bit 15 is not used.
  488. Bit 14 is the significance of a coefficient (0 if non-significant, 1 otherwise).
  489. Bit 13 is the visited state (i.e. if a coefficient has been coded in the
  490. significance propagation pass of the current bit-plane). Bit 12 indicates if
  491. the magnitude refinement has already been applied to the
  492. coefficient. Bits 11 to 8 store the sign of the already significant left, right,
  493. up and down neighbors (1 for negative, 0 for positive or not yet significant).
  494. Bits 7 to 4 store the significance of the left, right, up and down neighbors
  495. (1 for significant, 0 for non significant). Bits 3 to 0 store the significance
  496. of the diagonal coefficients (up-left, up-right, down-left and down-right;
  497. 1 for significant, 0 for non significant).
  498. The upper 16 bits the state is stored as in the lower 16 bits,
  499. but with the bits shifted up by 16.
  500. The lower 16 bits are referred to as "row 1" ("R1") while the upper
  501. 16 bits are referred to as "row 2" ("R2").
  502. *)
  503. state : J2KU.SetArrayPtr;
  504. mq : MQDecoder; (* A reference to the MQ decoder *)
  505. dbr : J2KU.DataBitReader; (* Used to read raw bits of coefficient data extracted from the stream *)
  506. (* Some entropy decoder options *)
  507. predTerm, resetCtx, vertCausal, segUsed : BOOLEAN;
  508. concealError : BOOLEAN; (* If TRUE, error concealment will be done (if errors are detected) *)
  509. PROCEDURE &InitNew *(edOpt : J2KU.EntropyDecoderOptions;
  510. cr : J2KCS.CodestreamReader;
  511. decSpec : J2KCS.DecoderSpecs);
  512. BEGIN
  513. mq := NIL;
  514. dbr := NIL;
  515. ReInit(edOpt, cr, decSpec);
  516. END InitNew;
  517. PROCEDURE ReInit ( edOpt : J2KU.EntropyDecoderOptions;
  518. cr : J2KCS.CodestreamReader;
  519. decSpec : J2KCS.DecoderSpecs);
  520. BEGIN
  521. concealError := edOpt.concealError;
  522. SELF.cr := cr;
  523. SELF.decSpec := decSpec;
  524. IF mq = NIL THEN
  525. NEW(mq, MQ_INITSTATES, MQ_INITMPS);
  526. ELSE
  527. mq.ReInit(MQ_INITSTATES, MQ_INITMPS);
  528. END;
  529. IF dbr = NIL THEN
  530. NEW(dbr, mq.GetByteReader());
  531. ELSE
  532. dbr.ReInit(mq.GetByteReader());
  533. END;
  534. state := NIL;
  535. END ReInit;
  536. (**
  537. Sets the maximum layer range for which data shall be delivered
  538. and decoded, i.e. data outside this range shall NEVER be requested.
  539. This procedure shall NOT be called after the first code-block data
  540. has been read.
  541. maxStartLayer and maxEndLayer are inclusive.
  542. *)
  543. PROCEDURE SetMaxLayerRange (maxStartLayer, maxEndLayer : LONGINT);
  544. BEGIN
  545. cr.SetMaxLayerRange(maxStartLayer, maxEndLayer);
  546. END SetMaxLayerRange;
  547. (**
  548. Sets the layer range for which data shall be delivered
  549. and decoded.
  550. startLayer and endLayer are inclusive.
  551. *)
  552. PROCEDURE SetLayerRange (startLayer, endLayer : LONGINT);
  553. BEGIN
  554. cr.SetLayerRange(startLayer, endLayer);
  555. END SetLayerRange;
  556. (**
  557. Gets the layer range for which data shall be delivered
  558. and decoded.
  559. startLayer and endLayer are inclusive.
  560. *)
  561. PROCEDURE GetLayerRange (VAR startLayer, endLayer : LONGINT);
  562. BEGIN
  563. cr.GetLayerRange(startLayer, endLayer);
  564. END GetLayerRange;
  565. (**
  566. Sets the maximum decomposition level range for which data shall be delivered
  567. and decoded, i.e. data outside this range shall NEVER be requested. This procedure
  568. shall NOT be called after the first code-block data has been read.
  569. maxStartDecLvl : The decompositon level to start at (inclusive) -> upper bound
  570. maxEndDecLvl : The decomposition level to end at (inclusive) -> lower bound
  571. *)
  572. PROCEDURE SetMaxDecLevelRange (maxStartDecLvl, maxEndDecLvl : LONGINT);
  573. BEGIN
  574. cr.SetMaxDecLevelRange(maxStartDecLvl, maxEndDecLvl);
  575. END SetMaxDecLevelRange;
  576. (**
  577. Sets the decomposition level range for which data shall be delivered
  578. and decoded.
  579. startDecLvl : The decompositon level to start at (inclusive) -> upper bound
  580. endDecLvl : The decomposition level to end at (inclusive) -> lower bound
  581. *)
  582. PROCEDURE SetDecLevelRange (startDecLvl, endDecLvl : LONGINT);
  583. BEGIN
  584. cr.SetDecLevelRange(startDecLvl, endDecLvl);
  585. END SetDecLevelRange;
  586. (**
  587. Gets the decomposition level range for which data shall be delivered
  588. and decoded.
  589. startDecLvl : The decompositon level to start at (inclusive) -> upper bound
  590. endDecLvl : The decomposition level to end at (inclusive) -> lower bound
  591. *)
  592. PROCEDURE GetDecLevelRange (VAR startDecLvl, endDecLvl : LONGINT);
  593. BEGIN
  594. cr.GetDecLevelRange(startDecLvl, endDecLvl);
  595. END GetDecLevelRange;
  596. PROCEDURE SetReBuildMode;
  597. BEGIN
  598. cr.SetReBuildMode();
  599. END SetReBuildMode;
  600. (* Gets the entropy decoded code-blocks *)
  601. PROCEDURE GetCodeBlocks (VAR cblk : ARRAY OF DataBlk; VAR cblkInfo : ARRAY OF J2KU.CblkInfo; ncblks : LONGINT) : LONGINT;
  602. VAR
  603. cblkIdx, ncblksRet : LONGINT;
  604. codedCblk : ARRAY CBLK_BUFSIZE OF J2KU.CodedCblk;
  605. curDataBlk : DataBlkInt;
  606. curCblkInfo : J2KU.CblkInfo;
  607. passes, curBp, lastNonBypassBp, segIdx, tile, comp : LONGINT;
  608. zeroLUT, data : J2KU.LongIntArrayPtr;
  609. bypass, term, cleanupTerm : BOOLEAN; (* Some entropy decoder options *)
  610. ok : BOOLEAN;
  611. BEGIN
  612. (*
  613. This implementation relies on the condition that the component above this one
  614. always requests <= CBLK_BUFSIZE code-blocks
  615. *)
  616. ASSERT(ncblks <= CBLK_BUFSIZE);
  617. ncblksRet := cr.GetCodeBlocks(codedCblk, cblkInfo, ncblks);
  618. (* Get as many coded code-blocks in the stream as needed, decode them *)
  619. tile := cr.CurrentTile();
  620. FOR cblkIdx := 0 TO ncblksRet - 1 DO
  621. curDataBlk := cblk[cblkIdx](DataBlkInt);
  622. curCblkInfo := cblkInfo[cblkIdx];
  623. curBp := curCblkInfo.curbp;
  624. passes := codedCblk[cblkIdx].cpasses;
  625. data := curDataBlk.data;
  626. (* See if we need to allocate a new array *)
  627. IF (data = NIL)
  628. OR (curDataBlk.scanw < curCblkInfo.width)
  629. OR (LEN(data^) < (curDataBlk.scanw*curCblkInfo.height + curDataBlk.offset))
  630. THEN
  631. NEW(data, curCblkInfo.width*curCblkInfo.height);
  632. curDataBlk.data := data;
  633. curDataBlk.offset := 0;
  634. curDataBlk.scanw := curCblkInfo.width;
  635. END;
  636. Machine.Fill32(ADDRESSOF(data[0]), LEN(data^)*SIZEOF(LONGINT), 0);
  637. Machine.Fill32(ADDRESSOF(state[0]), LEN(state^)*SIZEOF(SET), 0);
  638. (* Restart MQ-Decoder *)
  639. IF codedCblk[cblkIdx].nseg > 1 THEN
  640. mq.NextSegment(codedCblk[cblkIdx].data, 0, codedCblk[cblkIdx].segLen[0]);
  641. ELSE
  642. mq.NextSegment(codedCblk[cblkIdx].data, 0, codedCblk[cblkIdx].dataLen);
  643. END;
  644. mq.ResetContexts();
  645. segIdx := 1;
  646. (* See which significance LUT is to be used *)
  647. CASE curCblkInfo.subbinfo.type OF
  648. J2KU.SUB_LL:
  649. zeroLUT := ENTROPY_ZEROLL_LUT;
  650. | J2KU.SUB_HL:
  651. zeroLUT := ENTROPY_ZEROHL_LUT;
  652. | J2KU.SUB_LH:
  653. zeroLUT := ENTROPY_ZEROLL_LUT;
  654. | J2KU.SUB_HH:
  655. zeroLUT := ENTROPY_ZEROHH_LUT;
  656. END;
  657. comp := curCblkInfo.subbinfo.component;
  658. (* Get options *)
  659. bypass := decSpec.BypassCoding(tile, comp);
  660. term := decSpec.RegularTermination(tile, comp);
  661. predTerm := decSpec.PredictableTermination(tile, comp);
  662. resetCtx := decSpec.ResetContexts(tile, comp);
  663. segUsed := decSpec.SegmentationSymbols(tile, comp);
  664. vertCausal := decSpec.VerticallyCausalContext(tile, comp);
  665. IF bypass THEN
  666. (* Determine the first bit-plane for which MQ bypassing is used *)
  667. lastNonBypassBp := J2KU.LONGINT_BITS - 1 - ENTROPY_NUM_NON_BYPASS_BP - curCblkInfo.zerobp;
  668. END;
  669. (* The cleanup pass terminates if the "termination on each coding pass" option is used *)
  670. cleanupTerm := term;
  671. ok := TRUE;
  672. (* Cleanup pass comes first *)
  673. IF (passes > 0) & (curBp >= 0) THEN
  674. ok := CleanupPass(curDataBlk, curCblkInfo, curBp, zeroLUT, cleanupTerm);
  675. DEC(passes);
  676. IF ok OR ~concealError THEN
  677. DEC(curBp);
  678. END;
  679. END;
  680. IF ok OR ~concealError THEN
  681. LOOP
  682. IF (passes <= 0) OR (curBp < 0) THEN EXIT; END;
  683. IF bypass & (curBp < lastNonBypassBp) THEN
  684. (* Raw significance propagation pass *)
  685. (* Start a new raw segment *)
  686. dbr.NextSegment(NIL, -1, codedCblk[cblkIdx].segLen[segIdx]);
  687. INC(segIdx);
  688. ok := RawSigPropPass(curDataBlk, curCblkInfo, curBp, term);
  689. DEC(passes);
  690. IF (passes <= 0) OR (~ok & concealError) THEN EXIT; END;
  691. IF term THEN
  692. (* Start of new raw segment *)
  693. dbr.NextSegment(NIL, -1, codedCblk[cblkIdx].segLen[segIdx]);
  694. INC(segIdx);
  695. END;
  696. (* Raw magnitude refinement pass *)
  697. (* NOTE: We always terminate after this pass *)
  698. ok := RawMagRefPass(curDataBlk, curCblkInfo, curBp, TRUE);
  699. ELSE
  700. IF term THEN
  701. (* Start of new segment *)
  702. mq.NextSegment(NIL, -1, codedCblk[cblkIdx].segLen[segIdx]);
  703. INC(segIdx);
  704. END;
  705. (* Significance propagation pass *)
  706. ok := SigPropPass(curDataBlk, curCblkInfo, curBp, zeroLUT, term);
  707. DEC(passes);
  708. IF (passes <= 0) OR (~ok & concealError) THEN EXIT; END;
  709. IF term THEN
  710. (* Start of new segment *)
  711. mq.NextSegment(NIL, -1, codedCblk[cblkIdx].segLen[segIdx]);
  712. INC(segIdx);
  713. END;
  714. (* Magnitude refinement pass *)
  715. ok := MagRefPass(curDataBlk, curCblkInfo, curBp, term);
  716. END;
  717. DEC(passes);
  718. IF (passes <= 0) OR (~ok & concealError) THEN EXIT; END;
  719. IF term OR (bypass & (curBp < lastNonBypassBp)) THEN
  720. (* Start a new MQ segment *)
  721. mq.NextSegment(NIL, - 1, codedCblk[cblkIdx].segLen[segIdx]);
  722. INC(segIdx);
  723. END;
  724. IF bypass & (curBp = lastNonBypassBp) THEN
  725. (* From now on the cleanup pass always terminates *)
  726. cleanupTerm := TRUE;
  727. END;
  728. (* Cleanup pass *)
  729. ok := CleanupPass(curDataBlk, curCblkInfo, curBp, zeroLUT, cleanupTerm);
  730. DEC(passes);
  731. IF ~ok & concealError THEN EXIT; END;
  732. (* Go to next bit-plane *)
  733. DEC(curBp);
  734. END;
  735. END;
  736. IF ~ok & concealError THEN
  737. LogConcealMsg(curCblkInfo, curBp);
  738. Conceal(curDataBlk, curCblkInfo, curBp);
  739. END;
  740. END;
  741. RETURN ncblksRet;
  742. END GetCodeBlocks;
  743. PROCEDURE DataAvailable () : BOOLEAN;
  744. BEGIN
  745. RETURN ~cr.EndOfCodestream();
  746. END DataAvailable;
  747. PROCEDURE TilePartAvailable () : BOOLEAN;
  748. BEGIN
  749. RETURN cr.TilePartAvailable();
  750. END TilePartAvailable;
  751. PROCEDURE AllTilePartsRead () : BOOLEAN;
  752. BEGIN
  753. RETURN cr.AllTilePartsRead();
  754. END AllTilePartsRead;
  755. PROCEDURE NextTilePart () : BOOLEAN;
  756. BEGIN
  757. IF ~cr.NextTilePart() THEN
  758. RETURN FALSE;
  759. END;
  760. RETURN InitTile();
  761. END NextTilePart;
  762. PROCEDURE InitTile () : BOOLEAN;
  763. VAR
  764. curTile, maxCblkWidth, maxCblkHeight, maxSize : LONGINT;
  765. BEGIN
  766. IF cr.CurrentTilePart() = 0 THEN
  767. (* See if we have to enlarge the state array *)
  768. curTile := cr.CurrentTile();
  769. maxCblkWidth := LSH(SYSTEM.VAL(LONGINT, 1), decSpec.GetMaxCblkWidthExp(curTile));
  770. maxCblkHeight := LSH(SYSTEM.VAL(LONGINT, 1), decSpec.GetMaxCblkHeightExp(curTile));
  771. maxSize := (maxCblkWidth + 2 * ENTROPY_ARRAYOFF) * (((maxCblkHeight + 1 ) DIV 2)+ 2 * ENTROPY_ARRAYOFF);
  772. IF (state = NIL) OR (LEN(state^) < maxSize) THEN
  773. NEW(state, maxSize);
  774. END;
  775. END;
  776. RETURN TRUE;
  777. END InitTile;
  778. PROCEDURE CurrentTile () : LONGINT;
  779. BEGIN
  780. RETURN cr.CurrentTile();
  781. END CurrentTile;
  782. PROCEDURE CurrentTilePart () : LONGINT;
  783. BEGIN
  784. RETURN cr.CurrentTilePart();
  785. END CurrentTilePart;
  786. PROCEDURE GetSubbandInfo (tile, component, reslevel, subband : LONGINT) : J2KU.SubbandInfo;
  787. BEGIN
  788. RETURN cr.GetSubbandInfo(tile, component, reslevel, subband)
  789. END GetSubbandInfo;
  790. (* Logs a message when an error has been detected and concealing is done *)
  791. PROCEDURE LogConcealMsg (cblkInfo : J2KU.CblkInfo; curBp : LONGINT);
  792. BEGIN
  793. KernelLog.String("WARNING: EntropyDecoder detected error at bit-plane ");
  794. KernelLog.Int(curBp, 0);
  795. KernelLog.String(" in code-block ");
  796. KernelLog.Int(cblkInfo.index, 0);
  797. KernelLog.String(" , subband index ");
  798. KernelLog.Int(cblkInfo.subbinfo.index, 0);
  799. KernelLog.String(", res. level");
  800. KernelLog.Int(cblkInfo.subbinfo.reslevel, 0);
  801. KernelLog.String(", component ");
  802. KernelLog.Int(cblkInfo.subbinfo.component, 0);
  803. KernelLog.String(", tile ");
  804. KernelLog.Int(cr.CurrentTile(), 0);
  805. KernelLog.Ln();
  806. KernelLog.String("Concealing...");
  807. KernelLog.Ln();
  808. END LogConcealMsg;
  809. (* This procedure applies the significance propagation pass to the compressed image data *)
  810. PROCEDURE SigPropPass (cblk : DataBlk; cblkInfo : J2KU.CblkInfo; curBp : LONGINT; zeroLUT : J2KU.LongIntArrayPtr; term : BOOLEAN) : BOOLEAN;
  811. VAR
  812. i, j : LONGINT;
  813. stripeHeight : LONGINT;
  814. dataIdx, stateIdx : LONGINT;
  815. curState : SET;
  816. rowStartState, rowWidthState, rowStartData : LONGINT;
  817. stateStripeIncr, dataStripeIncr : LONGINT;
  818. ctx : LONGINT;
  819. sign : LONGINT;
  820. setMask : SET;
  821. ok : BOOLEAN;
  822. data : J2KU.LongIntArrayPtr;
  823. scanw : LONGINT; (* The scan width of the code-block data *)
  824. off_ul, off_ur, off_dl, off_dr : LONGINT;
  825. BEGIN
  826. (* Get local reference to data *)
  827. data := cblk(DataBlkInt).data;
  828. setMask := SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 3), curBp - 1));
  829. rowWidthState := cblkInfo.width + 2 * ENTROPY_ARRAYOFF;
  830. (* Cache rowStart (of the extended arrays) *)
  831. rowStartState := rowWidthState + ENTROPY_ARRAYOFF;
  832. scanw := cblk.scanw;
  833. rowStartData := cblk.offset;
  834. stateStripeIncr := (ENTROPY_STRIPE_HEIGHT DIV 2)*rowWidthState;
  835. dataStripeIncr := ENTROPY_STRIPE_HEIGHT*scanw;
  836. (* Offsets for diagonal neighbors *)
  837. off_ul := -rowWidthState - 1; (* Up left *)
  838. off_ur := -rowWidthState + 1; (* Up right *)
  839. off_dl := rowWidthState - 1; (* Down left *)
  840. off_dr := rowWidthState + 1; (* Down right *)
  841. i := 0;
  842. (* Loop on rows *)
  843. WHILE i < cblkInfo.height DO
  844. (* We have to check if there are enough rows to scan an entire stripe or just a truncated one *)
  845. IF ENTROPY_STRIPE_HEIGHT > (cblkInfo.height - i) THEN
  846. stripeHeight := cblkInfo.height - i;
  847. ELSE
  848. stripeHeight := ENTROPY_STRIPE_HEIGHT;
  849. END;
  850. FOR j := 0 TO cblkInfo.width - 1 DO
  851. stateIdx := rowStartState + j;
  852. dataIdx := rowStartData + j;
  853. curState := state[stateIdx];
  854. (* Scan 1st row *)
  855. IF (curState * STATE_SIG_R1 = {})
  856. & (curState * STATE_VECT_MASK_R1 # {})
  857. THEN
  858. (* Did the coefficient just become significant? If not, move on *)
  859. IF mq.Decode(zeroLUT[SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R1)]) = 1 THEN
  860. (* Coefficient has become significant -> decode sign bit *)
  861. ctx := ENTROPY_SIGN_LUT[LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R1), -SIGN_VECT_SHIFT_R1)];
  862. sign := SYSTEM.VAL(LONGINT,
  863. SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
  864. / SYSTEM.VAL(SET, LSH(ctx, -J2KU.LONGINT_BITS + 1))
  865. );
  866. data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
  867. (* Update state information*)
  868. IF ~vertCausal THEN
  869. (* Upper diagonal neighbors *)
  870. (* Only update previous stripe if not in vertical causal mode *)
  871. state[stateIdx + off_ul] := state[stateIdx + off_ul] + STATE_D_DR_R2;
  872. state[stateIdx + off_ur] := state[stateIdx + off_ur] + STATE_D_DL_R2;
  873. END;
  874. (* Update rest of neighbors, depending on sign *)
  875. IF sign # 0 THEN
  876. curState := curState
  877. + STATE_SIG_R1 + STATE_VISITED_R1
  878. + STATE_V_U_R2 + STATE_V_U_SIGN_R2;
  879. IF ~vertCausal THEN
  880. (* Only update previous stripe if not in vertical causal mode *)
  881. state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
  882. + STATE_V_D_R2
  883. + STATE_V_D_SIGN_R2;
  884. END;
  885. state [stateIdx - 1] := state[stateIdx - 1]
  886. + STATE_H_R_R1
  887. + STATE_H_R_SIGN_R1
  888. + STATE_D_UR_R2;
  889. state [stateIdx + 1] := state[stateIdx + 1]
  890. + STATE_H_L_R1
  891. + STATE_H_L_SIGN_R1
  892. + STATE_D_UL_R2;
  893. ELSE
  894. curState := curState
  895. + STATE_SIG_R1 + STATE_VISITED_R1
  896. + STATE_V_U_R2;
  897. IF ~vertCausal THEN
  898. (* Only update previous stripe if not in vertical causal mode *)
  899. state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
  900. + STATE_V_D_R2;
  901. END;
  902. state [stateIdx - 1] := state[stateIdx - 1]
  903. + STATE_H_R_R1
  904. + STATE_D_UR_R2;
  905. state [stateIdx + 1] := state[stateIdx + 1]
  906. + STATE_H_L_R1
  907. + STATE_D_UL_R2;
  908. END;
  909. ELSE
  910. curState := curState + STATE_VISITED_R1;
  911. END;
  912. state[stateIdx] := curState;
  913. END;
  914. (* Scan 2nd row *)
  915. INC(dataIdx, scanw);
  916. IF (stripeHeight > 1)
  917. & (curState * STATE_SIG_R2 = {})
  918. & (curState * STATE_VECT_MASK_R2 # {})
  919. THEN
  920. (* Did the coefficient just become significant? If not, move on *)
  921. IF mq.Decode(zeroLUT[LSH(SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R2), -STATE_SEP)]) = 1 THEN
  922. (* Coefficient has become significant -> decode sign bit *)
  923. ctx := ENTROPY_SIGN_LUT[LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R2), -SIGN_VECT_SHIFT_R2)];
  924. sign := SYSTEM.VAL(LONGINT,
  925. SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
  926. / SYSTEM.VAL(SET, LSH(ctx, -J2KU.LONGINT_BITS + 1))
  927. );
  928. data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
  929. (* Update state information*)
  930. (* Lower diagonal neighbors *)
  931. state[stateIdx + off_dl] := state[stateIdx + off_dl] + STATE_D_UR_R1;
  932. state[stateIdx + off_dr] := state[stateIdx + off_dr] + STATE_D_UL_R1;
  933. (* Update rest of neighbors, depending on sign *)
  934. IF sign # 0 THEN
  935. curState := curState
  936. + STATE_SIG_R2 + STATE_VISITED_R2
  937. + STATE_V_D_R1 + STATE_V_D_SIGN_R1;
  938. state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
  939. + STATE_V_U_R1
  940. + STATE_V_U_SIGN_R1;
  941. state[stateIdx - 1] := state[stateIdx - 1]
  942. + STATE_H_R_R2
  943. + STATE_H_R_SIGN_R2
  944. + STATE_D_DR_R1;
  945. state[stateIdx + 1] := state[stateIdx + 1]
  946. + STATE_H_L_R2
  947. + STATE_H_L_SIGN_R2
  948. + STATE_D_DL_R1;
  949. ELSE
  950. curState := curState
  951. + STATE_SIG_R2 + STATE_VISITED_R2
  952. + STATE_V_D_R1;
  953. state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
  954. + STATE_V_U_R1;
  955. state[stateIdx - 1] := state[stateIdx - 1]
  956. + STATE_H_R_R2
  957. + STATE_D_DR_R1;
  958. state [stateIdx + 1] := state[stateIdx + 1]
  959. + STATE_H_L_R2
  960. + STATE_D_DL_R1;
  961. END;
  962. ELSE
  963. curState := curState + STATE_VISITED_R2;
  964. END;
  965. state[stateIdx] := curState;
  966. END;
  967. (* Scan 3rd row *)
  968. INC(stateIdx, rowWidthState);
  969. INC(dataIdx, scanw);
  970. curState := state[stateIdx];
  971. IF (stripeHeight > 2)
  972. & (curState * STATE_SIG_R1 = {})
  973. & (curState * STATE_VECT_MASK_R1 # {})
  974. THEN
  975. (* Did the coefficient just become significant? If not, move on *)
  976. IF mq.Decode(zeroLUT[SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R1)]) = 1 THEN
  977. (* Coefficient has become significant -> decode sign bit *)
  978. ctx := ENTROPY_SIGN_LUT[LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R1), -SIGN_VECT_SHIFT_R1)];
  979. sign := SYSTEM.VAL(LONGINT,
  980. SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
  981. / SYSTEM.VAL(SET, LSH(ctx, -J2KU.LONGINT_BITS + 1))
  982. );
  983. data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
  984. (* Update state information*)
  985. (* Upper diagonal neighbors *)
  986. state[stateIdx + off_ul] := state[stateIdx + off_ul] + STATE_D_DR_R2;
  987. state[stateIdx + off_ur] := state[stateIdx + off_ur] + STATE_D_DL_R2;
  988. (* Update rest of neighbors, depending on sign *)
  989. IF sign # 0 THEN
  990. curState := curState
  991. + STATE_SIG_R1 + STATE_VISITED_R1
  992. + STATE_V_U_R2 + STATE_V_U_SIGN_R2;
  993. state[stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
  994. + STATE_V_D_R2
  995. + STATE_V_D_SIGN_R2;
  996. state[stateIdx - 1] := state[stateIdx - 1]
  997. + STATE_H_R_R1
  998. + STATE_H_R_SIGN_R1
  999. + STATE_D_UR_R2;
  1000. state[stateIdx + 1] := state[stateIdx + 1]
  1001. + STATE_H_L_R1
  1002. + STATE_H_L_SIGN_R1
  1003. + STATE_D_UL_R2;
  1004. ELSE
  1005. curState := curState
  1006. + STATE_SIG_R1 + STATE_VISITED_R1
  1007. + STATE_V_U_R2;
  1008. state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
  1009. + STATE_V_D_R2;
  1010. state[stateIdx - 1] := state[stateIdx - 1]
  1011. + STATE_H_R_R1
  1012. + STATE_D_UR_R2;
  1013. state[stateIdx + 1] := state[stateIdx + 1]
  1014. + STATE_H_L_R1
  1015. + STATE_D_UL_R2;
  1016. END;
  1017. ELSE
  1018. curState := curState + STATE_VISITED_R1;
  1019. END;
  1020. state[stateIdx] := curState;
  1021. END;
  1022. (* Scan 4th row *)
  1023. INC(dataIdx, scanw);
  1024. IF (stripeHeight > 3)
  1025. & (curState * STATE_SIG_R2 = {})
  1026. & (curState * STATE_VECT_MASK_R2 # {})
  1027. THEN
  1028. (* Did the coefficient just become significant? If not, move on *)
  1029. IF mq.Decode(zeroLUT[LSH(SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R2), -STATE_SEP)]) = 1 THEN
  1030. (* Coefficient has become significant -> decode sign bit *)
  1031. ctx := ENTROPY_SIGN_LUT[LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R2), -SIGN_VECT_SHIFT_R2)];
  1032. sign := SYSTEM.VAL(LONGINT,
  1033. SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
  1034. / SYSTEM.VAL(SET, LSH(ctx, -J2KU.LONGINT_BITS + 1))
  1035. );
  1036. data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
  1037. (* Update state information*)
  1038. (* Lower diagonal neighbors *)
  1039. state[stateIdx + off_dl] := state[stateIdx + off_dl] + STATE_D_UR_R1;
  1040. state[stateIdx + off_dr] := state[stateIdx + off_dr] + STATE_D_UL_R1;
  1041. (* Update rest of neighbors, depending on sign *)
  1042. IF sign # 0 THEN
  1043. curState := curState
  1044. + STATE_SIG_R2 + STATE_VISITED_R2
  1045. + STATE_V_D_R1 + STATE_V_D_SIGN_R1;
  1046. state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
  1047. + STATE_V_U_R1
  1048. + STATE_V_U_SIGN_R1;
  1049. state[stateIdx - 1] := state[stateIdx - 1]
  1050. + STATE_H_R_R2
  1051. + STATE_H_R_SIGN_R2
  1052. + STATE_D_DR_R1;
  1053. state[stateIdx + 1] := state[stateIdx + 1]
  1054. + STATE_H_L_R2
  1055. + STATE_H_L_SIGN_R2
  1056. + STATE_D_DL_R1;
  1057. ELSE
  1058. curState := curState
  1059. + STATE_SIG_R2 + STATE_VISITED_R2
  1060. + STATE_V_D_R1;
  1061. state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
  1062. + STATE_V_U_R1;
  1063. state[stateIdx - 1] := state[stateIdx - 1]
  1064. + STATE_H_R_R2
  1065. + STATE_D_DR_R1;
  1066. state [stateIdx + 1] := state[stateIdx + 1]
  1067. + STATE_H_L_R2
  1068. + STATE_D_DL_R1;
  1069. END;
  1070. ELSE
  1071. curState := curState + STATE_VISITED_R2;
  1072. END;
  1073. state[stateIdx] := curState;
  1074. END;
  1075. END;
  1076. (* Move to next row of stripes *)
  1077. INC(i, ENTROPY_STRIPE_HEIGHT);
  1078. (* Compute row start of next row *)
  1079. rowStartState := rowStartState + stateStripeIncr;
  1080. rowStartData := rowStartData + dataStripeIncr;
  1081. END;
  1082. (* We may do an error check if predictable termination is used *)
  1083. IF predTerm & term THEN
  1084. ok := mq.CheckPredTerm();
  1085. ELSE
  1086. ok := TRUE;
  1087. END;
  1088. (* Maybe need to reset contexts *)
  1089. IF resetCtx THEN
  1090. mq.ResetContexts();
  1091. END;
  1092. RETURN ok;
  1093. END SigPropPass;
  1094. (*
  1095. This procedure applies the significance propagation pass to the compressed image data,
  1096. reading bits directly from the stream
  1097. *)
  1098. PROCEDURE RawSigPropPass (cblk : DataBlk; cblkInfo : J2KU.CblkInfo; curBp : LONGINT; term : BOOLEAN) : BOOLEAN;
  1099. VAR
  1100. i, j : LONGINT;
  1101. stripeHeight : LONGINT;
  1102. dataIdx, stateIdx : LONGINT;
  1103. curState : SET;
  1104. rowStartState, rowWidthState, rowStartData : LONGINT;
  1105. stateStripeIncr, dataStripeIncr : LONGINT;
  1106. sign : LONGINT;
  1107. setMask : SET;
  1108. ok : BOOLEAN;
  1109. data : J2KU.LongIntArrayPtr;
  1110. scanw : LONGINT; (* The scan width of the code-block data *)
  1111. off_ul, off_ur, off_dl, off_dr : LONGINT;
  1112. BEGIN
  1113. (* Get local reference to data *)
  1114. data := cblk(DataBlkInt).data;
  1115. setMask := SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 3), curBp - 1));
  1116. rowWidthState := cblkInfo.width + 2 * ENTROPY_ARRAYOFF;
  1117. (* Cache rowStart (of the extended arrays) *)
  1118. rowStartState := rowWidthState + ENTROPY_ARRAYOFF;
  1119. scanw := cblk.scanw;
  1120. rowStartData := cblk.offset;
  1121. stateStripeIncr := (ENTROPY_STRIPE_HEIGHT DIV 2)*rowWidthState;
  1122. dataStripeIncr := ENTROPY_STRIPE_HEIGHT*scanw;
  1123. (* Offsets for diagonal neighbors *)
  1124. off_ul := -rowWidthState - 1; (* Up left *)
  1125. off_ur := -rowWidthState + 1; (* Up right *)
  1126. off_dl := rowWidthState - 1; (* Down left *)
  1127. off_dr := rowWidthState + 1; (* Down right *)
  1128. i := 0;
  1129. (* Loop on rows *)
  1130. WHILE i < cblkInfo.height DO
  1131. (* We have to check if there are enough rows to scan an entire stripe or just a truncated one *)
  1132. IF ENTROPY_STRIPE_HEIGHT > (cblkInfo.height - i) THEN
  1133. stripeHeight := cblkInfo.height - i;
  1134. ELSE
  1135. stripeHeight := ENTROPY_STRIPE_HEIGHT;
  1136. END;
  1137. FOR j := 0 TO cblkInfo.width - 1 DO
  1138. stateIdx := rowStartState + j;
  1139. dataIdx := rowStartData + j;
  1140. curState := state[stateIdx];
  1141. (* Scan 1st row *)
  1142. IF (curState * STATE_SIG_R1 = {})
  1143. & (curState * STATE_VECT_MASK_R1 # {})
  1144. THEN
  1145. (* Did the coefficient just become significant? If not, move on *)
  1146. IF dbr.NextBit() = 1 THEN
  1147. (* Coefficient has become significant -> decode sign bit *)
  1148. sign := dbr.NextBit();
  1149. data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
  1150. (* Update state information*)
  1151. IF ~vertCausal THEN
  1152. (* Upper diagonal neighbors *)
  1153. (* Only update previous stripe if not in vertical causal mode *)
  1154. state[stateIdx + off_ul] := state[stateIdx + off_ul] + STATE_D_DR_R2;
  1155. state[stateIdx + off_ur] := state[stateIdx + off_ur] + STATE_D_DL_R2;
  1156. END;
  1157. (* Update rest of neighbors, depending on sign *)
  1158. IF sign # 0 THEN
  1159. curState := curState
  1160. + STATE_SIG_R1 + STATE_VISITED_R1
  1161. + STATE_V_U_R2 + STATE_V_U_SIGN_R2;
  1162. IF ~vertCausal THEN
  1163. (* Only update previous stripe if not in vertical causal mode *)
  1164. state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
  1165. + STATE_V_D_R2
  1166. + STATE_V_D_SIGN_R2;
  1167. END;
  1168. state [stateIdx - 1] := state[stateIdx - 1]
  1169. + STATE_H_R_R1
  1170. + STATE_H_R_SIGN_R1
  1171. + STATE_D_UR_R2;
  1172. state [stateIdx + 1] := state[stateIdx + 1]
  1173. + STATE_H_L_R1
  1174. + STATE_H_L_SIGN_R1
  1175. + STATE_D_UL_R2;
  1176. ELSE
  1177. curState := curState
  1178. + STATE_SIG_R1 + STATE_VISITED_R1
  1179. + STATE_V_U_R2;
  1180. IF ~vertCausal THEN
  1181. (* Only update previous stripe if not in vertical causal mode *)
  1182. state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
  1183. + STATE_V_D_R2;
  1184. END;
  1185. state [stateIdx - 1] := state[stateIdx - 1]
  1186. + STATE_H_R_R1
  1187. + STATE_D_UR_R2;
  1188. state [stateIdx + 1] := state[stateIdx + 1]
  1189. + STATE_H_L_R1
  1190. + STATE_D_UL_R2;
  1191. END;
  1192. ELSE
  1193. curState := curState + STATE_VISITED_R1;
  1194. END;
  1195. state[stateIdx] := curState;
  1196. END;
  1197. (* Scan 2nd row *)
  1198. INC(dataIdx, scanw);
  1199. IF (stripeHeight > 1)
  1200. & (curState * STATE_SIG_R2 = {})
  1201. & (curState * STATE_VECT_MASK_R2 # {})
  1202. THEN
  1203. (* Did the coefficient just become significant? If not, move on *)
  1204. IF dbr.NextBit() = 1 THEN
  1205. (* Coefficient has become significant -> decode sign bit *)
  1206. sign := dbr.NextBit();
  1207. data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
  1208. (* Update state information*)
  1209. (* Lower diagonal neighbors *)
  1210. state[stateIdx + off_dl] := state[stateIdx + off_dl] + STATE_D_UR_R1;
  1211. state[stateIdx + off_dr] := state[stateIdx + off_dr] + STATE_D_UL_R1;
  1212. (* Update rest of neighbors, depending on sign *)
  1213. IF sign # 0 THEN
  1214. curState := curState
  1215. + STATE_SIG_R2 + STATE_VISITED_R2
  1216. + STATE_V_D_R1 + STATE_V_D_SIGN_R1;
  1217. state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
  1218. + STATE_V_U_R1
  1219. + STATE_V_U_SIGN_R1;
  1220. state[stateIdx - 1] := state[stateIdx - 1]
  1221. + STATE_H_R_R2
  1222. + STATE_H_R_SIGN_R2
  1223. + STATE_D_DR_R1;
  1224. state[stateIdx + 1] := state[stateIdx + 1]
  1225. + STATE_H_L_R2
  1226. + STATE_H_L_SIGN_R2
  1227. + STATE_D_DL_R1;
  1228. ELSE
  1229. curState := curState
  1230. + STATE_SIG_R2 + STATE_VISITED_R2
  1231. + STATE_V_D_R1;
  1232. state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
  1233. + STATE_V_U_R1;
  1234. state[stateIdx - 1] := state[stateIdx - 1]
  1235. + STATE_H_R_R2
  1236. + STATE_D_DR_R1;
  1237. state [stateIdx + 1] := state[stateIdx + 1]
  1238. + STATE_H_L_R2
  1239. + STATE_D_DL_R1;
  1240. END;
  1241. ELSE
  1242. curState := curState + STATE_VISITED_R2;
  1243. END;
  1244. state[stateIdx] := curState;
  1245. END;
  1246. (* Scan 3rd row *)
  1247. INC(stateIdx, rowWidthState);
  1248. INC(dataIdx, scanw);
  1249. curState := state[stateIdx];
  1250. IF (stripeHeight > 2)
  1251. & (curState * STATE_SIG_R1 = {})
  1252. & (curState * STATE_VECT_MASK_R1 # {})
  1253. THEN
  1254. (* Did the coefficient just become significant? If not, move on *)
  1255. IF dbr.NextBit() = 1 THEN
  1256. (* Coefficient has become significant -> decode sign bit *)
  1257. sign := dbr.NextBit();
  1258. data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
  1259. (* Update state information*)
  1260. (* Upper diagonal neighbors *)
  1261. state[stateIdx + off_ul] := state[stateIdx + off_ul] + STATE_D_DR_R2;
  1262. state[stateIdx + off_ur] := state[stateIdx + off_ur] + STATE_D_DL_R2;
  1263. (* Update rest of neighbors, depending on sign *)
  1264. IF sign # 0 THEN
  1265. curState := curState
  1266. + STATE_SIG_R1 + STATE_VISITED_R1
  1267. + STATE_V_U_R2 + STATE_V_U_SIGN_R2;
  1268. state[stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
  1269. + STATE_V_D_R2
  1270. + STATE_V_D_SIGN_R2;
  1271. state[stateIdx - 1] := state[stateIdx - 1]
  1272. + STATE_H_R_R1
  1273. + STATE_H_R_SIGN_R1
  1274. + STATE_D_UR_R2;
  1275. state[stateIdx + 1] := state[stateIdx + 1]
  1276. + STATE_H_L_R1
  1277. + STATE_H_L_SIGN_R1
  1278. + STATE_D_UL_R2;
  1279. ELSE
  1280. curState := curState
  1281. + STATE_SIG_R1 + STATE_VISITED_R1
  1282. + STATE_V_U_R2;
  1283. state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
  1284. + STATE_V_D_R2;
  1285. state[stateIdx - 1] := state[stateIdx - 1]
  1286. + STATE_H_R_R1
  1287. + STATE_D_UR_R2;
  1288. state[stateIdx + 1] := state[stateIdx + 1]
  1289. + STATE_H_L_R1
  1290. + STATE_D_UL_R2;
  1291. END;
  1292. ELSE
  1293. curState := curState + STATE_VISITED_R1;
  1294. END;
  1295. state[stateIdx] := curState;
  1296. END;
  1297. (* Scan 4th row *)
  1298. INC(dataIdx, scanw);
  1299. IF (stripeHeight > 3)
  1300. & (curState * STATE_SIG_R2 = {})
  1301. & (curState * STATE_VECT_MASK_R2 # {})
  1302. THEN
  1303. (* Did the coefficient just become significant? If not, move on *)
  1304. IF dbr.NextBit() = 1 THEN
  1305. (* Coefficient has become significant -> decode sign bit *)
  1306. sign := dbr.NextBit();
  1307. data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
  1308. (* Update state information*)
  1309. (* Lower diagonal neighbors *)
  1310. state[stateIdx + off_dl] := state[stateIdx + off_dl] + STATE_D_UR_R1;
  1311. state[stateIdx + off_dr] := state[stateIdx + off_dr] + STATE_D_UL_R1;
  1312. (* Update rest of neighbors, depending on sign *)
  1313. IF sign # 0 THEN
  1314. curState := curState
  1315. + STATE_SIG_R2 + STATE_VISITED_R2
  1316. + STATE_V_D_R1 + STATE_V_D_SIGN_R1;
  1317. state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
  1318. + STATE_V_U_R1
  1319. + STATE_V_U_SIGN_R1;
  1320. state[stateIdx - 1] := state[stateIdx - 1]
  1321. + STATE_H_R_R2
  1322. + STATE_H_R_SIGN_R2
  1323. + STATE_D_DR_R1;
  1324. state[stateIdx + 1] := state[stateIdx + 1]
  1325. + STATE_H_L_R2
  1326. + STATE_H_L_SIGN_R2
  1327. + STATE_D_DL_R1;
  1328. ELSE
  1329. curState := curState
  1330. + STATE_SIG_R2 + STATE_VISITED_R2
  1331. + STATE_V_D_R1;
  1332. state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
  1333. + STATE_V_U_R1;
  1334. state[stateIdx - 1] := state[stateIdx - 1]
  1335. + STATE_H_R_R2
  1336. + STATE_D_DR_R1;
  1337. state [stateIdx + 1] := state[stateIdx + 1]
  1338. + STATE_H_L_R2
  1339. + STATE_D_DL_R1;
  1340. END;
  1341. ELSE
  1342. curState := curState + STATE_VISITED_R2;
  1343. END;
  1344. state[stateIdx] := curState;
  1345. END;
  1346. END;
  1347. (* Move to next row of stripes *)
  1348. INC(i, ENTROPY_STRIPE_HEIGHT);
  1349. (* Compute row start of next row *)
  1350. rowStartState := rowStartState + stateStripeIncr;
  1351. rowStartData := rowStartData + dataStripeIncr;
  1352. END;
  1353. (* Try to detect error *)
  1354. IF term THEN
  1355. ok := dbr.CheckBytePadding();
  1356. ELSE
  1357. ok := TRUE;
  1358. END;
  1359. RETURN ok;
  1360. END RawSigPropPass;
  1361. (* This procedure applies the magnitude refinement pass to the compressed image data *)
  1362. PROCEDURE MagRefPass (cblk : DataBlk; cblkInfo : J2KU.CblkInfo; curBp : LONGINT; term : BOOLEAN) : BOOLEAN;
  1363. VAR
  1364. i, j : LONGINT;
  1365. stripeHeight : LONGINT;
  1366. dataIdx, stateIdx : LONGINT;
  1367. curState : SET;
  1368. rowStartState, rowWidthState, rowStartData : LONGINT;
  1369. stateStripeIncr, dataStripeIncr : LONGINT;
  1370. bit : LONGINT;
  1371. tmpDataSample : SET;
  1372. setMask, resetMask : SET;
  1373. ok : BOOLEAN;
  1374. data : J2KU.LongIntArrayPtr;
  1375. scanw : LONGINT; (* The scan width of the code-block data *)
  1376. off_ul, off_ur, off_dl, off_dr : LONGINT;
  1377. BEGIN
  1378. (* Get local reference to data *)
  1379. data := cblk(DataBlkInt).data;
  1380. setMask := SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), curBp - 1));
  1381. resetMask := SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, -1), curBp + 1));
  1382. rowWidthState := cblkInfo.width + 2 * ENTROPY_ARRAYOFF;
  1383. (* Cache rowStart (of the extended arrays) *)
  1384. rowStartState := rowWidthState + ENTROPY_ARRAYOFF;
  1385. scanw := cblk.scanw;
  1386. rowStartData := cblk.offset;
  1387. stateStripeIncr := (ENTROPY_STRIPE_HEIGHT DIV 2)*rowWidthState;
  1388. dataStripeIncr := ENTROPY_STRIPE_HEIGHT*scanw;
  1389. (* Offsets for diagonal neighbors *)
  1390. off_ul := -rowWidthState - 1; (* Up left *)
  1391. off_ur := -rowWidthState + 1; (* Up right *)
  1392. off_dl := rowWidthState - 1; (* Down left *)
  1393. off_dr := rowWidthState + 1; (* Down right *)
  1394. i := 0;
  1395. (* Loop on rows *)
  1396. WHILE i < cblkInfo.height DO
  1397. (* We have to check if there are enough rows to scan an entire stripe or just a truncated one *)
  1398. IF ENTROPY_STRIPE_HEIGHT > (cblkInfo.height - i) THEN
  1399. stripeHeight := cblkInfo.height - i;
  1400. ELSE
  1401. stripeHeight := ENTROPY_STRIPE_HEIGHT;
  1402. END;
  1403. FOR j := 0 TO cblkInfo.width - 1 DO
  1404. stateIdx := rowStartState + j;
  1405. dataIdx := rowStartData + j;
  1406. curState := state[stateIdx];
  1407. (* Scan 1st row *)
  1408. IF ((curState * STATE_SIG_R1) = STATE_SIG_R1)
  1409. & ((curState * STATE_VISITED_R1) = {})
  1410. THEN
  1411. IF (curState * STATE_MAGREF_R1) = STATE_MAGREF_R1 THEN
  1412. bit := mq.Decode(ENTROPY_MR_CTX);
  1413. ELSE (* First time in magnitude refinement pass *)
  1414. IF (curState * STATE_VECT_MASK_R1) = {} THEN
  1415. (* No neighbor significant *)
  1416. bit := mq.Decode(ENTROPY_MR_FIRSTZ_CTX);
  1417. ELSE
  1418. bit := mq.Decode(ENTROPY_MR_FIRSTNZ_CTX);
  1419. END;
  1420. (* Mark the coefficient as being in the magnitude refinement pass *)
  1421. state[stateIdx] := curState + STATE_MAGREF_R1;
  1422. curState := curState + STATE_MAGREF_R1;
  1423. END;
  1424. tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
  1425. data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, LSH(bit, curBp)) + setMask);
  1426. END;
  1427. (* Scan 2nd row *)
  1428. INC(dataIdx, scanw);
  1429. IF (stripeHeight > 1)
  1430. & (curState * STATE_SIG_R2 = STATE_SIG_R2)
  1431. & (curState * STATE_VISITED_R2 = {})
  1432. THEN
  1433. IF (curState * STATE_MAGREF_R2) = STATE_MAGREF_R2 THEN
  1434. bit := mq.Decode(ENTROPY_MR_CTX);
  1435. ELSE (* First time in magnitude refinement pass *)
  1436. IF curState * STATE_VECT_MASK_R2 = {} THEN
  1437. (* No neighbor significant *)
  1438. bit := mq.Decode(ENTROPY_MR_FIRSTZ_CTX);
  1439. ELSE
  1440. bit := mq.Decode(ENTROPY_MR_FIRSTNZ_CTX);
  1441. END;
  1442. (* Mark the coefficient as being in the magnitude refinement pass *)
  1443. state[stateIdx] := curState + STATE_MAGREF_R2;
  1444. END;
  1445. tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
  1446. data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, LSH(bit, curBp)) + setMask);
  1447. END;
  1448. (* Scan 3rd row *)
  1449. INC(stateIdx, rowWidthState);
  1450. INC(dataIdx, scanw);
  1451. curState := state[stateIdx];
  1452. IF (stripeHeight > 2)
  1453. & (curState * STATE_SIG_R1 = STATE_SIG_R1)
  1454. & (curState * STATE_VISITED_R1 = {})
  1455. THEN
  1456. IF (curState * STATE_MAGREF_R1) = STATE_MAGREF_R1 THEN
  1457. bit := mq.Decode(ENTROPY_MR_CTX);
  1458. ELSE (* First time in magnitude refinement pass *)
  1459. IF curState * STATE_VECT_MASK_R1 = {} THEN
  1460. (* No neighbor significant *)
  1461. bit := mq.Decode(ENTROPY_MR_FIRSTZ_CTX);
  1462. ELSE
  1463. bit := mq.Decode(ENTROPY_MR_FIRSTNZ_CTX);
  1464. END;
  1465. (* Mark the coefficient as being in the magnitude refinement pass *)
  1466. state[stateIdx] := curState + STATE_MAGREF_R1;
  1467. curState := curState + STATE_MAGREF_R1;
  1468. END;
  1469. tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
  1470. data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, LSH(bit, curBp)) + setMask);
  1471. END;
  1472. (* Scan 4th row *)
  1473. INC(dataIdx, scanw);
  1474. IF (stripeHeight > 3)
  1475. & (curState * STATE_SIG_R2 = STATE_SIG_R2)
  1476. & (curState * STATE_VISITED_R2 = {})
  1477. THEN
  1478. IF (curState * STATE_MAGREF_R2) = STATE_MAGREF_R2 THEN
  1479. bit := mq.Decode(ENTROPY_MR_CTX);
  1480. ELSE (* First time in magnitude refinement pass *)
  1481. IF curState * STATE_VECT_MASK_R2 = {} THEN
  1482. (* No neighbor significant *)
  1483. bit := mq.Decode(ENTROPY_MR_FIRSTZ_CTX);
  1484. ELSE
  1485. bit := mq.Decode(ENTROPY_MR_FIRSTNZ_CTX);
  1486. END;
  1487. (* Mark the coefficient as being in the magnitude refinement pass *)
  1488. state[stateIdx] := curState + STATE_MAGREF_R2;
  1489. END;
  1490. tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
  1491. data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, LSH(bit, curBp)) + setMask);
  1492. END;
  1493. END;
  1494. (* Move to next row of stripes *)
  1495. INC(i, ENTROPY_STRIPE_HEIGHT);
  1496. (* Compute row start of next row *)
  1497. rowStartState := rowStartState + stateStripeIncr;
  1498. rowStartData := rowStartData + dataStripeIncr;
  1499. END;
  1500. (* We may do an error check if predictable termination is used *)
  1501. IF predTerm & term THEN
  1502. ok := mq.CheckPredTerm();
  1503. ELSE
  1504. ok := TRUE;
  1505. END;
  1506. (* Maybe need to reset contexts *)
  1507. IF resetCtx THEN
  1508. mq.ResetContexts();
  1509. END;
  1510. RETURN ok;
  1511. END MagRefPass;
  1512. (*
  1513. This procedure applies the magnitude refinement pass to the compressed image data,
  1514. reading directly from the stream
  1515. *)
  1516. PROCEDURE RawMagRefPass (cblk : DataBlk; cblkInfo : J2KU.CblkInfo; curBp : LONGINT; term : BOOLEAN) : BOOLEAN;
  1517. VAR
  1518. i, j : LONGINT;
  1519. stripeHeight : LONGINT;
  1520. dataIdx, stateIdx : LONGINT;
  1521. curState : SET;
  1522. rowStartState, rowWidthState, rowStartData : LONGINT;
  1523. stateStripeIncr, dataStripeIncr : LONGINT;
  1524. bit : LONGINT;
  1525. tmpDataSample : SET;
  1526. setMask, resetMask : SET;
  1527. ok : BOOLEAN;
  1528. data : J2KU.LongIntArrayPtr;
  1529. scanw : LONGINT; (* The scan width of the code-block data *)
  1530. off_ul, off_ur, off_dl, off_dr : LONGINT;
  1531. BEGIN
  1532. (* Get local reference to data *)
  1533. data := cblk(DataBlkInt).data;
  1534. setMask := SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), curBp - 1));
  1535. resetMask := SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, -1), curBp + 1));
  1536. rowWidthState := cblkInfo.width + 2 * ENTROPY_ARRAYOFF;
  1537. (* Cache rowStart (of the extended arrays) *)
  1538. rowStartState := rowWidthState + ENTROPY_ARRAYOFF;
  1539. scanw := cblk.scanw;
  1540. rowStartData := cblk.offset;
  1541. stateStripeIncr := (ENTROPY_STRIPE_HEIGHT DIV 2)*rowWidthState;
  1542. dataStripeIncr := ENTROPY_STRIPE_HEIGHT*scanw;
  1543. (* Offsets for diagonal neighbors *)
  1544. off_ul := -rowWidthState - 1; (* Up left *)
  1545. off_ur := -rowWidthState + 1; (* Up right *)
  1546. off_dl := rowWidthState - 1; (* Down left *)
  1547. off_dr := rowWidthState + 1; (* Down right *)
  1548. i := 0;
  1549. (* Loop on rows *)
  1550. WHILE i < cblkInfo.height DO
  1551. (* We have to check if there are enough rows to scan an entire stripe or just a truncated one *)
  1552. IF ENTROPY_STRIPE_HEIGHT > (cblkInfo.height - i) THEN
  1553. stripeHeight := cblkInfo.height - i;
  1554. ELSE
  1555. stripeHeight := ENTROPY_STRIPE_HEIGHT;
  1556. END;
  1557. FOR j := 0 TO cblkInfo.width - 1 DO
  1558. stateIdx := rowStartState + j;
  1559. dataIdx := rowStartData + j;
  1560. curState := state[stateIdx];
  1561. (* Scan 1st row *)
  1562. IF (curState * STATE_SIG_R1 = STATE_SIG_R1)
  1563. & (curState * STATE_VISITED_R1 = {})
  1564. THEN
  1565. bit := dbr.NextBit();
  1566. tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
  1567. data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, LSH(bit, curBp)) + setMask);
  1568. (* No need to set IN_MAG_REF since all magnitude refinement passes to follow are "raw" *)
  1569. END;
  1570. (* Scan 2nd row *)
  1571. INC(dataIdx, scanw);
  1572. IF (stripeHeight > 1)
  1573. & (curState * STATE_SIG_R2 = STATE_SIG_R2)
  1574. & (curState * STATE_VISITED_R2 = {})
  1575. THEN
  1576. bit := dbr.NextBit();
  1577. tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
  1578. data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, LSH(bit, curBp)) + setMask);
  1579. (* No need to set IN_MAG_REF since all magnitude refinement passes to follow are "raw" *)
  1580. END;
  1581. (* Scan 3rd row *)
  1582. INC(stateIdx, rowWidthState);
  1583. INC(dataIdx, scanw);
  1584. curState := state[stateIdx];
  1585. IF (stripeHeight > 2)
  1586. & (curState * STATE_SIG_R1 = STATE_SIG_R1)
  1587. & (curState * STATE_VISITED_R1 = {})
  1588. THEN
  1589. bit := dbr.NextBit();
  1590. tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
  1591. data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, LSH(bit, curBp)) + setMask);
  1592. (* No need to set IN_MAG_REF since all magnitude refinement passes to follow are "raw" *)
  1593. END;
  1594. (* Scan 4th row *)
  1595. INC(dataIdx, scanw);
  1596. IF (stripeHeight > 3)
  1597. & (curState * STATE_SIG_R2 = STATE_SIG_R2)
  1598. & (curState * STATE_VISITED_R2 = {})
  1599. THEN
  1600. bit := dbr.NextBit();
  1601. tmpDataSample := SYSTEM.VAL(SET, data[dataIdx]) * resetMask;
  1602. data[dataIdx] := SYSTEM.VAL(LONGINT, tmpDataSample + SYSTEM.VAL(SET, LSH(bit, curBp)) + setMask);
  1603. END;
  1604. END;
  1605. (* Move to next row of stripes *)
  1606. INC(i, ENTROPY_STRIPE_HEIGHT);
  1607. (* Compute row start of next row *)
  1608. rowStartState := rowStartState + stateStripeIncr;
  1609. rowStartData := rowStartData + dataStripeIncr;
  1610. END;
  1611. (* Try to detect error *)
  1612. IF term THEN
  1613. ok := dbr.CheckBytePadding();
  1614. ELSE
  1615. ok := TRUE;
  1616. END;
  1617. RETURN ok;
  1618. END RawMagRefPass;
  1619. (* This procedure applies the cleanup pass to the compressed image data *)
  1620. PROCEDURE CleanupPass (cblk : DataBlk; cblkInfo : J2KU.CblkInfo; curBp : LONGINT; zeroLUT : J2KU.LongIntArrayPtr; term : BOOLEAN) : BOOLEAN;
  1621. VAR
  1622. sign, symbol : LONGINT; (* The symbol returned by the MQ-decoder *)
  1623. dataIdx, stateIdx, tmpDataIdx, tmpStateIdx : LONGINT;
  1624. stripeStartIdx : LONGINT;
  1625. curState, tmpCurState : SET;
  1626. rowStartState, rowWidthState, rowStartData : LONGINT;
  1627. stateStripeIncr, dataStripeIncr : LONGINT;
  1628. stripeHeight : LONGINT;
  1629. i, j : LONGINT;
  1630. ctx : LONGINT;
  1631. setMask : SET;
  1632. ok : BOOLEAN;
  1633. data : J2KU.LongIntArrayPtr;
  1634. scanw : LONGINT; (* The scan width of the code-block data *)
  1635. off_ul, off_ur, off_dl, off_dr : LONGINT;
  1636. BEGIN
  1637. (* Get local reference to data *)
  1638. data := cblk(DataBlkInt).data;
  1639. setMask := SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 3), curBp - 1));
  1640. rowWidthState := cblkInfo.width + 2 * ENTROPY_ARRAYOFF;
  1641. (* Cache row start *)
  1642. rowStartState := rowWidthState + ENTROPY_ARRAYOFF;
  1643. scanw := cblk.scanw;
  1644. rowStartData := cblk.offset;
  1645. stateStripeIncr := (ENTROPY_STRIPE_HEIGHT DIV 2)*rowWidthState;
  1646. dataStripeIncr := ENTROPY_STRIPE_HEIGHT*scanw;
  1647. (* Offsets for diagonal neighbors *)
  1648. off_ul := -rowWidthState - 1; (* Up left *)
  1649. off_ur := -rowWidthState + 1; (* Up right *)
  1650. off_dl := rowWidthState - 1; (* Down left *)
  1651. off_dr := rowWidthState + 1; (* Down right *)
  1652. i := 0;
  1653. (* Loop on rows *)
  1654. WHILE i < cblkInfo.height DO
  1655. (* We have to check if there are enough rows to scan an entire stripe or just a truncated one *)
  1656. IF ENTROPY_STRIPE_HEIGHT > (cblkInfo.height - i) THEN
  1657. stripeHeight := cblkInfo.height - i;
  1658. ELSE
  1659. stripeHeight := ENTROPY_STRIPE_HEIGHT;
  1660. END;
  1661. FOR j := 0 TO cblkInfo.width - 1 DO
  1662. stateIdx := rowStartState + j;
  1663. dataIdx := rowStartData + j;
  1664. curState := state[stateIdx];
  1665. (*
  1666. Check for RLC: if all samples are not significant, not visited and do have
  1667. a zero context, and colum is full height, we do RLC
  1668. *)
  1669. IF (stripeHeight = ENTROPY_STRIPE_HEIGHT)
  1670. & ((curState = {}) & (state[stateIdx + rowWidthState] = {}))
  1671. THEN
  1672. IF mq.Decode(ENTROPY_RUNCTX) = 1 THEN
  1673. (* Not all four bits of the coefficients of this stripe are 0 *)
  1674. (* Determine first non-zero coefficient bit *)
  1675. stripeStartIdx := mq.Decode(ENTROPY_UNICTX);
  1676. stripeStartIdx := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(stripeStartIdx, 1)) + SYSTEM.VAL(SET, mq.Decode(ENTROPY_UNICTX)));
  1677. (* Handle the first non-zero coefficient separately *)
  1678. IF stripeStartIdx > 1 THEN
  1679. tmpStateIdx := stateIdx + rowWidthState;
  1680. ELSE
  1681. tmpStateIdx := stateIdx;
  1682. END;
  1683. tmpDataIdx := dataIdx + scanw*stripeStartIdx;
  1684. tmpCurState := state[tmpStateIdx];
  1685. (* See if the first non-zero coefficient is in top or bottom part of stripe *)
  1686. IF ~ODD(stripeStartIdx) THEN
  1687. (* Coefficient has become significant -> decode sign bit *)
  1688. ctx := ENTROPY_SIGN_LUT[LSH(SYSTEM.VAL(LONGINT, tmpCurState*SIGN_VECT_MASK_R1), -SIGN_VECT_SHIFT_R1)];
  1689. sign := SYSTEM.VAL(LONGINT,
  1690. SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
  1691. / SYSTEM.VAL(SET, LSH(ctx, -J2KU.LONGINT_BITS + 1))
  1692. );
  1693. data[tmpDataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
  1694. (* Update state information*)
  1695. IF (stripeStartIdx # 0) OR ~vertCausal THEN
  1696. (* Upper diagonal neighbors *)
  1697. (* Only update previous stripe if not in vertical causal mode *)
  1698. state[tmpStateIdx + off_ul] := state[tmpStateIdx + off_ul] + STATE_D_DR_R2;
  1699. state[tmpStateIdx + off_ur] := state[tmpStateIdx + off_ur] + STATE_D_DL_R2;
  1700. END;
  1701. (* Update rest of neighbors, depending on sign *)
  1702. IF sign # 0 THEN
  1703. tmpCurState := tmpCurState
  1704. + STATE_SIG_R1
  1705. + STATE_V_U_R2 + STATE_V_U_SIGN_R2;
  1706. IF (stripeStartIdx # 0) OR ~vertCausal THEN
  1707. (* Only update previous stripe if not in vertical causal mode *)
  1708. state [tmpStateIdx - rowWidthState] := state[tmpStateIdx - rowWidthState]
  1709. + STATE_V_D_R2
  1710. + STATE_V_D_SIGN_R2;
  1711. END;
  1712. state [tmpStateIdx - 1] := state[tmpStateIdx - 1]
  1713. + STATE_H_R_R1
  1714. + STATE_H_R_SIGN_R1
  1715. + STATE_D_UR_R2;
  1716. state [tmpStateIdx + 1] := state[tmpStateIdx + 1]
  1717. + STATE_H_L_R1
  1718. + STATE_H_L_SIGN_R1
  1719. + STATE_D_UL_R2;
  1720. ELSE
  1721. tmpCurState := tmpCurState
  1722. + STATE_SIG_R1
  1723. + STATE_V_U_R2;
  1724. IF (stripeStartIdx # 0) OR ~vertCausal THEN
  1725. (* Only update previous stripe if not in vertical causal mode *)
  1726. state [tmpStateIdx - rowWidthState] := state[tmpStateIdx - rowWidthState]
  1727. + STATE_V_D_R2;
  1728. END;
  1729. state [tmpStateIdx - 1] := state[tmpStateIdx - 1]
  1730. + STATE_H_R_R1
  1731. + STATE_D_UR_R2;
  1732. state [tmpStateIdx + 1] := state[tmpStateIdx + 1]
  1733. + STATE_H_L_R1
  1734. + STATE_D_UL_R2;
  1735. END;
  1736. ELSE
  1737. (* Coefficient has become significant -> decode sign bit *)
  1738. ctx := ENTROPY_SIGN_LUT[LSH(SYSTEM.VAL(LONGINT, tmpCurState*SIGN_VECT_MASK_R2), -SIGN_VECT_SHIFT_R2)];
  1739. sign := SYSTEM.VAL(LONGINT,
  1740. SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
  1741. / SYSTEM.VAL(SET, LSH(ctx, -J2KU.LONGINT_BITS + 1))
  1742. );
  1743. data[tmpDataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
  1744. (* Update state information*)
  1745. (* Lower diagonal neighbors *)
  1746. state[tmpStateIdx + off_dl] := state[tmpStateIdx + off_dl] + STATE_D_UR_R1;
  1747. state[tmpStateIdx + off_dr] := state[tmpStateIdx + off_dr] + STATE_D_UL_R1;
  1748. (* Update rest of neighbors, depending on sign *)
  1749. IF sign # 0 THEN
  1750. tmpCurState := tmpCurState
  1751. + STATE_SIG_R2
  1752. + STATE_V_D_R1 + STATE_V_D_SIGN_R1;
  1753. state[tmpStateIdx + rowWidthState] := state[tmpStateIdx + rowWidthState]
  1754. + STATE_V_U_R1
  1755. + STATE_V_U_SIGN_R1;
  1756. state[tmpStateIdx - 1] := state[tmpStateIdx - 1]
  1757. + STATE_H_R_R2
  1758. + STATE_H_R_SIGN_R2
  1759. + STATE_D_DR_R1;
  1760. state[tmpStateIdx + 1] := state[tmpStateIdx + 1]
  1761. + STATE_H_L_R2
  1762. + STATE_H_L_SIGN_R2
  1763. + STATE_D_DL_R1;
  1764. ELSE
  1765. tmpCurState := tmpCurState
  1766. + STATE_SIG_R2
  1767. + STATE_V_D_R1;
  1768. state[tmpStateIdx + rowWidthState] := state[tmpStateIdx + rowWidthState]
  1769. + STATE_V_U_R1;
  1770. state[tmpStateIdx - 1] := state[tmpStateIdx - 1]
  1771. + STATE_H_R_R2
  1772. + STATE_D_DR_R1;
  1773. state [tmpStateIdx + 1] := state[tmpStateIdx + 1]
  1774. + STATE_H_L_R2
  1775. + STATE_D_DL_R1;
  1776. END;
  1777. END;
  1778. (* Save state *)
  1779. state[tmpStateIdx] := tmpCurState;
  1780. ELSE
  1781. (* Ensure that we skip all coefficients *)
  1782. stripeStartIdx := ENTROPY_STRIPE_HEIGHT;
  1783. END;
  1784. ELSE
  1785. stripeStartIdx := -1;
  1786. END;
  1787. (* Scan 1st row *)
  1788. curState := state[stateIdx];
  1789. IF (stripeStartIdx < 0)
  1790. & (curState * STATE_SIG_R1 = {})
  1791. & (curState * STATE_VISITED_R1 = {})
  1792. THEN
  1793. (* Did the coefficient just become significant? If not, move on *)
  1794. IF mq.Decode(zeroLUT[SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R1)]) = 1 THEN
  1795. (* Coefficient has become significant -> decode sign bit *)
  1796. ctx := ENTROPY_SIGN_LUT[LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R1), -SIGN_VECT_SHIFT_R1)];
  1797. sign := SYSTEM.VAL(LONGINT,
  1798. SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
  1799. / SYSTEM.VAL(SET, LSH(ctx, -J2KU.LONGINT_BITS + 1))
  1800. );
  1801. data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
  1802. (* Update state information*)
  1803. IF ~vertCausal THEN
  1804. (* Upper diagonal neighbors *)
  1805. (* Only update previous stripe if not in vertical causal mode *)
  1806. state[stateIdx + off_ul] := state[stateIdx + off_ul] + STATE_D_DR_R2;
  1807. state[stateIdx + off_ur] := state[stateIdx + off_ur] + STATE_D_DL_R2;
  1808. END;
  1809. (* Update rest of neighbors, depending on sign *)
  1810. IF sign # 0 THEN
  1811. curState := curState
  1812. + STATE_SIG_R1
  1813. + STATE_V_U_R2 + STATE_V_U_SIGN_R2;
  1814. IF ~vertCausal THEN
  1815. (* Only update previous stripe if not in vertical causal mode *)
  1816. state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
  1817. + STATE_V_D_R2
  1818. + STATE_V_D_SIGN_R2;
  1819. END;
  1820. state [stateIdx - 1] := state[stateIdx - 1]
  1821. + STATE_H_R_R1
  1822. + STATE_H_R_SIGN_R1
  1823. + STATE_D_UR_R2;
  1824. state [stateIdx + 1] := state[stateIdx + 1]
  1825. + STATE_H_L_R1
  1826. + STATE_H_L_SIGN_R1
  1827. + STATE_D_UL_R2;
  1828. ELSE
  1829. curState := curState
  1830. + STATE_SIG_R1
  1831. + STATE_V_U_R2;
  1832. IF ~vertCausal THEN
  1833. (* Only update previous stripe if not in vertical causal mode *)
  1834. state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
  1835. + STATE_V_D_R2;
  1836. END;
  1837. state [stateIdx - 1] := state[stateIdx - 1]
  1838. + STATE_H_R_R1
  1839. + STATE_D_UR_R2;
  1840. state [stateIdx + 1] := state[stateIdx + 1]
  1841. + STATE_H_L_R1
  1842. + STATE_D_UL_R2;
  1843. END;
  1844. END;
  1845. END;
  1846. (* Scan 2nd row *)
  1847. INC(dataIdx, scanw);
  1848. IF (stripeStartIdx < 1)
  1849. & (stripeHeight > 1)
  1850. & (curState * STATE_SIG_R2 = {})
  1851. & (curState * STATE_VISITED_R2 = {})
  1852. THEN
  1853. (* Did the coefficient just become significant? If not, move on *)
  1854. IF mq.Decode(zeroLUT[LSH(SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R2), -STATE_SEP)]) = 1 THEN
  1855. (* Coefficient has become significant -> decode sign bit *)
  1856. ctx := ENTROPY_SIGN_LUT[LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R2), -SIGN_VECT_SHIFT_R2)];
  1857. sign := SYSTEM.VAL(LONGINT,
  1858. SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
  1859. / SYSTEM.VAL(SET, LSH(ctx, -J2KU.LONGINT_BITS + 1))
  1860. );
  1861. data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
  1862. (* Update state information*)
  1863. (* Lower diagonal neighbors *)
  1864. state[stateIdx + off_dl] := state[stateIdx + off_dl] + STATE_D_UR_R1;
  1865. state[stateIdx + off_dr] := state[stateIdx + off_dr] + STATE_D_UL_R1;
  1866. (* Update rest of neighbors, depending on sign *)
  1867. IF sign # 0 THEN
  1868. curState := curState
  1869. + STATE_SIG_R2
  1870. + STATE_V_D_R1 + STATE_V_D_SIGN_R1;
  1871. state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
  1872. + STATE_V_U_R1
  1873. + STATE_V_U_SIGN_R1;
  1874. state[stateIdx - 1] := state[stateIdx - 1]
  1875. + STATE_H_R_R2
  1876. + STATE_H_R_SIGN_R2
  1877. + STATE_D_DR_R1;
  1878. state[stateIdx + 1] := state[stateIdx + 1]
  1879. + STATE_H_L_R2
  1880. + STATE_H_L_SIGN_R2
  1881. + STATE_D_DL_R1;
  1882. ELSE
  1883. curState := curState
  1884. + STATE_SIG_R2
  1885. + STATE_V_D_R1;
  1886. state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
  1887. + STATE_V_U_R1;
  1888. state[stateIdx - 1] := state[stateIdx - 1]
  1889. + STATE_H_R_R2
  1890. + STATE_D_DR_R1;
  1891. state [stateIdx + 1] := state[stateIdx + 1]
  1892. + STATE_H_L_R2
  1893. + STATE_D_DL_R1;
  1894. END;
  1895. END;
  1896. END;
  1897. (* Set coefficients back to not visited *)
  1898. state[stateIdx] := curState * SET (-(STATE_VISITED_R1 + STATE_VISITED_R2));
  1899. (* Scan 3rd row *)
  1900. INC(stateIdx, rowWidthState);
  1901. INC(dataIdx, scanw);
  1902. curState := state[stateIdx];
  1903. IF (stripeStartIdx < 2)
  1904. & (stripeHeight > 2)
  1905. & (curState * STATE_SIG_R1 = {})
  1906. & (curState * STATE_VISITED_R1 = {})
  1907. THEN
  1908. (* Did the coefficient just become significant? If not, move on *)
  1909. IF mq.Decode(zeroLUT[SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R1)]) = 1 THEN
  1910. (* Coefficient has become significant -> decode sign bit *)
  1911. ctx := ENTROPY_SIGN_LUT[LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R1), -SIGN_VECT_SHIFT_R1)];
  1912. sign := SYSTEM.VAL(LONGINT,
  1913. SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
  1914. / SYSTEM.VAL(SET, LSH(ctx, -J2KU.LONGINT_BITS + 1))
  1915. );
  1916. data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
  1917. (* Update state information*)
  1918. (* Upper diagonal neighbors *)
  1919. state[stateIdx + off_ul] := state[stateIdx + off_ul] + STATE_D_DR_R2;
  1920. state[stateIdx + off_ur] := state[stateIdx + off_ur] + STATE_D_DL_R2;
  1921. (* Update rest of neighbors, depending on sign *)
  1922. IF sign # 0 THEN
  1923. curState := curState
  1924. + STATE_SIG_R1
  1925. + STATE_V_U_R2 + STATE_V_U_SIGN_R2;
  1926. state[stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
  1927. + STATE_V_D_R2
  1928. + STATE_V_D_SIGN_R2;
  1929. state[stateIdx - 1] := state[stateIdx - 1]
  1930. + STATE_H_R_R1
  1931. + STATE_H_R_SIGN_R1
  1932. + STATE_D_UR_R2;
  1933. state[stateIdx + 1] := state[stateIdx + 1]
  1934. + STATE_H_L_R1
  1935. + STATE_H_L_SIGN_R1
  1936. + STATE_D_UL_R2;
  1937. ELSE
  1938. curState := curState
  1939. + STATE_SIG_R1
  1940. + STATE_V_U_R2;
  1941. state [stateIdx - rowWidthState] := state[stateIdx - rowWidthState]
  1942. + STATE_V_D_R2;
  1943. state[stateIdx - 1] := state[stateIdx - 1]
  1944. + STATE_H_R_R1
  1945. + STATE_D_UR_R2;
  1946. state[stateIdx + 1] := state[stateIdx + 1]
  1947. + STATE_H_L_R1
  1948. + STATE_D_UL_R2;
  1949. END;
  1950. END;
  1951. END;
  1952. (* Scan 4th row *)
  1953. INC(dataIdx, scanw);
  1954. IF (stripeStartIdx < 3)
  1955. & (stripeHeight > 3)
  1956. & (curState * STATE_SIG_R2 = {})
  1957. & (curState * STATE_VISITED_R2 = {})
  1958. THEN
  1959. (* Did the coefficient just become significant? If not, move on *)
  1960. IF mq.Decode(zeroLUT[LSH(SYSTEM.VAL(LONGINT, curState * STATE_VECT_MASK_R2), -STATE_SEP)]) = 1 THEN
  1961. (* Coefficient has become significant -> decode sign bit *)
  1962. ctx := ENTROPY_SIGN_LUT[LSH(SYSTEM.VAL(LONGINT, curState*SIGN_VECT_MASK_R2), -SIGN_VECT_SHIFT_R2)];
  1963. sign := SYSTEM.VAL(LONGINT,
  1964. SYSTEM.VAL(SET, mq.Decode(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ctx) * SIGN_LUT_MASK)))
  1965. / SYSTEM.VAL(SET, LSH(ctx, -J2KU.LONGINT_BITS + 1))
  1966. );
  1967. data[dataIdx] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(sign, J2KU.LONGINT_BITS - 1)) + setMask);
  1968. (* Update state information*)
  1969. (* Lower diagonal neighbors *)
  1970. state[stateIdx + off_dl] := state[stateIdx + off_dl] + STATE_D_UR_R1;
  1971. state[stateIdx + off_dr] := state[stateIdx + off_dr] + STATE_D_UL_R1;
  1972. (* Update rest of neighbors, depending on sign *)
  1973. IF sign # 0 THEN
  1974. curState := curState
  1975. + STATE_SIG_R2
  1976. + STATE_V_D_R1 + STATE_V_D_SIGN_R1;
  1977. state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
  1978. + STATE_V_U_R1
  1979. + STATE_V_U_SIGN_R1;
  1980. state[stateIdx - 1] := state[stateIdx - 1]
  1981. + STATE_H_R_R2
  1982. + STATE_H_R_SIGN_R2
  1983. + STATE_D_DR_R1;
  1984. state[stateIdx + 1] := state[stateIdx + 1]
  1985. + STATE_H_L_R2
  1986. + STATE_H_L_SIGN_R2
  1987. + STATE_D_DL_R1;
  1988. ELSE
  1989. curState := curState
  1990. + STATE_SIG_R2
  1991. + STATE_V_D_R1;
  1992. state[stateIdx + rowWidthState] := state[stateIdx + rowWidthState]
  1993. + STATE_V_U_R1;
  1994. state[stateIdx - 1] := state[stateIdx - 1]
  1995. + STATE_H_R_R2
  1996. + STATE_D_DR_R1;
  1997. state [stateIdx + 1] := state[stateIdx + 1]
  1998. + STATE_H_L_R2
  1999. + STATE_D_DL_R1;
  2000. END;
  2001. state[stateIdx] := curState;
  2002. END;
  2003. END;
  2004. (* Set coefficients back to not visited *)
  2005. state[stateIdx] := curState * SET(-(STATE_VISITED_R1 + STATE_VISITED_R2));
  2006. END;
  2007. (* Move to next row of stripes *)
  2008. INC(i, ENTROPY_STRIPE_HEIGHT);
  2009. (* Compute row start of next row *)
  2010. rowStartState := rowStartState + stateStripeIncr;
  2011. rowStartData := rowStartData + dataStripeIncr;
  2012. END;
  2013. (* Check if segmentation symbols are used *)
  2014. IF segUsed THEN
  2015. (* Assemble 4 bits *)
  2016. symbol := SYSTEM.VAL(LONGINT,
  2017. SYSTEM.VAL(SET, LSH(mq.Decode(ENTROPY_UNICTX), 3))
  2018. + SYSTEM.VAL(SET, LSH(mq.Decode(ENTROPY_UNICTX), 2))
  2019. + SYSTEM.VAL(SET, LSH(mq.Decode(ENTROPY_UNICTX), 1))
  2020. + SYSTEM.VAL(SET, mq.Decode(ENTROPY_UNICTX))
  2021. );
  2022. (* The segmentation symbol is 1010 (or 0xA) *)
  2023. IF symbol # ENTROPY_SEG_MARKER THEN
  2024. RETURN FALSE;
  2025. END;
  2026. END;
  2027. (* We may do an error check if predictable termination is used *)
  2028. IF predTerm & term THEN
  2029. ok := mq.CheckPredTerm();
  2030. ELSE
  2031. ok := TRUE;
  2032. END;
  2033. (* Maybe need to reset contexts *)
  2034. IF resetCtx THEN
  2035. mq.ResetContexts();
  2036. END;
  2037. RETURN ok;
  2038. END CleanupPass;
  2039. (* Conceals a detected error *)
  2040. PROCEDURE Conceal (dataBlk : DataBlk; cblkInfo : J2KU.CblkInfo; bp : LONGINT);
  2041. VAR
  2042. value, setmask, resetmask, mbmask, i, j, rowStart : LONGINT;
  2043. data : J2KU.LongIntArrayPtr;
  2044. scanw : LONGINT;
  2045. BEGIN
  2046. data := dataBlk(DataBlkInt).data;
  2047. scanw := dataBlk.scanw;
  2048. setmask := LSH(1, bp);
  2049. resetmask := LSH(-1, bp);
  2050. (* Mask to extract magnitude bits, without sign bit *)
  2051. mbmask := SYSTEM.VAL(LONGINT, J2KU.LONGINT_SIGN_BIT / SYSTEM.VAL(SET, resetmask));
  2052. (* We need to restore the state before the bit-plane where the error happened *)
  2053. (* Visit each sample and apply the reset mask to it and add a 1/2 approximation if significant *)
  2054. FOR i := 0 TO cblkInfo.height - 1 DO
  2055. rowStart := i*scanw;
  2056. FOR j := 0 TO cblkInfo.width - 1 DO
  2057. value := data[rowStart + j];
  2058. IF SYSTEM.VAL(SET, value) * SYSTEM.VAL(SET, mbmask) # {} THEN
  2059. (*
  2060. Something was decoded in previous bit-planes -> set the approximation
  2061. for the previous bit-plane
  2062. *)
  2063. data[rowStart + j] := SYSTEM.VAL(LONGINT,
  2064. (SYSTEM.VAL(SET, value)
  2065. * SYSTEM.VAL(SET, resetmask))
  2066. + SYSTEM.VAL(SET, setmask)
  2067. );
  2068. ELSE
  2069. (* Was insignificant in previous bit-plane -> set to 0 *)
  2070. data[rowStart + j] := 0;
  2071. END;
  2072. END;
  2073. END;
  2074. END Conceal;
  2075. PROCEDURE FreeNonRebuildResources;
  2076. BEGIN
  2077. cr.FreeNonRebuildResources();
  2078. END FreeNonRebuildResources;
  2079. PROCEDURE FreeResources;
  2080. BEGIN
  2081. state := NIL;
  2082. mq := NIL;
  2083. dbr := NIL;
  2084. cr.FreeResources();
  2085. END FreeResources;
  2086. END EntropyDecoder;
  2087. (* --- END Entropy decoder types --- *)
  2088. (* --- ROI types --- *)
  2089. ROIDescaler = OBJECT
  2090. VAR
  2091. decSpec : J2KCS.DecoderSpecs;
  2092. ed : EntropyDecoder;
  2093. noROI : BOOLEAN;
  2094. PROCEDURE &InitNew *(roiOpt : J2KU.ROIDescalerOptions;
  2095. ed : EntropyDecoder;
  2096. decSpec : J2KCS.DecoderSpecs);
  2097. BEGIN
  2098. ReInit(roiOpt, ed, decSpec);
  2099. END InitNew;
  2100. PROCEDURE ReInit ( roiOpt : J2KU.ROIDescalerOptions;
  2101. ed : EntropyDecoder;
  2102. decSpec : J2KCS.DecoderSpecs);
  2103. BEGIN
  2104. SELF.noROI := roiOpt.noROI;
  2105. SELF.decSpec := decSpec;
  2106. SELF.ed := ed;
  2107. END ReInit;
  2108. (*
  2109. If ROI decoding is needed, the de-scaled code-blocks are returned. Otherwise nothing is done
  2110. *)
  2111. PROCEDURE GetCodeBlocks (VAR cblk : ARRAY OF DataBlk; VAR cblkInfo : ARRAY OF J2KU.CblkInfo; ncblks : LONGINT) : LONGINT;
  2112. VAR
  2113. cblkIdx, ncblksRet : LONGINT;
  2114. data : J2KU.LongIntArrayPtr;
  2115. curTile, comp, magBits, idx, i, j : LONGINT;
  2116. (*
  2117. First mask needed to extract all magnitude bits in the range of maximum magnitude bits as defined in equation E.2 of the standard.
  2118. Second mask needed to extract magnitude bits beyond the range of maximum magnitude bits.
  2119. Third mask is the inverse of the second one. It's kind of the same as the first mask, except that we also extract the sign bit.
  2120. *)
  2121. mask1, mask2, mask3 : SET;
  2122. approx : SET; (* Mask to set the 1/2 approximation bit, if it gets deleted during truncation *)
  2123. tmp : SET;
  2124. shift : LONGINT;
  2125. width, height, scanw : LONGINT;
  2126. BEGIN
  2127. (* Get as many coded code-blocks in the stream as needed, descale them *)
  2128. ncblksRet := ed.GetCodeBlocks(cblk, cblkInfo, ncblks);
  2129. curTile := ed.CurrentTile();
  2130. FOR cblkIdx := 0 TO ncblksRet - 1 DO
  2131. comp := cblkInfo[cblkIdx].subbinfo.component;
  2132. (* If there is no ROI present then don't do anything *)
  2133. IF ~noROI & decSpec.ROIUsed(curTile, comp) THEN
  2134. data := cblk[cblkIdx](DataBlkInt).data;
  2135. idx := cblk[cblkIdx].offset;
  2136. scanw := cblk[cblkIdx].scanw;
  2137. width := cblkInfo[cblkIdx].width;
  2138. height := cblkInfo[cblkIdx].height;
  2139. shift := decSpec.GetROIShift(curTile, comp);
  2140. magBits := cblkInfo[cblkIdx].subbinfo.magbits;
  2141. mask3 := SYSTEM.VAL(SET, LSH(J2KU.SWAP_MASK, (J2KU.LONGINT_BITS - 1)- magBits));
  2142. mask2 := -mask3;
  2143. mask1 := mask3 * SET(-J2KU.LONGINT_SIGN_BIT);
  2144. approx := SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 1), (J2KU.LONGINT_BITS - 2) - magBits));
  2145. (* For every coefficient see if it belongs to the background or a ROI *)
  2146. FOR i := 0 TO height - 1 DO
  2147. FOR j := 0 TO width - 1 DO
  2148. tmp := SYSTEM.VAL(SET, data[idx]);
  2149. IF (tmp * mask1) = {} THEN
  2150. (* Background coefficients: All first MSBs are 0 *)
  2151. (* Need to shift the coefficient *)
  2152. data[idx] := SYSTEM.VAL(LONGINT,
  2153. (tmp * J2KU.LONGINT_SIGN_BIT) (* extract sign *)
  2154. + SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, tmp), shift)));
  2155. ELSIF (tmp * mask2) # {} THEN
  2156. (* The number of decoded magnitude bits is greater than the maximum number of magnitude bits -> need to truncate & set approximation bit *)
  2157. data[idx] := SYSTEM.VAL(LONGINT, (tmp * mask3) + approx);
  2158. END;
  2159. INC(idx);
  2160. END;
  2161. idx := idx - width + scanw;
  2162. END;
  2163. END;
  2164. END;
  2165. RETURN ncblksRet;
  2166. END GetCodeBlocks;
  2167. (**
  2168. Sets the maximum layer range for which data shall be delivered
  2169. and decoded, i.e. data outside this range shall NEVER be requested.
  2170. This procedure shall NOT be called after the first code-block data
  2171. has been read.
  2172. maxStartLayer and maxEndLayer are inclusive.
  2173. *)
  2174. PROCEDURE SetMaxLayerRange (maxStartLayer, maxEndLayer : LONGINT);
  2175. BEGIN
  2176. ed.SetMaxLayerRange(maxStartLayer, maxEndLayer);
  2177. END SetMaxLayerRange;
  2178. (**
  2179. Sets the layer range for which data shall be delivered
  2180. and decoded.
  2181. startLayer and endLayer are inclusive.
  2182. *)
  2183. PROCEDURE SetLayerRange (startLayer, endLayer : LONGINT);
  2184. BEGIN
  2185. ed.SetLayerRange(startLayer, endLayer);
  2186. END SetLayerRange;
  2187. (**
  2188. Gets the layer range for which data shall be delivered
  2189. and decoded.
  2190. startLayer and endLayer are inclusive.
  2191. *)
  2192. PROCEDURE GetLayerRange (VAR startLayer, endLayer : LONGINT);
  2193. BEGIN
  2194. ed.GetLayerRange(startLayer, endLayer);
  2195. END GetLayerRange;
  2196. (**
  2197. Sets the maximum decomposition level range for which data shall be delivered
  2198. and decoded, i.e. data outside this range shall NEVER be requested. This procedure
  2199. shall NOT be called after the first code-block data has been read.
  2200. maxStartDecLvl : The decompositon level to start at (inclusive) -> upper bound
  2201. maxEndDecLvl : The decomposition level to end at (inclusive) -> lower bound
  2202. *)
  2203. PROCEDURE SetMaxDecLevelRange (maxStartDecLvl, maxEndDecLvl : LONGINT);
  2204. BEGIN
  2205. ed.SetMaxDecLevelRange(maxStartDecLvl, maxEndDecLvl);
  2206. END SetMaxDecLevelRange;
  2207. (**
  2208. Sets the decomposition level range for which data shall be delivered
  2209. and decoded.
  2210. startDecLvl : The decompositon level to start at (inclusive) -> upper bound
  2211. endDecLvl : The decomposition level to end at (inclusive) -> lower bound
  2212. *)
  2213. PROCEDURE SetDecLevelRange (startDecLvl, endDecLvl : LONGINT);
  2214. BEGIN
  2215. ed.SetDecLevelRange(startDecLvl, endDecLvl);
  2216. END SetDecLevelRange;
  2217. (**
  2218. Gets the decomposition level range for which data shall be delivered
  2219. and decoded.
  2220. startDecLvl : The decompositon level to start at (inclusive) -> upper bound
  2221. endDecLvl : The decomposition level to end at (inclusive) -> lower bound
  2222. *)
  2223. PROCEDURE GetDecLevelRange (VAR startDec, endDec : LONGINT);
  2224. BEGIN
  2225. ed.GetDecLevelRange(startDec, endDec);
  2226. END GetDecLevelRange;
  2227. PROCEDURE SetReBuildMode;
  2228. BEGIN
  2229. ed.SetReBuildMode();
  2230. END SetReBuildMode;
  2231. PROCEDURE CurrentTile () : LONGINT;
  2232. BEGIN
  2233. RETURN ed.CurrentTile();
  2234. END CurrentTile;
  2235. PROCEDURE CurrentTilePart () : LONGINT;
  2236. BEGIN
  2237. RETURN ed.CurrentTilePart();
  2238. END CurrentTilePart;
  2239. PROCEDURE NextTilePart () : BOOLEAN;
  2240. BEGIN
  2241. RETURN ed.NextTilePart();
  2242. END NextTilePart;
  2243. PROCEDURE DataAvailable () : BOOLEAN;
  2244. BEGIN
  2245. RETURN ed.DataAvailable();
  2246. END DataAvailable;
  2247. PROCEDURE GetSubbandInfo (tile, component, reslevel, subband : LONGINT) : J2KU.SubbandInfo;
  2248. BEGIN
  2249. RETURN ed.GetSubbandInfo(tile, component, reslevel, subband)
  2250. END GetSubbandInfo;
  2251. PROCEDURE TilePartAvailable () : BOOLEAN;
  2252. BEGIN
  2253. RETURN ed.TilePartAvailable();
  2254. END TilePartAvailable;
  2255. PROCEDURE AllTilePartsRead () : BOOLEAN;
  2256. BEGIN
  2257. RETURN ed.AllTilePartsRead();
  2258. END AllTilePartsRead;
  2259. PROCEDURE FreeNonRebuildResources;
  2260. BEGIN
  2261. ed.FreeNonRebuildResources();
  2262. END FreeNonRebuildResources;
  2263. PROCEDURE FreeResources;
  2264. BEGIN
  2265. ed.FreeResources();
  2266. END FreeResources;
  2267. END ROIDescaler;
  2268. (* --- ROI types --- *)
  2269. (* --- Dequantizer types --- *)
  2270. Dequantizer = OBJECT
  2271. VAR
  2272. roi : ROIDescaler; (* This will be the source for code-blocks *)
  2273. dataTypes : POINTER TO ARRAY OF ARRAY OF LONGINT;
  2274. decSpec : J2KCS.DecoderSpecs;
  2275. tBitDepth : J2KU.LongIntArrayPtr; (* The bit depths of the transformed components *)
  2276. (*
  2277. Pre-calculated step sizes used in irreversible quantization. The actual step size used is then
  2278. computed by multiplying the respective preStep value with 2^Rb, where Rb is the nominal
  2279. dynamic range for the respective subband.
  2280. 1st dim: tile index
  2281. 2nd dim: component
  2282. 3rd dim: resolution level
  2283. 4th dim: subband index
  2284. *)
  2285. (*
  2286. NOTE: We always allocate memory that won't be used, e.g. always values for 3 subbands,
  2287. or space for components for which no quantization is performed
  2288. *)
  2289. preStep : POINTER TO ARRAY OF POINTER TO ARRAY OF POINTER TO ARRAY OF ARRAY 3 OF REAL;
  2290. cblkBuf : ARRAY CBLK_BUFSIZE OF DataBlk;
  2291. overallMinDecLvl : LONGINT;(*
  2292. The overall minimum end decomposition level, i.e. there won't be any
  2293. delivered code-block which belongs to a lower dec. level.
  2294. *)
  2295. PROCEDURE &InitNew *(deqOpt : J2KU.DequantizerOptions;
  2296. roi : ROIDescaler;
  2297. decSpec : J2KCS.DecoderSpecs);
  2298. BEGIN
  2299. dataTypes := NIL;
  2300. tBitDepth := NIL;
  2301. preStep := NIL;
  2302. ReInit(deqOpt, roi, decSpec);
  2303. END InitNew;
  2304. PROCEDURE ReInit (deqOpt : J2KU.DequantizerOptions;
  2305. roi : ROIDescaler;
  2306. decSpec : J2KCS.DecoderSpecs);
  2307. VAR
  2308. ntiles, ncomp, i, j : LONGINT;
  2309. imgInfo : J2KCS.ImageInfo;
  2310. utBitDepth : J2KU.LongIntArrayPtr; (* The bit depths of the untransformed (i.e. original) components *)
  2311. cblkInt : DataBlkInt;
  2312. BEGIN
  2313. (* Get the relevant decoder option(s) *)
  2314. SELF.roi := roi;
  2315. (* Get number of tiles and components *)
  2316. SELF.decSpec := decSpec;
  2317. imgInfo := decSpec.GetImageInfo();
  2318. ntiles := imgInfo.GetNumTiles();
  2319. ncomp := imgInfo.GetNumComponents();
  2320. NEW(dataTypes, ntiles, ncomp);
  2321. (* Set default data type (LONGINT) *)
  2322. FOR j := 0 TO ntiles - 1 DO
  2323. Machine.Fill32(ADDRESSOF(dataTypes[j][0]), ncomp*SIZEOF(LONGINT), DATA_LONGINT);
  2324. END;
  2325. NEW(utBitDepth, ncomp);
  2326. FOR i := 0 TO ncomp - 1 DO
  2327. utBitDepth[i] := imgInfo.GetBitDepth(i);
  2328. END;
  2329. (* TODO: Compute the actual bit depths *)
  2330. tBitDepth := utBitDepth;
  2331. FOR i := 0 TO CBLK_BUFSIZE - 1 DO
  2332. NEW(cblkInt);
  2333. cblkBuf[i] := cblkInt;
  2334. END;
  2335. preStep := NIL;
  2336. (* By default we expect data for all decomposition levels *)
  2337. overallMinDecLvl := 0;
  2338. END ReInit;
  2339. PROCEDURE SetDataType (tile, component, type : LONGINT);
  2340. BEGIN
  2341. dataTypes[tile][component] := type;
  2342. END SetDataType;
  2343. PROCEDURE DataAvailable () : BOOLEAN;
  2344. BEGIN
  2345. RETURN roi.DataAvailable();
  2346. END DataAvailable;
  2347. PROCEDURE CurrentTile () : LONGINT;
  2348. BEGIN
  2349. RETURN roi.CurrentTile();
  2350. END CurrentTile;
  2351. PROCEDURE CurrentTilePart () : LONGINT;
  2352. BEGIN
  2353. RETURN roi.CurrentTilePart();
  2354. END CurrentTilePart;
  2355. PROCEDURE NextTilePart () : BOOLEAN;
  2356. BEGIN
  2357. IF ~roi.NextTilePart() THEN
  2358. RETURN FALSE;
  2359. END;
  2360. IF roi.CurrentTilePart() = 0 THEN
  2361. (* Need to pre-calculate step sizes *)
  2362. CalculateStepSizes(roi.CurrentTile());
  2363. END;
  2364. RETURN TRUE;
  2365. END NextTilePart;
  2366. (* Pre-calculates the quantization steps for all components of a tile *)
  2367. PROCEDURE CalculateStepSizes (tile : LONGINT);
  2368. CONST
  2369. (* The normalization factor for the manitssa (2^11, since 11 bits are used to represent the mantissa *)
  2370. NORM_FACT = LSH(SYSTEM.VAL(LONGINT, 1), 11);
  2371. VAR
  2372. ntiles, ncomp, i, ndec, r: LONGINT;
  2373. qStyle, exp : LONGINT;
  2374. mant : REAL;
  2375. imgInfo : J2KCS.ImageInfo;
  2376. BEGIN
  2377. imgInfo := decSpec.GetImageInfo();
  2378. ntiles := imgInfo.GetNumTiles();
  2379. ncomp := imgInfo.GetNumComponents();
  2380. (* Loop over components *)
  2381. FOR i := 0 TO ncomp - 1 DO
  2382. (* We need to calculate the stepsizes based on the quantization type *)
  2383. qStyle := decSpec.GetQuantStyle(tile, i);
  2384. CASE qStyle OF
  2385. | J2KCS.NOQUANT:
  2386. (* EMPTY; no exponent and mantissa provided; step size is always 1 *)
  2387. | J2KCS.QUANT_EXP:
  2388. (* For every resolution level and subband we have a separate value *)
  2389. IF preStep = NIL THEN
  2390. NEW(preStep, ntiles);
  2391. END;
  2392. IF preStep[tile] = NIL THEN
  2393. NEW(preStep[tile], ncomp);
  2394. END;
  2395. ndec := decSpec.GetNumDecLevels(tile, i);
  2396. (*
  2397. Subract maximum end decomposition level from number of decomposition levels.
  2398. This will give us the actual maximum number of decomposition level from the
  2399. minimum to the end.
  2400. NOTE: We then allocate from the minimum, NOT from the maximum start
  2401. decomposition level that was specified by calling SetMaxDecLevelRange.
  2402. *)
  2403. DEC(ndec, overallMinDecLvl);
  2404. NEW(preStep[tile][i], ndec + 1);
  2405. (* Resolution level 0 *)
  2406. exp := decSpec.GetQuantExponent(tile, i, 0, J2KU.SUB_LL);
  2407. mant := decSpec.GetQuantMantissa(tile, i, 0, J2KU.SUB_LL);
  2408. preStep[tile][i][0][0] := ((1 + (mant / NORM_FACT)) / LSH(SYSTEM.VAL(LONGINT, 1), exp));
  2409. (* Now the other resolution levels *)
  2410. FOR r := 1 TO ndec DO
  2411. exp := decSpec.GetQuantExponent(tile, i, r, J2KU.SUB_HL);
  2412. mant := decSpec.GetQuantMantissa(tile, i, r, J2KU.SUB_HL);
  2413. preStep[tile][i][r][0] := ((1 + (mant / NORM_FACT)) / LSH(SYSTEM.VAL(LONGINT, 1), exp));
  2414. exp := decSpec.GetQuantExponent(tile, i, r, J2KU.SUB_LH);
  2415. mant := decSpec.GetQuantMantissa(tile, i, r, J2KU.SUB_LH);
  2416. preStep[tile][i][r][1] := ((1 + (mant / NORM_FACT)) / LSH(SYSTEM.VAL(LONGINT, 1), exp));
  2417. exp := decSpec.GetQuantExponent(tile, i, r, J2KU.SUB_HH);
  2418. mant := decSpec.GetQuantMantissa(tile, i, r, J2KU.SUB_HH);
  2419. preStep[tile][i][r][2] := ((1 + (mant / NORM_FACT)) / LSH(SYSTEM.VAL(LONGINT, 1), exp));
  2420. END;
  2421. | J2KCS.QUANT_DER:
  2422. (* The values for the NL-LL band are signalled only *)
  2423. IF preStep = NIL THEN
  2424. NEW(preStep, ntiles);
  2425. END;
  2426. IF preStep[tile] = NIL THEN
  2427. NEW(preStep[tile], ncomp);
  2428. END;
  2429. NEW(preStep[tile][i], 1);
  2430. exp := decSpec.GetQuantExponent(tile, i, 0, J2KU.SUB_LL);
  2431. mant := decSpec.GetQuantMantissa(tile, i, 0, J2KU.SUB_LL);
  2432. preStep[tile][i][0][0] := ((1 + (mant / NORM_FACT)) / LSH(SYSTEM.VAL(LONGINT, 1), exp));
  2433. ELSE
  2434. KernelLog.String("ERROR (Dequantizer.CalculateStepSizes) : Unknown quantization style");
  2435. KernelLog.Ln();
  2436. END;
  2437. END;
  2438. END CalculateStepSizes;
  2439. PROCEDURE GetSubbandInfo (tile, component, reslevel, subband : LONGINT) : J2KU.SubbandInfo;
  2440. BEGIN
  2441. RETURN roi.GetSubbandInfo(tile, component, reslevel, subband)
  2442. END GetSubbandInfo;
  2443. PROCEDURE TilePartAvailable () : BOOLEAN;
  2444. BEGIN
  2445. RETURN roi.TilePartAvailable();
  2446. END TilePartAvailable;
  2447. PROCEDURE AllTilePartsRead () : BOOLEAN;
  2448. BEGIN
  2449. RETURN roi.AllTilePartsRead();
  2450. END AllTilePartsRead;
  2451. (**
  2452. Sets the maximum layer range for which data shall be delivered
  2453. and decoded, i.e. data outside this range shall NEVER be requested.
  2454. This procedure shall NOT be called after the first code-block data
  2455. has been read.
  2456. maxStartLayer and maxEndLayer are inclusive.
  2457. *)
  2458. PROCEDURE SetMaxLayerRange (maxStartLayer, maxEndLayer : LONGINT);
  2459. BEGIN
  2460. roi.SetMaxLayerRange(maxStartLayer, maxEndLayer);
  2461. END SetMaxLayerRange;
  2462. (**
  2463. Sets the layer range for which data shall be delivered
  2464. and decoded.
  2465. startLayer and endLayer are inclusive.
  2466. *)
  2467. PROCEDURE SetLayerRange (startLayer, endLayer : LONGINT);
  2468. BEGIN
  2469. roi.SetLayerRange(startLayer, endLayer);
  2470. END SetLayerRange;
  2471. (**
  2472. Gets the layer range for which data shall be delivered
  2473. and decoded.
  2474. startLayer and endLayer are inclusive.
  2475. *)
  2476. PROCEDURE GetLayerRange (VAR startLayer, endLayer : LONGINT);
  2477. BEGIN
  2478. roi.GetLayerRange(startLayer, endLayer);
  2479. END GetLayerRange;
  2480. (**
  2481. Sets the maximum decomposition level range for which data shall be delivered
  2482. and decoded, i.e. data outside this range shall NEVER be requested. This procedure
  2483. shall NOT be called after the first code-block data has been read.
  2484. maxStartDecLvl : The decompositon level to start at (inclusive) -> upper bound
  2485. maxEndDecLvl : The decomposition level to end at (inclusive) -> lower bound
  2486. *)
  2487. PROCEDURE SetMaxDecLevelRange (maxStartDecLvl, maxEndDecLvl : LONGINT);
  2488. BEGIN
  2489. overallMinDecLvl := maxEndDecLvl;
  2490. roi.SetMaxDecLevelRange(maxStartDecLvl, maxEndDecLvl);
  2491. END SetMaxDecLevelRange;
  2492. (**
  2493. Sets the decomposition level range for which data shall be delivered
  2494. and decoded.
  2495. startDecLvl : The decompositon level to start at (inclusive) -> upper bound
  2496. endDecLvl : The decomposition level to end at (inclusive) -> lower bound
  2497. *)
  2498. PROCEDURE SetDecLevelRange (startDecLvl, endDecLvl : LONGINT);
  2499. BEGIN
  2500. roi.SetDecLevelRange(startDecLvl, endDecLvl);
  2501. END SetDecLevelRange;
  2502. (**
  2503. Gets the decomposition level range for which data shall be delivered
  2504. and decoded.
  2505. startDec : The decompositon level to start at (inclusive) -> upper bound
  2506. endDec : The decomposition level to end at (inclusive) -> lower bound
  2507. *)
  2508. PROCEDURE GetDecLevelRange (VAR startDec, endDec : LONGINT);
  2509. BEGIN
  2510. roi.GetDecLevelRange(startDec, endDec);
  2511. END GetDecLevelRange;
  2512. PROCEDURE SetReBuildMode;
  2513. BEGIN
  2514. roi.SetReBuildMode();
  2515. END SetReBuildMode;
  2516. (**
  2517. Returns dequantized code-blocks
  2518. *)
  2519. PROCEDURE GetCodeBlocks (VAR cblk : ARRAY OF DataBlk; VAR cblkInfo : ARRAY OF J2KU.CblkInfo; ncblks : LONGINT) : LONGINT;
  2520. VAR
  2521. cblkIdx, ncblksRet : LONGINT;
  2522. qStyle, cblkSize, width, height, shift, i, j, tmp, gainLog : LONGINT;
  2523. curTile, comp, ndec : LONGINT;
  2524. step : REAL;
  2525. realData : J2KU.RealArrayPtr;
  2526. srcData : J2KU.LongIntArrayPtr;
  2527. cblkReal : DataBlkReal;
  2528. subbInfo : J2KU.SubbandInfo;
  2529. dataIdxIn, scanwIn, dataIdxOut, scanwOut : LONGINT;
  2530. BEGIN
  2531. (*
  2532. This implementation relies on the condition that the component above this one
  2533. always requests <= CBLK_BUFSIZE code-blocks
  2534. *)
  2535. ASSERT(ncblks <= CBLK_BUFSIZE);
  2536. ncblksRet := roi.GetCodeBlocks(cblkBuf, cblkInfo, ncblks);
  2537. curTile := roi.CurrentTile();
  2538. FOR cblkIdx := 0 TO ncblksRet - 1 DO
  2539. (* Get the maximum number of most significant bits for this code-block *)
  2540. subbInfo := cblkInfo[cblkIdx].subbinfo;
  2541. comp := subbInfo.component;
  2542. qStyle := decSpec.GetQuantStyle(curTile, comp);
  2543. cblkSize := cblkInfo[cblkIdx].width*cblkInfo[cblkIdx].height;
  2544. width := cblkInfo[cblkIdx].width;
  2545. height := cblkInfo[cblkIdx].height;
  2546. shift := J2KU.LONGINT_BITS - 1 - subbInfo.magbits;
  2547. srcData := cblkBuf[cblkIdx](DataBlkInt).data;
  2548. dataIdxIn := cblkBuf[cblkIdx].offset;
  2549. scanwIn := cblkBuf[cblkIdx].scanw;
  2550. CASE dataTypes[curTile][comp] OF
  2551. | DATA_LONGINT :
  2552. (* We can use the source block as destination block *)
  2553. cblk[cblkIdx] := cblkBuf[cblkIdx];
  2554. | DATA_REAL :
  2555. (* We cannot do in-place modification *)
  2556. (* Allocate new code-block for REAL data *)
  2557. NEW(cblkReal);
  2558. NEW(realData, cblkSize);
  2559. (* Set fields *)
  2560. cblkReal.data := realData;
  2561. cblkReal.offset := 0;
  2562. cblkReal.scanw := width;
  2563. cblk[cblkIdx] := cblkReal;
  2564. END;
  2565. IF qStyle = J2KCS.NOQUANT THEN
  2566. CASE dataTypes[curTile][comp] OF
  2567. | DATA_LONGINT :
  2568. (* First we adjust the data *)
  2569. FOR j := 0 TO height - 1 DO
  2570. FOR i := 0 TO width - 1 DO
  2571. IF srcData[dataIdxIn] >= 0 THEN
  2572. srcData[dataIdxIn] := LSH(srcData[dataIdxIn], -shift);
  2573. ELSE
  2574. srcData[dataIdxIn] := -LSH(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, srcData[dataIdxIn]) / J2KU.LONGINT_SIGN_BIT), -shift);
  2575. END;
  2576. INC(dataIdxIn);
  2577. END;
  2578. dataIdxIn := dataIdxIn - width + scanwIn;
  2579. END;
  2580. | DATA_REAL :
  2581. (* First we adjust the data -> No in-place transformation possible *)
  2582. dataIdxOut := cblk[cblkIdx].offset;
  2583. scanwOut := cblk[cblkIdx].scanw;
  2584. FOR j := 0 TO height - 1 DO
  2585. FOR i := 0 TO width - 1 DO
  2586. IF srcData[dataIdxIn] >= 0 THEN
  2587. realData[dataIdxOut] := LSH(srcData[dataIdxIn], -shift);
  2588. ELSE
  2589. realData[dataIdxOut] := -LSH(SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, srcData[dataIdxIn]) / J2KU.LONGINT_SIGN_BIT), -shift);
  2590. END;
  2591. INC(dataIdxIn);
  2592. INC(dataIdxOut);
  2593. END;
  2594. dataIdxIn := dataIdxIn - width + scanwIn;
  2595. dataIdxOut := dataIdxOut - width + scanwOut;
  2596. END;
  2597. END;
  2598. ELSE
  2599. (* (Irreversible) quantization is used *)
  2600. (* Determine the base 2 exponent of the subband gain and the index of the subband in the step size array *)
  2601. CASE subbInfo.type OF
  2602. | J2KU.SUB_LL:
  2603. gainLog := 0;
  2604. | J2KU.SUB_HL:
  2605. gainLog := 1;
  2606. | J2KU.SUB_LH:
  2607. gainLog := 1;
  2608. | J2KU.SUB_HH:
  2609. gainLog := 2;
  2610. END;
  2611. IF qStyle = J2KCS.QUANT_DER THEN
  2612. (* Derived exponent *)
  2613. ndec := decSpec.GetNumDecLevels(curTile, comp);
  2614. step := preStep[curTile][comp][0][0]
  2615. * LSH(SYSTEM.VAL(LONGINT, 1), tBitDepth[comp] + gainLog + ndec - subbInfo.declevel);
  2616. ELSE
  2617. (* Values are singalled for each resolution level and subband *)
  2618. step := preStep[curTile][comp][subbInfo.reslevel][subbInfo.index]
  2619. * LSH(SYSTEM.VAL(LONGINT, 1), tBitDepth[comp] + gainLog);
  2620. END;
  2621. (* Adjust the step to the number of magnitude bits *)
  2622. step := step / LSH(SYSTEM.VAL(LONGINT, 1), shift);
  2623. CASE dataTypes[curTile][comp] OF
  2624. | DATA_LONGINT :
  2625. FOR j := 0 TO height - 1 DO
  2626. FOR i := 0 TO width - 1 DO
  2627. IF srcData[dataIdxIn] < 0 THEN
  2628. tmp := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, srcData[dataIdxIn]) / J2KU.LONGINT_SIGN_BIT);
  2629. srcData[dataIdxIn] := -ENTIER(tmp * step + 0.5);
  2630. ELSE
  2631. srcData[dataIdxIn] := ENTIER(srcData[dataIdxIn] * step + 0.5);
  2632. END;
  2633. INC(dataIdxIn);
  2634. END;
  2635. dataIdxIn := dataIdxIn - width + scanwIn;
  2636. END;
  2637. | DATA_REAL :
  2638. dataIdxOut := cblk[cblkIdx].offset;
  2639. scanwOut := cblk[cblkIdx].scanw;
  2640. FOR j := 0 TO height - 1 DO
  2641. FOR i := 0 TO width - 1 DO
  2642. IF srcData[dataIdxIn] < 0 THEN
  2643. tmp := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, srcData[dataIdxIn]) / J2KU.LONGINT_SIGN_BIT);
  2644. realData[dataIdxOut] := -tmp * step;
  2645. ELSE
  2646. realData[dataIdxOut] := srcData[dataIdxIn] * step;
  2647. END;
  2648. INC(dataIdxIn);
  2649. INC(dataIdxOut);
  2650. END;
  2651. dataIdxIn := dataIdxIn - width + scanwIn;
  2652. dataIdxOut := dataIdxOut - width + scanwOut;
  2653. END;
  2654. END;
  2655. END;
  2656. END;
  2657. RETURN ncblksRet;
  2658. END GetCodeBlocks;
  2659. PROCEDURE FreeNonRebuildResources;
  2660. BEGIN
  2661. roi.FreeNonRebuildResources();
  2662. END FreeNonRebuildResources;
  2663. PROCEDURE FreeResources;
  2664. VAR
  2665. i : LONGINT;
  2666. BEGIN
  2667. FOR i := 0 TO CBLK_BUFSIZE - 1 DO
  2668. cblkBuf[i] := NIL;
  2669. END;
  2670. dataTypes := NIL;
  2671. tBitDepth := NIL;
  2672. preStep := NIL;
  2673. roi.FreeResources();
  2674. END FreeResources;
  2675. END Dequantizer;
  2676. (* --- END Dequantizer types --- *)
  2677. (* --- Wavelet transformation types --- *)
  2678. (*
  2679. INFO:
  2680. Here there are two strategies when applying wavelet filters:
  2681. The Low Pass First convention and the High Pass First convention.
  2682. The Low Pass First convention is used when the low-pass coefficients
  2683. are located at even indexed positions after up-sampling.
  2684. The High Pass First convention is used when the high-pass coefficients
  2685. are located at even indexed positions after up-sampling.
  2686. *)
  2687. FilterSynInt = OBJECT
  2688. PROCEDURE SynthesizeLPF ( lowCoeffs : J2KU.LongIntArrayPtr; lowOffset, lowStep : LONGINT;
  2689. highCoeffs : J2KU.LongIntArrayPtr; highOffset, highStep : LONGINT;
  2690. outData : J2KU.LongIntArrayPtr; outOffset, outStep, len : LONGINT);
  2691. END SynthesizeLPF;
  2692. PROCEDURE SynthesizeHPF ( lowCoeffs : J2KU.LongIntArrayPtr; lowOffset, lowStep : LONGINT;
  2693. highCoeffs : J2KU.LongIntArrayPtr; highOffset, highStep : LONGINT;
  2694. outData : J2KU.LongIntArrayPtr; outOffset, outStep, len : LONGINT);
  2695. END SynthesizeHPF;
  2696. END FilterSynInt;
  2697. FilterSynReal = OBJECT
  2698. PROCEDURE SynthesizeLPF( lowCoeffs : J2KU.RealArrayPtr; lowOffset, lowStep : LONGINT;
  2699. highCoeffs : J2KU.RealArrayPtr; highOffset, highStep : LONGINT;
  2700. outData : J2KU.RealArrayPtr; outOffset, outStep, len : LONGINT);
  2701. END SynthesizeLPF;
  2702. PROCEDURE SynthesizeHPF( lowCoeffs : J2KU.RealArrayPtr; lowOffset, lowStep : LONGINT;
  2703. highCoeffs : J2KU.RealArrayPtr; highOffset, highStep : LONGINT;
  2704. outData : J2KU.RealArrayPtr; outOffset, outStep, len : LONGINT);
  2705. END SynthesizeHPF;
  2706. END FilterSynReal;
  2707. FilterSyn5x3Lifting = OBJECT(FilterSynInt)
  2708. PROCEDURE SynthesizeLPF ( lowCoeffs : J2KU.LongIntArrayPtr; lowOffset, lowStep : LONGINT;
  2709. highCoeffs : J2KU.LongIntArrayPtr; highOffset, highStep : LONGINT;
  2710. outData : J2KU.LongIntArrayPtr; outOffset, outStep, len : LONGINT);
  2711. VAR
  2712. iOut, iHigh, iLow, jmpOut, i : LONGINT;
  2713. oddLen : BOOLEAN;
  2714. BEGIN
  2715. iOut := outOffset;
  2716. jmpOut := 2*outStep; (* '2*' because of upsampling *)
  2717. iHigh := highOffset;
  2718. iLow := lowOffset;
  2719. oddLen := ODD(len);
  2720. (* Handle head boundary *)
  2721. IF len > 1 THEN
  2722. outData[iOut] := lowCoeffs[iLow] - ASH(highCoeffs[iHigh] + 1, -1);
  2723. ELSE
  2724. outData[iOut] := lowCoeffs[iLow];
  2725. END;
  2726. INC(iOut, jmpOut);
  2727. INC(iLow, lowStep);
  2728. INC(iHigh, highStep);
  2729. (* First reconstruct even-indexed samples *)
  2730. FOR i := 2 TO len - 2 BY 2 DO
  2731. outData[iOut] := lowCoeffs[iLow] - ASH(highCoeffs[iHigh-highStep] + highCoeffs[iHigh] + 2, -2);
  2732. INC(iOut, jmpOut);
  2733. INC(iHigh, highStep);
  2734. INC(iLow, lowStep);
  2735. END;
  2736. (* If we have odd length, this means that the last sample is even-indexed *)
  2737. IF oddLen & (len > 2) THEN
  2738. outData[iOut] := lowCoeffs[iLow] - ASH(highCoeffs[iHigh - highStep] + 1, -1);
  2739. END;
  2740. iOut := outOffset + outStep;
  2741. iHigh := highOffset;
  2742. (* Now go for the odd-indexed samples *)
  2743. FOR i:=1 TO len - 2 BY 2 DO
  2744. outData[iOut] := highCoeffs[iHigh] + ASH(outData[iOut - outStep] + outData[iOut + outStep], -1);
  2745. INC(iOut, jmpOut);
  2746. INC(iHigh, highStep);
  2747. END;
  2748. (* If we have even length, this means that the last sample is odd-indexed *)
  2749. IF ~oddLen & (len > 1) THEN
  2750. outData[iOut] := highCoeffs[iHigh] + outData[iOut-outStep];
  2751. END;
  2752. END SynthesizeLPF;
  2753. PROCEDURE SynthesizeHPF ( lowCoeffs : J2KU.LongIntArrayPtr; lowOffset, lowStep : LONGINT;
  2754. highCoeffs : J2KU.LongIntArrayPtr; highOffset, highStep : LONGINT;
  2755. outData : J2KU.LongIntArrayPtr; outOffset, outStep, len : LONGINT);
  2756. VAR
  2757. iOut, iHigh, iLow, jmpOut, i : LONGINT;
  2758. oddLen : BOOLEAN;
  2759. BEGIN
  2760. iOut := outOffset + outStep;
  2761. jmpOut := 2*outStep; (* '2*' because of upsampling *)
  2762. iHigh := highOffset;
  2763. iLow := lowOffset;
  2764. oddLen := ODD(len);
  2765. (* First reconstruct even-indexed samples *)
  2766. FOR i := 1 TO len - 2 BY 2 DO
  2767. outData[iOut] := lowCoeffs[iLow] - ASH(highCoeffs[iHigh] + highCoeffs[iHigh+highStep] + 2, -2);
  2768. INC(iOut, jmpOut);
  2769. INC(iHigh, highStep);
  2770. INC(iLow, lowStep);
  2771. END;
  2772. IF ~oddLen & (len > 1) THEN
  2773. outData[iOut] := lowCoeffs[iLow] - ASH(highCoeffs[iHigh] + 1, -1);
  2774. END;
  2775. iOut := outOffset;
  2776. iHigh := highOffset;
  2777. (* Handle head boundary *)
  2778. IF len > 1 THEN
  2779. outData[iOut] := highCoeffs[iHigh] + outData[iOut + outStep];
  2780. ELSE
  2781. outData[iOut] := ASH(highCoeffs[iHigh], -1);
  2782. END;
  2783. INC(iOut, jmpOut);
  2784. INC(iHigh, highStep);
  2785. (* Now go for the odd-indexed samples *)
  2786. FOR i := 2 TO len - 2 BY 2 DO
  2787. outData[iOut] := highCoeffs[iHigh] + ASH(outData[iOut - outStep] + outData[iOut + outStep], -1);
  2788. INC(iOut, jmpOut);
  2789. INC(iHigh, highStep);
  2790. END;
  2791. (* If we have odd length, this means that the last sample is odd-indexed *)
  2792. IF oddLen & (len > 1) THEN
  2793. outData[iOut] := highCoeffs[iHigh] + outData[iOut - outStep];
  2794. END;
  2795. END SynthesizeHPF;
  2796. END FilterSyn5x3Lifting;
  2797. CONST
  2798. (* Lifting constants for the 9x7 irreversible filter *)
  2799. ALPHA = -1.586134342;
  2800. BETA = -0.05298011854;
  2801. GAMMA = 0.8829110762;
  2802. DELTA = 0.443568522;
  2803. KL = 0.8128930655;
  2804. KH = 1.230174106;
  2805. TYPE
  2806. FilterSyn9x7Lifting = OBJECT(FilterSynReal)
  2807. PROCEDURE SynthesizeLPF( lowCoeffs : J2KU.RealArrayPtr; lowOffset, lowStep : LONGINT;
  2808. highCoeffs : J2KU.RealArrayPtr; highOffset, highStep : LONGINT;
  2809. outData : J2KU.RealArrayPtr; outOffset, outStep, len : LONGINT);
  2810. VAR
  2811. iOut, iHigh, iLow, jmpOut, i : LONGINT;
  2812. oddLen : BOOLEAN;
  2813. BEGIN
  2814. (* NOTE: Step 1 & 2 as specified in the standard have been integrated into steps 3 & 4 *)
  2815. (* Step 3 as specified in the standard *)
  2816. iOut := outOffset;
  2817. jmpOut := 2*outStep;
  2818. iHigh := highOffset;
  2819. iLow := lowOffset;
  2820. oddLen := ODD(len);
  2821. (* Handle head boundary effect if reconstructed signal consists of more than 1 sample*)
  2822. IF len > 1 THEN
  2823. outData[iOut] := lowCoeffs[iLow]/KL - 2*DELTA*highCoeffs[iHigh]/KH;
  2824. ELSE
  2825. outData[iOut] := lowCoeffs[iLow];
  2826. END;
  2827. INC(iOut, jmpOut);
  2828. INC(iHigh, highStep);
  2829. INC(iLow, lowStep);
  2830. FOR i := 2 TO len - 2 BY 2 DO
  2831. outData[iOut] := lowCoeffs[iLow]/KL - DELTA*(highCoeffs[iHigh - highStep] + highCoeffs[iHigh])/KH;
  2832. INC(iOut, jmpOut);
  2833. INC(iHigh, highStep);
  2834. INC(iLow, lowStep);
  2835. END;
  2836. (* Handle tail boundary effect if reconstructed signal has odd length *)
  2837. (* If we have odd length, this means that the last sample is even-indexed *)
  2838. IF oddLen & (len > 2) THEN
  2839. outData[iOut] := lowCoeffs[iLow]/KL - 2*DELTA*(highCoeffs[iHigh - highStep])/KH;
  2840. END;
  2841. (* Step 4 as specified in the standard *)
  2842. iOut := outOffset + outStep;
  2843. iHigh := highOffset;
  2844. FOR i := 1 TO len - 2 BY 2 DO
  2845. outData[iOut] := highCoeffs[iHigh]/KH - GAMMA*(outData[iOut - outStep] + outData[iOut + outStep]);
  2846. INC(iOut, jmpOut);
  2847. INC(iHigh, highStep);
  2848. END;
  2849. (* Handle tail boundary effect if reconstructed signal has even length *)
  2850. (* If we have even length, this means that the last sample is odd-indexed *)
  2851. IF ~oddLen & (len > 1) THEN
  2852. outData[iOut] := highCoeffs[iHigh]/KH - 2*GAMMA*(outData[iOut - outStep]);
  2853. END;
  2854. (* Step 5 as specified in the standard *)
  2855. iOut := outOffset;
  2856. (* Handle head boundary effect if reconstructed signal consists of more than 1 sample *)
  2857. IF len > 1 THEN
  2858. outData[iOut] := outData[iOut] - 2*BETA*(outData[iOut + outStep]);
  2859. END;
  2860. INC(iOut, jmpOut);
  2861. FOR i := 2 TO len - 2 BY 2 DO
  2862. outData[iOut] := outData[iOut] - BETA*(outData[iOut - outStep] + outData[iOut + outStep]);
  2863. INC(iOut, jmpOut);
  2864. END;
  2865. (* Handle tail boundary effect if reconstructed signal has odd length *)
  2866. (* If we have odd length, this means that the last sample is even-indexed *)
  2867. IF oddLen & (len > 2) THEN
  2868. outData[iOut] := outData[iOut] - 2*BETA*outData[iOut - outStep];
  2869. END;
  2870. (* Step 6 as specified in the standard *)
  2871. iOut := outOffset + outStep;
  2872. FOR i := 1 TO len - 2 BY 2 DO
  2873. outData[iOut] := outData[iOut] - ALPHA*(outData[iOut - outStep] + outData[iOut + outStep]);
  2874. INC(iOut, jmpOut);
  2875. END;
  2876. (* Handle tail boundary effect if reconstructed signal has even length *)
  2877. (* If we have even length, this means that the last sample is odd-indexed *)
  2878. IF ~oddLen & (len > 1) THEN
  2879. outData[iOut] := outData[iOut] - 2*ALPHA*outData[iOut - outStep];
  2880. END;
  2881. END SynthesizeLPF;
  2882. PROCEDURE SynthesizeHPF( lowCoeffs : J2KU.RealArrayPtr; lowOffset, lowStep : LONGINT;
  2883. highCoeffs : J2KU.RealArrayPtr; highOffset, highStep : LONGINT;
  2884. outData : J2KU.RealArrayPtr; outOffset, outStep, len : LONGINT);
  2885. VAR
  2886. iOut, iHigh, iLow, jmpOut, i : LONGINT;
  2887. oddLen : BOOLEAN;
  2888. BEGIN
  2889. (* NOTE: Step 1 & 2 as specified in the standard have been integrated into steps 3 & 4 *)
  2890. (* Step 3 as specified in the standard *)
  2891. iOut := outOffset + outStep;
  2892. jmpOut := 2*outStep;
  2893. iHigh := highOffset;
  2894. iLow := lowOffset;
  2895. oddLen := ODD(len);
  2896. FOR i := 1 TO len - 2 BY 2 DO
  2897. outData[iOut] := lowCoeffs[iLow]/KL - DELTA*(highCoeffs[iHigh]/KH + highCoeffs[iHigh + highStep]/KH);
  2898. INC(iOut, jmpOut);
  2899. INC(iHigh, highStep);
  2900. INC(iLow, lowStep);
  2901. END;
  2902. (* Handle tail boundary effect if reconstructed signal has even length *)
  2903. (* Ifwe have even length, this means that the last sample is even-indexed *)
  2904. IF ~oddLen & (len > 1) THEN
  2905. outData[iOut] := lowCoeffs[iLow]/KL - 2*DELTA*(highCoeffs[iHigh]/KH);
  2906. END;
  2907. (* Step 4 as specified in the standard *)
  2908. iOut := outOffset;
  2909. iHigh := highOffset;
  2910. (* Handle head boundary effect if reconstructed signal consists of more than 1 sample *)
  2911. IF len > 1 THEN
  2912. outData[iOut] := highCoeffs[iHigh]/KH - 2*GAMMA*outData[iOut + outStep];
  2913. ELSE
  2914. outData[iOut] := highCoeffs[iHigh] / 2;
  2915. END;
  2916. INC(iOut, jmpOut);
  2917. INC(iHigh, highStep);
  2918. FOR i := 2 TO len - 2 BY 2 DO
  2919. outData[iOut] := highCoeffs[iHigh]/KH - GAMMA*(outData[iOut - outStep] + outData[iOut + outStep]);
  2920. INC(iOut, jmpOut);
  2921. INC(iHigh, highStep);
  2922. END;
  2923. (* Handle tail boundary effect if reconstructed signal has odd length *)
  2924. (* If we have odd length, this means that the last sample is odd-indexed *)
  2925. IF oddLen & (len > 2) THEN
  2926. outData[iOut] := highCoeffs[iHigh]/KH - 2*GAMMA*outData[iOut - outStep];
  2927. END;
  2928. (* Step 5 as specified in the standard *)
  2929. iOut := outOffset + outStep;
  2930. FOR i := 1 TO len - 2 BY 2 DO
  2931. outData[iOut] := outData[iOut] - BETA*(outData[iOut - outStep] + outData[iOut + outStep]);
  2932. INC(iOut, jmpOut);
  2933. END;
  2934. (* Handle tail boundary effect if reconstructed signal has even length *)
  2935. (* If we have even length, this means that the last sample is even-indexed *)
  2936. IF ~oddLen & (len > 1) THEN
  2937. outData[iOut] := outData[iOut] - 2*BETA*outData[iOut - outStep];
  2938. END;
  2939. (* Step 6 as specified in the standard *)
  2940. iOut := outOffset;
  2941. (* Handle head boundary effect if reconstructed signal consists of more than 1 sample *)
  2942. IF len > 1 THEN
  2943. outData[iOut] := outData[iOut] - 2*ALPHA*outData[iOut + outStep];
  2944. END;
  2945. INC(iOut, jmpOut);
  2946. FOR i := 2 TO len - 2 BY 2 DO
  2947. outData[iOut] := outData[iOut] - ALPHA*(outData[iOut - outStep] + outData[iOut + outStep]);
  2948. INC(iOut, jmpOut);
  2949. END;
  2950. (* Handle tail boundary effect if reconstructed signal has odd length *)
  2951. (* If we have odd length, this means that the last sample is odd-indexed *)
  2952. IF oddLen & (len > 2) THEN
  2953. outData[iOut] := outData[iOut] - 2*ALPHA*outData[iOut - outStep];
  2954. END;
  2955. END SynthesizeHPF;
  2956. END FilterSyn9x7Lifting;
  2957. InverseDWT = OBJECT
  2958. VAR
  2959. deq : Dequantizer;
  2960. curTile : LONGINT;
  2961. ncomp : LONGINT;
  2962. minDecLvl, maxDecLvl, minLayer, maxLayer : LONGINT;
  2963. reconstructedComps : POINTER TO ARRAY OF ARRAY OF DataBlk;
  2964. reconstructedCompsInfo : POINTER TO ARRAY OF ARRAY OF J2KU.BlkInfo;
  2965. reconstructedRange : POINTER TO ARRAY OF ARRAY 4 OF LONGINT;
  2966. filterIrrev : FilterSynReal; (* We always use a filter operating on real values when we have irreversible transformation *)
  2967. filterRev : FilterSynInt; (* We always use a filter operating on integer values when we have reversible transformation *)
  2968. decSpec : J2KCS.DecoderSpecs;
  2969. gotoReBuild : BOOLEAN;
  2970. overallMinDecLvl : LONGINT;
  2971. PROCEDURE &InitNew *( invDWTOpt : J2KU.InverseDWTOptions;
  2972. deq : Dequantizer;
  2973. decSpec : J2KCS.DecoderSpecs);
  2974. BEGIN
  2975. ReInit(invDWTOpt, deq, decSpec);
  2976. END InitNew;
  2977. PROCEDURE ReInit ( invDWTOpt : J2KU.InverseDWTOptions;
  2978. deq : Dequantizer;
  2979. decSpec : J2KCS.DecoderSpecs);
  2980. VAR
  2981. ntiles : LONGINT;
  2982. imgInfo : J2KCS.ImageInfo;
  2983. BEGIN
  2984. imgInfo := decSpec.GetImageInfo();
  2985. ncomp := imgInfo.GetNumComponents();
  2986. ntiles := imgInfo.GetNumTiles();
  2987. (* Initialize members *)
  2988. SELF.deq := deq;
  2989. SELF.decSpec := decSpec;
  2990. (* Default: Reconstruct the whole image *)
  2991. minDecLvl := 0;
  2992. maxDecLvl := MAX(LONGINT);
  2993. minLayer := 0;
  2994. maxLayer := MAX(LONGINT);
  2995. overallMinDecLvl := 0;
  2996. NEW(reconstructedComps, ntiles, ncomp);
  2997. NEW(reconstructedCompsInfo, ntiles, ncomp);
  2998. NEW(reconstructedRange, ntiles);
  2999. CASE invDWTOpt.filterRev OF
  3000. | FILTER_5X3_LIFTING :
  3001. filterRev := filter5x3Lift;
  3002. ELSE
  3003. KernelLog.String("ERROR (InverseDWT.ReInit): Invalid reversible filter type specified");
  3004. KernelLog.Ln();
  3005. END;
  3006. CASE invDWTOpt.filterIrrev OF
  3007. | FILTER_9X7_LIFTING :
  3008. filterIrrev := filter9x7Lift;
  3009. ELSE
  3010. KernelLog.String("ERROR (InverseDWT.ReInit): Invalid irreversible filter type specified");
  3011. KernelLog.Ln();
  3012. END;
  3013. gotoReBuild := FALSE;
  3014. END ReInit;
  3015. PROCEDURE FullTransform () : BOOLEAN;
  3016. BEGIN
  3017. (* Since this implementation does a full transformation per step, this procedure is just a wrapper *)
  3018. RETURN TransformStep();
  3019. END FullTransform;
  3020. (*
  3021. Initializes all coefficients contained in the reconstructed component buffer to 0
  3022. (or 0.0 in the case of floating point values). That is done for all components of the
  3023. current tile.
  3024. *)
  3025. PROCEDURE InitReconstructedRange;
  3026. VAR
  3027. recMinDecLvl, c, ndec : LONGINT;
  3028. reslevel, offset, width, height, scanw, h : LONGINT;
  3029. subbInfo : J2KU.SubbandInfo;
  3030. dataInt : J2KU.LongIntArrayPtr;
  3031. dataReal : J2KU.RealArrayPtr;
  3032. BEGIN
  3033. (* NOTE:
  3034. We need to re-init the whole buffer up to the current decomposition level.
  3035. We cannot just re-init the reconstructed range, because the lower levels
  3036. also get affected during wavelet reconstruction (-> they're just 0 low pass
  3037. contributions).
  3038. *)
  3039. (* Need to get the 'real' minimum decomposition level of the reconstructed components *)
  3040. IF reconstructedRange[curTile][3] < 0 THEN
  3041. recMinDecLvl := 0;
  3042. ELSE
  3043. recMinDecLvl := reconstructedRange[curTile][3];
  3044. END;
  3045. FOR c := 0 TO ncomp - 1 DO
  3046. ndec := decSpec.GetNumDecLevels(curTile, c);
  3047. reslevel := ndec - recMinDecLvl;
  3048. (* Maybe the component has not been reconstructed at all *)
  3049. IF reslevel >= 0 THEN
  3050. (* Get the LL subband of the reconstructed resolution level *)
  3051. subbInfo := deq.GetSubbandInfo(curTile, c, reslevel, J2KU.SUB_LL);
  3052. offset := reconstructedComps[curTile][c].offset;
  3053. scanw := reconstructedComps[curTile][c].scanw;
  3054. width := subbInfo.width;
  3055. height := subbInfo.height;
  3056. IF reconstructedComps[curTile][c] IS DataBlkInt THEN
  3057. dataInt := reconstructedComps[curTile][c](DataBlkInt).data;
  3058. FOR h := 0 TO subbInfo.height - 1 DO
  3059. Machine.Fill32(ADDRESSOF(dataInt[offset]), width*SIZEOF(LONGINT), 0);
  3060. INC(offset, scanw);
  3061. END;
  3062. ELSIF reconstructedComps[curTile][c] IS DataBlkReal THEN
  3063. dataReal := reconstructedComps[curTile][c](DataBlkReal).data;
  3064. FOR h := 0 TO subbInfo.height - 1 DO
  3065. Machine.Fill32(ADDRESSOF(dataReal[offset]), width*SIZEOF(REAL), 0);
  3066. INC(offset, scanw);
  3067. END;
  3068. END;
  3069. END;
  3070. END;
  3071. END InitReconstructedRange;
  3072. (*
  3073. Gets data from the lower level (the dequantization component, that is)
  3074. and stores it in the internal buffer.
  3075. *)
  3076. PROCEDURE GetData () : BOOLEAN;
  3077. VAR
  3078. ncblksRet, i, j, rowStartComp, rowStartCblk : LONGINT;
  3079. dataCblkArr : ARRAY CBLK_BUFSIZE OF DataBlk;
  3080. dataCblkInfoArr : ARRAY CBLK_BUFSIZE OF J2KU.CblkInfo;
  3081. dataCblk : DataBlk;
  3082. recComp : DataBlk;
  3083. dataInt : J2KU.LongIntArrayPtr;
  3084. dataReal : J2KU.RealArrayPtr;
  3085. comp : LONGINT;
  3086. BEGIN
  3087. (* We let the dequantizer instantiate the concrete code-blocks *)
  3088. ncblksRet := deq.GetCodeBlocks(dataCblkArr, dataCblkInfoArr, CBLK_BUFSIZE);
  3089. (* Get code-blocks until all blocks for the current resolution level have been received *)
  3090. WHILE ncblksRet > 0 DO
  3091. FOR j := 0 TO ncblksRet - 1 DO
  3092. (* Copy data to internal buffer *)
  3093. comp := dataCblkInfoArr[j].subbinfo.component;
  3094. recComp := reconstructedComps[curTile][comp];
  3095. rowStartComp := dataCblkInfoArr[j].ulsy * recComp.scanw + dataCblkInfoArr[j].ulsx + recComp.offset;
  3096. rowStartCblk := dataCblkArr[j].offset;
  3097. dataCblk := dataCblkArr[j];
  3098. IF dataCblk IS DataBlkInt THEN
  3099. WITH dataCblk : DataBlkInt DO
  3100. dataInt := recComp(DataBlkInt).data;
  3101. FOR i := 0 TO dataCblkInfoArr[j].height - 1 DO
  3102. SYSTEM.MOVE(ADDRESSOF(dataCblk.data[rowStartCblk]), ADDRESSOF(dataInt[rowStartComp]), dataCblkInfoArr[j].width * SIZEOF(LONGINT));
  3103. INC(rowStartComp, recComp.scanw);
  3104. INC(rowStartCblk, dataCblk.scanw);
  3105. END;
  3106. END;
  3107. ELSIF dataCblk IS DataBlkReal THEN
  3108. WITH dataCblk : DataBlkReal DO
  3109. dataReal := recComp(DataBlkReal).data;
  3110. FOR i := 0 TO dataCblkInfoArr[j].height - 1 DO
  3111. SYSTEM.MOVE(ADDRESSOF(dataCblk.data[rowStartCblk]), ADDRESSOF(dataReal[rowStartComp]), dataCblkInfoArr[j].width * SIZEOF(REAL));
  3112. INC(rowStartComp, recComp.scanw);
  3113. INC(rowStartCblk, dataCblk.scanw);
  3114. END;
  3115. END;
  3116. ELSE
  3117. KernelLog.String("ERROR (InverseDWT.TransformStep) : Dequantizer returned unknown data-block type");
  3118. KernelLog.Ln();
  3119. RETURN FALSE;
  3120. END;
  3121. END;
  3122. (* We let the dequantizer instantiate the concrete code-blocks *)
  3123. ncblksRet := deq.GetCodeBlocks(dataCblkArr, dataCblkInfoArr, CBLK_BUFSIZE);
  3124. END;
  3125. RETURN TRUE;
  3126. END GetData;
  3127. (* Does 1 transformation step. This implmentation sets TransformStep = FullTransform *)
  3128. PROCEDURE TransformStep () : BOOLEAN;
  3129. VAR
  3130. i, origMaxDecLvl, origMinDecLvl : LONGINT;
  3131. BEGIN
  3132. (* Save original decomposition level range *)
  3133. origMaxDecLvl := maxDecLvl;
  3134. origMinDecLvl := minDecLvl;
  3135. (*
  3136. We need to set the appropriate decomposition level range, i.e. maybe we don't
  3137. have to rebuild from scratch but can continue reconstructing from the current
  3138. decomposition level range.
  3139. The following conditions for rebuilding from the current state are required:
  3140. 1. The layer range has not changed
  3141. 2. The maximum decomposition level has not changed
  3142. 3. The new minimum decomposition level is lower
  3143. than the current decomposition level (i.e. the new
  3144. resolution is higher than the current one)
  3145. Otherwise we need to reconstruct from the beginning.
  3146. *)
  3147. (* NOTE The following IF statement should NEVER evaluate to TRUE, if we're NOT in rebuild mode *)
  3148. IF (reconstructedRange[curTile][0] = minLayer)
  3149. & (reconstructedRange[curTile][1] = maxLayer)
  3150. THEN
  3151. IF (reconstructedRange[curTile][3] > origMinDecLvl)
  3152. & (reconstructedRange[curTile][2] = origMaxDecLvl)
  3153. THEN (* Need only the data of higher resolution levels (i.e. lower decomposition levels) *)
  3154. SetDecLevelRange(reconstructedRange[curTile][3]-1, origMinDecLvl);
  3155. IF ~GetData() THEN
  3156. RETURN FALSE;
  3157. END;
  3158. (*
  3159. We now need to set the start decomposition level to the upper decomposition level of the
  3160. reconstructed components, otherwise we would skip one reconstruction step
  3161. *)
  3162. SetDecLevelRange(reconstructedRange[curTile][3], origMinDecLvl);
  3163. (* If nothing has changed, we don't need to do anything *)
  3164. ELSIF (reconstructedRange[curTile][3] # origMinDecLvl)
  3165. OR (reconstructedRange[curTile][2] # origMaxDecLvl)
  3166. THEN
  3167. (* Need to reinitialize the reconstructed range *)
  3168. InitReconstructedRange();
  3169. (* We need to refetch all the data *)
  3170. IF ~GetData() THEN
  3171. RETURN FALSE;
  3172. END;
  3173. END;
  3174. ELSE (* Default case: retrieve all data *)
  3175. (* Need to reinitialize the reconstructed range *)
  3176. InitReconstructedRange();
  3177. IF ~GetData() THEN
  3178. RETURN FALSE;
  3179. END;
  3180. END;
  3181. (* Perform 2D wavelet reconstrution steps for each component of the current tile *)
  3182. (* Transformation only done, if no more tile-parts will follow *)
  3183. IF AllTilePartsRead() THEN
  3184. FOR i := 0 TO ncomp - 1 DO
  3185. IF ~Wavelet2DReconstruction(curTile, i) THEN
  3186. RETURN FALSE;
  3187. END;
  3188. END;
  3189. reconstructedRange[curTile][0] := minLayer;
  3190. reconstructedRange[curTile][1] := maxLayer;
  3191. reconstructedRange[curTile][2] := origMaxDecLvl;
  3192. reconstructedRange[curTile][3] := origMinDecLvl;
  3193. END;
  3194. (* Restore the original decompositon level range *)
  3195. SetDecLevelRange(origMaxDecLvl, origMinDecLvl);
  3196. RETURN TRUE;
  3197. END TransformStep;
  3198. (**
  3199. Sets the maximum layer range for which data shall be delivered
  3200. and decoded, i.e. data outside this range shall NEVER be requested.
  3201. This procedure shall NOT be called after the first code-block data
  3202. has been read.
  3203. maxStartLayer and maxEndLayer are inclusive.
  3204. *)
  3205. PROCEDURE SetMaxLayerRange (maxStartLayer, maxEndLayer : LONGINT);
  3206. BEGIN
  3207. deq.SetMaxLayerRange(maxStartLayer, maxEndLayer);
  3208. END SetMaxLayerRange;
  3209. (**
  3210. Sets the layer range for which data shall be delivered
  3211. and decoded.
  3212. startLayer and endLayer are inclusive.
  3213. *)
  3214. PROCEDURE SetLayerRange (startLayer, endLayer : LONGINT);
  3215. BEGIN
  3216. SELF.minLayer := startLayer;
  3217. SELF.maxLayer := endLayer;
  3218. deq.SetLayerRange(startLayer, endLayer);
  3219. END SetLayerRange;
  3220. (**
  3221. Gets the layer range for which data shall be delivered
  3222. and decoded.
  3223. startLayer and endLayer are inclusive.
  3224. *)
  3225. PROCEDURE GetLayerRange (VAR startLayer, endLayer : LONGINT);
  3226. BEGIN
  3227. startLayer := minLayer;
  3228. endLayer := maxLayer;
  3229. END GetLayerRange;
  3230. (**
  3231. Sets the maximum decomposition level range for which data shall be delivered
  3232. and decoded, i.e. data outside this range shall NEVER be requested. This procedure
  3233. shall NOT be called after the first code-block data has been read.
  3234. maxStartDecLvl : The decompositon level to start at (inclusive) -> upper bound
  3235. maxEndDecLvl : The decomposition level to end at (inclusive) -> lower bound
  3236. *)
  3237. PROCEDURE SetMaxDecLevelRange (maxStartDecLvl, maxEndDecLvl : LONGINT);
  3238. BEGIN
  3239. overallMinDecLvl := maxEndDecLvl;
  3240. deq.SetMaxDecLevelRange(maxStartDecLvl, maxEndDecLvl);
  3241. END SetMaxDecLevelRange;
  3242. (**
  3243. Sets the decomposition level range for which data shall be delivered
  3244. and decoded.
  3245. startDecLvl : The decompositon level to start at (inclusive) -> upper bound
  3246. endDecLvl : The decomposition level to end at (inclusive) -> lower bound
  3247. *)
  3248. PROCEDURE SetDecLevelRange (startDecLvl, endDecLvl : LONGINT);
  3249. BEGIN
  3250. SELF.minDecLvl := endDecLvl;
  3251. SELF.maxDecLvl := startDecLvl;
  3252. deq.SetDecLevelRange(startDecLvl, endDecLvl);
  3253. END SetDecLevelRange;
  3254. (**
  3255. Gets the decomposition level range for which data shall be delivered
  3256. and decoded.
  3257. startDec : The decompositon level to start at (inclusive) -> upper bound
  3258. endDec : The decomposition level to end at (inclusive) -> lower bound
  3259. *)
  3260. PROCEDURE GetDecLevelRange (VAR startDec, endDec : LONGINT);
  3261. BEGIN
  3262. startDec := maxDecLvl;
  3263. endDec := minDecLvl;
  3264. END GetDecLevelRange;
  3265. PROCEDURE GetComponent (component : LONGINT; VAR comp : DataBlk; VAR compInfo : J2KU.BlkInfo);
  3266. BEGIN
  3267. comp := reconstructedComps[curTile][component];
  3268. compInfo := reconstructedCompsInfo[curTile][component];
  3269. END GetComponent;
  3270. PROCEDURE CurrentTile () : LONGINT;
  3271. BEGIN
  3272. RETURN deq.CurrentTile();
  3273. END CurrentTile;
  3274. PROCEDURE CurrentTilePart () : LONGINT;
  3275. BEGIN
  3276. RETURN deq.CurrentTilePart();
  3277. END CurrentTilePart;
  3278. PROCEDURE NextTilePart () : BOOLEAN;
  3279. BEGIN
  3280. IF gotoReBuild THEN
  3281. SetReBuildMode();
  3282. gotoReBuild := FALSE;
  3283. END;
  3284. IF ~deq.NextTilePart() THEN
  3285. RETURN FALSE;
  3286. END;
  3287. RETURN InitTile();
  3288. END NextTilePart;
  3289. PROCEDURE AllTilePartsRead () : BOOLEAN;
  3290. BEGIN
  3291. RETURN deq.AllTilePartsRead();
  3292. END AllTilePartsRead;
  3293. PROCEDURE TilePartAvailable () : BOOLEAN;
  3294. BEGIN
  3295. RETURN deq.TilePartAvailable();
  3296. END TilePartAvailable;
  3297. PROCEDURE DataAvailable () : BOOLEAN;
  3298. BEGIN
  3299. RETURN deq.DataAvailable();
  3300. END DataAvailable;
  3301. PROCEDURE InitTile () : BOOLEAN;
  3302. VAR
  3303. transType, compSize, i, ndec : LONGINT;
  3304. subbInfo, subbInfoStart : J2KU.SubbandInfo;
  3305. compInt : DataBlkInt;
  3306. compReal : DataBlkReal;
  3307. recCompInfo : J2KU.BlkInfo;
  3308. minDecLvlTile : LONGINT;
  3309. BEGIN
  3310. curTile := deq.CurrentTile();
  3311. IF deq.CurrentTilePart() = 0 THEN
  3312. minDecLvlTile := decSpec.GetMinDecLevels(curTile);
  3313. (* Check that this tile has as much decomposition levels as required *)
  3314. IF minDecLvl > minDecLvlTile THEN
  3315. (* If possible, we can rebuild the image, else we issue an error and move to the end of/close the stream *)
  3316. IF overallMinDecLvl > minDecLvlTile THEN
  3317. (* We need to abort *)
  3318. KernelLog.String("ERROR (InverseDWT.InitTile): Can't build image at requested resolution level: ");
  3319. KernelLog.String(" Minimum resolution level of tile ");
  3320. KernelLog.Int(curTile, 0);
  3321. KernelLog.String(" is higher than the requested resolution level");
  3322. RETURN FALSE;
  3323. ELSE
  3324. (* After the current tile-part has been handled we enter the rebuild mode *)
  3325. gotoReBuild := TRUE;
  3326. (* Adjust new minimum decomposition level *)
  3327. SetDecLevelRange(maxDecLvl, minDecLvlTile);
  3328. END;
  3329. END;
  3330. FOR i := 0 TO ncomp - 1 DO
  3331. ndec := decSpec.GetNumDecLevels(curTile, i);
  3332. (* Get the subband info of the first resolution level (= start dec level for wavelet decomp.) *)
  3333. IF maxDecLvl >= ndec THEN
  3334. subbInfoStart := deq.GetSubbandInfo(curTile, i, 0, J2KU.SUB_LL);
  3335. ELSE
  3336. subbInfoStart := deq.GetSubbandInfo(curTile, i, ndec - maxDecLvl, J2KU.SUB_LL);
  3337. END;
  3338. (* We allocate space for the component at the maximum resolution level*)
  3339. subbInfo := deq.GetSubbandInfo(curTile, i, ndec - overallMinDecLvl, J2KU.SUB_LL);
  3340. compSize := subbInfo.width * subbInfo.height;
  3341. transType := decSpec.GetWavTransType(curTile, i);
  3342. NEW(recCompInfo);
  3343. recCompInfo.ulx := subbInfoStart.ulcx;
  3344. recCompInfo.uly := subbInfoStart.ulcy;
  3345. recCompInfo.width := subbInfoStart.width;
  3346. recCompInfo.height := subbInfoStart.height;
  3347. reconstructedCompsInfo[curTile][i] := recCompInfo;
  3348. IF transType = J2KCS.TRANS_5X3_REV THEN
  3349. NEW(compInt);
  3350. NEW(compInt.data, compSize);
  3351. deq.SetDataType(curTile, i, DATA_LONGINT);
  3352. reconstructedComps[curTile][i] := compInt;
  3353. (*Machine.Fill32(ADDRESSOF(compInt.data[0]), compSize*SIZEOF(LONGINT), 0);*)
  3354. ELSIF transType = J2KCS.TRANS_9X7_IRREV THEN
  3355. NEW(compReal);
  3356. NEW(compReal.data, compSize);
  3357. deq.SetDataType(curTile, i, DATA_REAL);
  3358. reconstructedComps[curTile][i] := compReal;
  3359. (*Machine.Fill32(ADDRESSOF(compReal.data[0]), compSize*SIZEOF(REAL), 0);*)
  3360. END;
  3361. reconstructedComps[curTile][i].offset := 0;
  3362. reconstructedComps[curTile][i].scanw := subbInfo.width;
  3363. END;
  3364. (* Layer range *)
  3365. reconstructedRange[curTile][0] := -1;
  3366. reconstructedRange[curTile][1] := -1;
  3367. (* Decomposition level range *)
  3368. reconstructedRange[curTile][2] := MIN(LONGINT);
  3369. reconstructedRange[curTile][3] := MAX(LONGINT);
  3370. END;
  3371. RETURN TRUE;
  3372. END InitTile;
  3373. (* Performs the 2D wavelet reconstruction with 2D-separable filters *)
  3374. PROCEDURE Wavelet2DReconstruction (tile, component : LONGINT) : BOOLEAN;
  3375. VAR
  3376. recComp : DataBlk;
  3377. recCompInfo : J2KU.BlkInfo;
  3378. ndec, curRes, curDec, ulcx, ulcy, ulx, uly, width, height, i, k, j : LONGINT;
  3379. subbInfo : J2KU.SubbandInfo;
  3380. bufInt, dataInt : J2KU.LongIntArrayPtr;
  3381. bufReal, dataReal : J2KU.RealArrayPtr;
  3382. dataOffset, tmpOffset : LONGINT;
  3383. transType : LONGINT;
  3384. BEGIN
  3385. recComp := reconstructedComps[tile][component];
  3386. recCompInfo := reconstructedCompsInfo[tile][component];
  3387. (* Get the corresponding transformation type *)
  3388. transType := decSpec.GetWavTransType(tile, component);
  3389. (* Get the pointers to the input/output data arrays *)
  3390. IF transType = J2KCS.TRANS_5X3_REV THEN
  3391. dataInt := recComp(DataBlkInt).data;
  3392. ELSIF transType = J2KCS.TRANS_9X7_IRREV THEN
  3393. dataReal := recComp(DataBlkReal).data;
  3394. ELSE
  3395. KernelLog.String("ERROR (InverseDWT.Wavelet2DReconstruction): Invalid/Unknown wavelet tranformation type specified");
  3396. KernelLog.Ln();
  3397. RETURN FALSE;
  3398. END;
  3399. (* Get number of decomposition levels *)
  3400. ndec := decSpec.GetNumDecLevels(tile, component);
  3401. (* Set the actual start decomposition level for this tile-component *)
  3402. IF maxDecLvl > ndec THEN
  3403. curDec := ndec;
  3404. ELSE
  3405. curDec := maxDecLvl;
  3406. END;
  3407. (* Store current values, in case we don't do any transformation *)
  3408. ulcx := recCompInfo.ulx;
  3409. ulcy := recCompInfo.uly;
  3410. width := recCompInfo.width;
  3411. height := recCompInfo.height;
  3412. (* While desired resolution /decomposition level not reached -> transform *)
  3413. (* NOTE: We don't check wether minDecLvl >= 0 here *)
  3414. WHILE (curDec > minDecLvl) DO
  3415. (* Go one decomposition level back *)
  3416. DEC(curDec);
  3417. (* Determine the resolution level to be reconstructed *)
  3418. curRes := ndec - curDec;
  3419. (* Get the LL subband at this resolution level *)
  3420. subbInfo := deq.GetSubbandInfo(tile, component, curRes, J2KU.SUB_LL);
  3421. ulcx := subbInfo.ulcx;
  3422. ulcy := subbInfo.ulcy;
  3423. ulx := subbInfo.ulsx;
  3424. uly := subbInfo.ulsy;
  3425. width := subbInfo.width;
  3426. height := subbInfo.height;
  3427. (* Only do reconstruction if subband has (width # 0) & (height # 0) *)
  3428. IF (width # 0) & (height # 0) THEN
  3429. dataOffset := uly*recComp.scanw + ulx + recComp.offset;
  3430. IF transType = J2KCS.TRANS_5X3_REV THEN
  3431. (* Do the horizontal reconstruction *)
  3432. tmpOffset := dataOffset;
  3433. IF width > height THEN
  3434. NEW(bufInt, width);
  3435. ELSE
  3436. NEW(bufInt, height);
  3437. END;
  3438. IF ~ODD(ulcx) THEN
  3439. (* The first coefficient is a low-pass coefficient *)
  3440. FOR i := 0 TO height - 1 DO
  3441. SYSTEM.MOVE(ADDRESSOF(dataInt[tmpOffset]), ADDRESSOF(bufInt[0]), width*SIZEOF(LONGINT));
  3442. (* If the width is odd then #(low-pass coefficients) = #(high-pass coefficients) + 1 *)
  3443. filterRev.SynthesizeLPF(bufInt, 0, 1, bufInt, (width+1) DIV 2, 1, dataInt, tmpOffset, 1, width);
  3444. INC(tmpOffset, recComp.scanw);
  3445. END;
  3446. ELSE
  3447. (* The first coefficient is a high-pass coefficient *)
  3448. FOR i := 0 TO height - 1 DO
  3449. SYSTEM.MOVE(ADDRESSOF(dataInt[tmpOffset]), ADDRESSOF(bufInt[0]), width*SIZEOF(LONGINT));
  3450. (* If the width is odd then #(high-pass coefficients) = #(low-pass coefficients) + 1 *)
  3451. filterRev.SynthesizeHPF(bufInt, 0, 1, bufInt, width DIV 2, 1, dataInt, tmpOffset, 1, width);
  3452. INC(tmpOffset, recComp.scanw);
  3453. END;
  3454. END;
  3455. (* Do the vertical reconstruction *)
  3456. tmpOffset := dataOffset;
  3457. IF ~ODD(ulcy) THEN
  3458. (* The first coefficient is a low-pass coefficient *)
  3459. FOR i := 0 TO width - 1 DO
  3460. k := tmpOffset;
  3461. FOR j := 0 TO height - 1 DO
  3462. bufInt[j] := dataInt[k];
  3463. INC(k, recComp.scanw);
  3464. END;
  3465. (* If the width is odd then #(low-pass coefficients) = #(high-pass coefficients) + 1 *)
  3466. filterRev.SynthesizeLPF(bufInt, 0, 1, bufInt, (height+1) DIV 2, 1, dataInt, tmpOffset, recComp.scanw, height);
  3467. INC(tmpOffset);
  3468. END;
  3469. ELSE
  3470. (* The first coefficient is a high-pass coefficient *)
  3471. FOR i := 0 TO width - 1 DO
  3472. k := tmpOffset;
  3473. FOR j := 0 TO height - 1 DO
  3474. bufInt[j] := dataInt[k];
  3475. INC(k, recComp.scanw);
  3476. END;
  3477. (* If the width is odd then #(high-pass coefficients) = #(low-pass coefficients) + 1 *)
  3478. filterRev.SynthesizeHPF(bufInt, 0, 1, bufInt, height DIV 2, 1, dataInt, tmpOffset, recComp.scanw, height);
  3479. INC(tmpOffset);
  3480. END;
  3481. END;
  3482. ELSIF transType = J2KCS.TRANS_9X7_IRREV THEN
  3483. (* Do the horizontal reconstruction *)
  3484. tmpOffset := dataOffset;
  3485. IF width > height THEN
  3486. NEW(bufReal, width);
  3487. ELSE
  3488. NEW(bufReal, height);
  3489. END;
  3490. IF ~ODD(ulcx) THEN
  3491. (* The first coefficient is a low-pass coefficient *)
  3492. FOR i := 0 TO height - 1 DO
  3493. SYSTEM.MOVE(ADDRESSOF(dataReal[tmpOffset]), ADDRESSOF(bufReal[0]), width*SIZEOF(REAL));
  3494. (* If the width is odd then #(low-pass coefficients) = #(high-pass coefficients) + 1 *)
  3495. filterIrrev.SynthesizeLPF(bufReal, 0, 1, bufReal, (width+1) DIV 2, 1, dataReal, tmpOffset, 1, width);
  3496. INC(tmpOffset, recComp.scanw);
  3497. END;
  3498. ELSE
  3499. (* The first coefficient is a high-pass coefficient *)
  3500. FOR i := 0 TO height - 1 DO
  3501. SYSTEM.MOVE(ADDRESSOF(dataReal[tmpOffset]), ADDRESSOF(bufReal[0]), width*SIZEOF(REAL));
  3502. (* If the width is odd then #(high-pass coefficients) = #(low-pass coefficients) + 1 *)
  3503. filterIrrev.SynthesizeHPF(bufReal, 0, 1, bufReal, width DIV 2, 1, dataReal, tmpOffset, 1, width);
  3504. INC(tmpOffset, recComp.scanw);
  3505. END;
  3506. END;
  3507. (* Do the vertical reconstruction *)
  3508. tmpOffset := dataOffset;
  3509. IF ~ODD(ulcy) THEN
  3510. (* The first coefficient is a low-pass coefficient *)
  3511. FOR i := 0 TO width - 1 DO
  3512. k := tmpOffset;
  3513. FOR j := 0 TO height - 1 DO
  3514. bufReal[j] := dataReal[k];
  3515. INC(k, recComp.scanw);
  3516. END;
  3517. (* If the width is odd then #(low-pass coefficients) = #(high-pass coefficients) + 1 *)
  3518. filterIrrev.SynthesizeLPF(bufReal, 0, 1, bufReal, (height+1) DIV 2, 1, dataReal, tmpOffset, recComp.scanw, height);
  3519. INC(tmpOffset);
  3520. END;
  3521. ELSE
  3522. (* The first coefficient is a high-pass coefficient *)
  3523. FOR i := 0 TO width - 1 DO
  3524. k := tmpOffset;
  3525. FOR j := 0 TO height - 1 DO
  3526. bufReal[j] := dataReal[k];
  3527. INC(k, recComp.scanw);
  3528. END;
  3529. (* If the width is odd then #(high-pass coefficients) = #(low-pass coefficients) + 1 *)
  3530. filterIrrev.SynthesizeHPF(bufReal, 0, 1, bufReal, height DIV 2, 1, dataReal, tmpOffset, recComp.scanw, height);
  3531. INC(tmpOffset);
  3532. END;
  3533. END;
  3534. END;
  3535. END;
  3536. END;
  3537. (* Update tile-component information *)
  3538. recCompInfo.ulx := ulcx;
  3539. recCompInfo.uly := ulcy;
  3540. recCompInfo.width := width;
  3541. recCompInfo.height := height;
  3542. RETURN TRUE;
  3543. END Wavelet2DReconstruction;
  3544. PROCEDURE SetReBuildMode;
  3545. BEGIN
  3546. deq.SetReBuildMode();
  3547. END SetReBuildMode;
  3548. PROCEDURE FreeNonRebuildResources;
  3549. BEGIN
  3550. deq.FreeNonRebuildResources();
  3551. END FreeNonRebuildResources;
  3552. PROCEDURE FreeResources;
  3553. BEGIN
  3554. reconstructedComps := NIL;
  3555. reconstructedCompsInfo := NIL;
  3556. reconstructedRange := NIL;
  3557. deq.FreeResources();
  3558. END FreeResources;
  3559. END InverseDWT;
  3560. (* --- END Wavelet transformation types --- *)
  3561. (* --- Inverse multiple component transformation types --- *)
  3562. InverseMCT = OBJECT
  3563. VAR
  3564. mct : LONGINT; (* The transformation type to be used *)
  3565. invDWT : InverseDWT; (* A reference to the wavelet tranformation object that will deliver data for us *)
  3566. curTile : LONGINT;
  3567. comp012 : POINTER TO ARRAY OF ARRAY OF DataBlkInt;
  3568. comp012Info : POINTER TO ARRAY OF ARRAY OF J2KU.BlkInfo;
  3569. decSpec : J2KCS.DecoderSpecs;
  3570. nonRebuildBuffer : BOOLEAN; (* Indicates wether the component data buffers shall be treated as rebuild or non-rebuild members *)
  3571. transformRequired : POINTER TO ARRAY OF BOOLEAN;
  3572. startLayer, endLayer, startDecLvl, endDecLvl : LONGINT;
  3573. PROCEDURE &InitNew *(invMCTOpt : J2KU.InverseMCTOptions;
  3574. invDWT : InverseDWT;
  3575. decSpec : J2KCS.DecoderSpecs);
  3576. BEGIN
  3577. ReInit(invMCTOpt, invDWT, decSpec);
  3578. END InitNew;
  3579. PROCEDURE ReInit ( invMCTOpt : J2KU.InverseMCTOptions;
  3580. invDWT : InverseDWT;
  3581. decSpec : J2KCS.DecoderSpecs);
  3582. VAR
  3583. i, ntiles: LONGINT;
  3584. imgInfo : J2KCS.ImageInfo;
  3585. BEGIN
  3586. SELF.invDWT := invDWT;
  3587. SELF.decSpec := decSpec;
  3588. imgInfo := decSpec.GetImageInfo();
  3589. ntiles := imgInfo.GetNumTiles();
  3590. NEW(comp012, ntiles, 3);
  3591. NEW(comp012Info, ntiles, 3);
  3592. nonRebuildBuffer := invMCTOpt.nonRebuildBuffer;
  3593. (* Reconstruct the whole image by default *)
  3594. startLayer := 0;
  3595. endLayer := MAX(LONGINT);
  3596. startDecLvl := MAX(LONGINT);
  3597. endDecLvl := 0;
  3598. NEW(transformRequired, ntiles);
  3599. FOR i := 0 TO ntiles - 1 DO
  3600. transformRequired[i] := TRUE;
  3601. END;
  3602. END ReInit;
  3603. (**
  3604. Sets the maximum layer range for which data shall be delivered
  3605. and decoded, i.e. data outside this range shall NEVER be requested.
  3606. This procedure shall NOT be called after the first code-block data
  3607. has been read.
  3608. maxStartLayer and maxEndLayer are inclusive.
  3609. *)
  3610. PROCEDURE SetMaxLayerRange (maxStartLayer, maxEndLayer : LONGINT);
  3611. BEGIN
  3612. invDWT.SetMaxLayerRange(maxStartLayer, maxEndLayer);
  3613. END SetMaxLayerRange;
  3614. (**
  3615. Sets the layer range for which data shall be delivered
  3616. and decoded.
  3617. startLayer and endLayer are inclusive.
  3618. *)
  3619. PROCEDURE SetLayerRange (startLayer, endLayer : LONGINT);
  3620. VAR
  3621. i : LONGINT;
  3622. BEGIN
  3623. IF (startLayer # SELF.startLayer) OR (endLayer # SELF.endLayer) THEN
  3624. FOR i := 0 TO LEN(transformRequired^) - 1 DO
  3625. transformRequired[i] := TRUE;
  3626. END;
  3627. END;
  3628. SELF.startLayer := startLayer;
  3629. SELF.endLayer := endLayer;
  3630. invDWT.SetLayerRange(startLayer, endLayer);
  3631. END SetLayerRange;
  3632. (**
  3633. Gets the layer range for which data shall be delivered
  3634. and decoded.
  3635. startLayer and endLayer are inclusive.
  3636. *)
  3637. PROCEDURE GetLayerRange (VAR startLayer, endLayer : LONGINT);
  3638. BEGIN
  3639. invDWT.GetLayerRange(startLayer, endLayer);
  3640. END GetLayerRange;
  3641. (**
  3642. Sets the maximum decomposition level range for which data shall be delivered
  3643. and decoded, i.e. data outside this range shall NEVER be requested. This procedure
  3644. shall NOT be called after the first code-block data has been read.
  3645. maxStartDecLvl : The decompositon level to start at (inclusive) -> upper bound
  3646. maxEndDecLvl : The decomposition level to end at (inclusive) -> lower bound
  3647. *)
  3648. PROCEDURE SetMaxDecLevelRange (maxStartDecLvl, maxEndDecLvl : LONGINT);
  3649. BEGIN
  3650. invDWT.SetMaxDecLevelRange(maxStartDecLvl, maxEndDecLvl);
  3651. END SetMaxDecLevelRange;
  3652. (**
  3653. Sets the decomposition level range for which data shall be delivered
  3654. and decoded.
  3655. startDecLvl : The decompositon level to start at (inclusive) -> upper bound
  3656. endDecLvl : The decomposition level to end at (inclusive) -> lower bound
  3657. *)
  3658. PROCEDURE SetDecLevelRange (startDecLvl, endDecLvl : LONGINT);
  3659. VAR
  3660. i : LONGINT;
  3661. BEGIN
  3662. IF (startDecLvl # SELF.startDecLvl) OR (endDecLvl # SELF.endDecLvl) THEN
  3663. FOR i := 0 TO LEN(transformRequired^) - 1 DO
  3664. transformRequired[i] := TRUE;
  3665. END;
  3666. END;
  3667. SELF.startDecLvl := startDecLvl;
  3668. SELF.endDecLvl := endDecLvl;
  3669. invDWT.SetDecLevelRange(startDecLvl, endDecLvl);
  3670. END SetDecLevelRange;
  3671. (**
  3672. Gets the decomposition level range for which data shall be delivered
  3673. and decoded.
  3674. startDecLvl : The decompositon level to start at (inclusive) -> upper bound
  3675. endDecLvl : The decomposition level to end at (inclusive) -> lower bound
  3676. *)
  3677. PROCEDURE GetDecLevelRange (VAR startDecLvl, endDecLvl : LONGINT);
  3678. BEGIN
  3679. startDecLvl := SELF.startDecLvl;
  3680. endDecLvl := SELF.endDecLvl;
  3681. END GetDecLevelRange;
  3682. (* Adapts a component when no component transformation is done (e.g. converting REAL to LONGINT) *)
  3683. PROCEDURE GetAdaptedComponent (component : LONGINT; VAR comp : DataBlk; VAR compInfo : J2KU.BlkInfo);
  3684. VAR
  3685. tmpComp : DataBlk;
  3686. dataBlkInt : DataBlkInt;
  3687. dataInt : J2KU.LongIntArrayPtr;
  3688. dataReal : J2KU.RealArrayPtr;
  3689. i, j, width, height, dataIdxReal, dataIdxInt, scanwReal, scanwInt : LONGINT;
  3690. BEGIN
  3691. invDWT.GetComponent(component, tmpComp, compInfo);
  3692. IF tmpComp IS DataBlkInt THEN
  3693. comp := tmpComp;
  3694. ELSIF tmpComp IS DataBlkReal THEN
  3695. (* Need to copy the data *)
  3696. width := compInfo.width;
  3697. height := compInfo.height;
  3698. NEW(dataBlkInt);
  3699. NEW(dataInt, width*height);
  3700. dataBlkInt.offset := 0;
  3701. dataBlkInt.scanw := width;
  3702. dataBlkInt.data := dataInt;
  3703. dataReal := tmpComp(DataBlkReal).data;
  3704. dataIdxReal := tmpComp.offset;
  3705. scanwReal := tmpComp.scanw;
  3706. dataIdxInt := dataBlkInt.offset;
  3707. scanwInt := dataBlkInt.scanw;
  3708. FOR j := 0 TO height - 1 DO
  3709. FOR i := 0 TO width - 1 DO
  3710. (* arithmetic rounding used *)
  3711. dataInt[dataIdxInt] := ENTIER(dataReal[dataIdxReal] + 0.5);
  3712. INC(dataIdxReal);
  3713. INC(dataIdxInt);
  3714. END;
  3715. dataIdxReal := dataIdxReal - width + scanwReal;
  3716. dataIdxInt := dataIdxInt - width + scanwInt;
  3717. END;
  3718. comp := dataBlkInt;
  3719. ELSE
  3720. KernelLog.String("ERROR (InverseMCT.GetAdaptedComponent): Returned data block type not unsupported");
  3721. KernelLog.Ln();
  3722. END;
  3723. END GetAdaptedComponent;
  3724. PROCEDURE GetComponent (component : LONGINT; VAR comp : DataBlk; VAR compInfo : J2KU.BlkInfo);
  3725. BEGIN
  3726. IF (component >= 3) OR (mct = MCT_NONE) THEN
  3727. GetAdaptedComponent(component, comp, compInfo);
  3728. ELSE
  3729. comp := comp012[curTile][component];
  3730. compInfo := comp012Info[curTile][component];
  3731. END;
  3732. END GetComponent;
  3733. PROCEDURE FullTransform () : BOOLEAN;
  3734. BEGIN
  3735. RETURN TransformStep();
  3736. END FullTransform;
  3737. (* Performs 1 transformation step. TransformStep = FullTransform in this implementation *)
  3738. PROCEDURE TransformStep () : BOOLEAN;
  3739. BEGIN
  3740. (* Let the wavelet transformation perform a full reconstruction of the current tile-part *)
  3741. IF ~invDWT.FullTransform() THEN
  3742. RETURN FALSE;
  3743. END;
  3744. IF transformRequired[curTile] OR nonRebuildBuffer THEN
  3745. IF AllTilePartsRead() THEN
  3746. transformRequired[curTile] := FALSE;
  3747. END;
  3748. CASE mct OF
  3749. MCT_NONE :
  3750. (* Don't do anything *)
  3751. RETURN TRUE;
  3752. | MCT_RCT :
  3753. RETURN InverseRCT();
  3754. | MCT_ICT :
  3755. RETURN InverseICT();
  3756. ELSE
  3757. KernelLog.String("ERROR (InverseMCT.TransformStep) : Invalid component transformation specified");
  3758. KernelLog.Ln();
  3759. RETURN FALSE;
  3760. END;
  3761. END;
  3762. RETURN TRUE;
  3763. END TransformStep;
  3764. PROCEDURE InitTile () : BOOLEAN;
  3765. VAR
  3766. ncomp, rev, i : LONGINT;
  3767. imgInfo : J2KCS.ImageInfo;
  3768. BEGIN
  3769. imgInfo := decSpec.GetImageInfo();
  3770. curTile := invDWT.CurrentTile();
  3771. ncomp := imgInfo.GetNumComponents();
  3772. (* Get the information on wether a transformation is used or not *)
  3773. IF (ncomp < 3) OR ~decSpec.CompTransUsed(curTile) THEN
  3774. mct := MCT_NONE;
  3775. RETURN TRUE;
  3776. ELSE
  3777. rev := 0;
  3778. FOR i := 0 TO 2 DO
  3779. IF decSpec.IsReversibleWavTrans(curTile, i) THEN
  3780. INC(rev);
  3781. END;
  3782. END;
  3783. IF rev = 3 THEN
  3784. mct := MCT_RCT;
  3785. ELSIF rev = 0 THEN
  3786. mct := MCT_ICT;
  3787. ELSE
  3788. KernelLog.String("ERROR (InverseMCT.InitTile): First three components of tile ");
  3789. KernelLog.Int(curTile, 0);
  3790. KernelLog.String(" differ in reversibility -> can't perform inverse component transformation");
  3791. KernelLog.Ln();
  3792. mct := -1;
  3793. RETURN FALSE;
  3794. END;
  3795. (* If this is the first tile-part we need to allocate buffers for the first 3 components *)
  3796. IF invDWT.CurrentTilePart() = 0 THEN
  3797. (* We allocate integer blocks because that's what we deliver *)
  3798. FOR i := 0 TO 2 DO
  3799. NEW(comp012[curTile][i]);
  3800. comp012[curTile][i].data := NIL;
  3801. NEW(comp012Info[curTile][i]);
  3802. END;
  3803. END;
  3804. RETURN TRUE;
  3805. END;
  3806. END InitTile;
  3807. PROCEDURE CurrentTile () : LONGINT;
  3808. BEGIN
  3809. RETURN invDWT.CurrentTile();
  3810. END CurrentTile;
  3811. PROCEDURE CurrentTilePart () : LONGINT;
  3812. BEGIN
  3813. RETURN invDWT.CurrentTilePart();
  3814. END CurrentTilePart;
  3815. PROCEDURE NextTilePart () : BOOLEAN;
  3816. BEGIN
  3817. IF ~invDWT.NextTilePart() THEN
  3818. RETURN FALSE;
  3819. END;
  3820. RETURN InitTile();
  3821. END NextTilePart;
  3822. PROCEDURE AllTilePartsRead () : BOOLEAN;
  3823. BEGIN
  3824. RETURN invDWT.AllTilePartsRead();
  3825. END AllTilePartsRead;
  3826. PROCEDURE TilePartAvailable () : BOOLEAN;
  3827. BEGIN
  3828. RETURN invDWT.TilePartAvailable();
  3829. END TilePartAvailable;
  3830. PROCEDURE DataAvailable () : BOOLEAN;
  3831. BEGIN
  3832. RETURN invDWT.DataAvailable();
  3833. END DataAvailable;
  3834. PROCEDURE InverseRCT () : BOOLEAN;
  3835. VAR
  3836. tmpComp : ARRAY 3 OF DataBlk;
  3837. data0, data1, data2, outData0, outData1, outData2 : J2KU.LongIntArrayPtr;
  3838. dataLen, i, j, dataIdxOut, dataIdxIn : LONGINT;
  3839. width, height, scanwOut, scanwIn : LONGINT;
  3840. BEGIN
  3841. (* Get the wavelet transformed components *)
  3842. invDWT.GetComponent(0, tmpComp[0], comp012Info[curTile][0]);
  3843. invDWT.GetComponent(1, tmpComp[1], comp012Info[curTile][1]);
  3844. invDWT.GetComponent(2, tmpComp[2], comp012Info[curTile][2]);
  3845. (* We assume that the data arrays of all components are of equal length *)
  3846. (* If that's not the case, then don't proceed *)
  3847. width := comp012Info[curTile][0].width;
  3848. height := comp012Info[curTile][0].height;
  3849. dataLen := width * height;
  3850. IF (dataLen # (comp012Info[curTile][1].width*comp012Info[curTile][1].height)) OR (dataLen # (comp012Info[curTile][2].width*comp012Info[curTile][2].height)) THEN
  3851. KernelLog.String("ERROR (InverseMCT.InverseRCT) : Transformation of components with different number of samples is not supported");
  3852. KernelLog.Ln();
  3853. RETURN FALSE;
  3854. END;
  3855. data0 := tmpComp[0](DataBlkInt).data;
  3856. data1 := tmpComp[1](DataBlkInt).data;
  3857. data2 := tmpComp[2](DataBlkInt).data;
  3858. outData0 := comp012[curTile][0].data;
  3859. outData1 := comp012[curTile][1].data;
  3860. outData2 := comp012[curTile][2].data;
  3861. (* Allocate space in the internal buffer for each component, if not yet done *)
  3862. (* NOTE:
  3863. If the buffer of component 0 is NIL we assume that no transformation has been done,
  3864. i.e. not before the current procedure call. We allocate the data for the other components
  3865. as well. This is legitimate, if we do this everytime. We would get a problem if we'd only
  3866. instantiate buffer for component 0. But that would mean that we didn't transform the
  3867. other components, which would not make any sense (or would it?).
  3868. *)
  3869. IF (outData0 = NIL) OR (LEN(outData0^) < dataLen) THEN
  3870. NEW(outData0, dataLen);
  3871. NEW(outData1, dataLen);
  3872. NEW(outData2, dataLen);
  3873. comp012[curTile][0].data := outData0;
  3874. comp012[curTile][1].data := outData1;
  3875. comp012[curTile][2].data := outData2;
  3876. comp012[curTile][0].scanw := comp012Info[curTile][0].width;
  3877. comp012[curTile][1].scanw := comp012Info[curTile][1].width;
  3878. comp012[curTile][2].scanw := comp012Info[curTile][2].width;
  3879. comp012[curTile][0].offset := 0;
  3880. comp012[curTile][1].offset := 0;
  3881. comp012[curTile][2].offset := 0;
  3882. END;
  3883. (* Perform the inverse transformation on all samples of each component *)
  3884. dataIdxOut := comp012[curTile][0].offset;
  3885. dataIdxIn := tmpComp[0].offset;
  3886. scanwOut := comp012[curTile][0].scanw;
  3887. scanwIn := tmpComp[0].scanw;
  3888. FOR j := 0 TO height - 1 DO
  3889. FOR i := 0 TO width - 1 DO
  3890. outData1[dataIdxOut] := data0[dataIdxIn] - ASH(data2[dataIdxIn] + data1[dataIdxIn], -2);
  3891. outData0[dataIdxOut] := data2[dataIdxIn] + outData1[dataIdxOut];
  3892. outData2[dataIdxOut] := data1[dataIdxIn] + outData1[dataIdxOut];
  3893. INC(dataIdxOut);
  3894. INC(dataIdxIn);
  3895. END;
  3896. (* Go to next row *)
  3897. dataIdxOut := dataIdxOut - width + scanwOut;
  3898. dataIdxIn := dataIdxIn - width + scanwIn;
  3899. END;
  3900. RETURN TRUE;
  3901. END InverseRCT;
  3902. PROCEDURE InverseICT () : BOOLEAN;
  3903. VAR
  3904. tmpComp : ARRAY 3 OF DataBlk;
  3905. data0, data1, data2 : J2KU.RealArrayPtr;
  3906. outData0, outData1, outData2 : J2KU.LongIntArrayPtr;
  3907. dataLen, i, j, dataIdxOut, dataIdxIn : LONGINT;
  3908. width, height, scanwOut, scanwIn : LONGINT;
  3909. BEGIN
  3910. (* Get the wavelet transformed components *)
  3911. invDWT.GetComponent(0, tmpComp[0], comp012Info[curTile][0]);
  3912. invDWT.GetComponent(1, tmpComp[1], comp012Info[curTile][1]);
  3913. invDWT.GetComponent(2, tmpComp[2], comp012Info[curTile][2]);
  3914. (* We assume that the data arrays of all components are of equal length *)
  3915. (* If that's not the case, then don't proceed *)
  3916. width := comp012Info[curTile][0].width;
  3917. height := comp012Info[curTile][0].height;
  3918. dataLen := width * height;
  3919. IF (dataLen # (comp012Info[curTile][1].width*comp012Info[curTile][1].height)) OR (dataLen # (comp012Info[curTile][2].width*comp012Info[curTile][2].height)) THEN
  3920. KernelLog.String("ERROR (InverseMCT.InverseRCT) : Transformation of components with different number of samples is not supported");
  3921. KernelLog.Ln();
  3922. RETURN FALSE;
  3923. END;
  3924. data0 := tmpComp[0](DataBlkReal).data;
  3925. data1 := tmpComp[1](DataBlkReal).data;
  3926. data2 := tmpComp[2](DataBlkReal).data;
  3927. outData0 := comp012[curTile][0].data;
  3928. outData1 := comp012[curTile][1].data;
  3929. outData2 := comp012[curTile][2].data;
  3930. (* Allocate space in the internal buffer for each component, if not yet done *)
  3931. (* NOTE:
  3932. If the buffer of component 0 is NIL we assume that no transformation has been done,
  3933. i.e. not before the current procedure call. We allocate the data for the other components
  3934. as well. This is legitimate, if we do this everytime. We would get a problem if we'd only
  3935. instantiate buffer for component 0. But that would mean that we didn't transform the
  3936. other components, which would not make any sense (or would it?).
  3937. *)
  3938. IF (outData0 = NIL) OR (LEN(outData0^) < dataLen) THEN
  3939. NEW(outData0, dataLen);
  3940. NEW(outData1, dataLen);
  3941. NEW(outData2, dataLen);
  3942. comp012[curTile][0].data := outData0;
  3943. comp012[curTile][1].data := outData1;
  3944. comp012[curTile][2].data := outData2;
  3945. comp012[curTile][0].scanw := comp012Info[curTile][0].width;
  3946. comp012[curTile][1].scanw := comp012Info[curTile][1].width;
  3947. comp012[curTile][2].scanw := comp012Info[curTile][2].width;
  3948. comp012[curTile][0].offset := 0;
  3949. comp012[curTile][1].offset := 0;
  3950. comp012[curTile][2].offset := 0;
  3951. END;
  3952. (* Perform the inverse transformation on all samples of each component *)
  3953. dataIdxOut := comp012[curTile][0].offset;
  3954. dataIdxIn := tmpComp[0].offset;
  3955. scanwOut := comp012[curTile][0].scanw;
  3956. scanwIn := tmpComp[0].scanw;
  3957. FOR j := 0 TO height - 1 DO
  3958. FOR i := 0 TO width - 1 DO
  3959. (* Use rounding: floor(x+0.5) *)
  3960. outData0[dataIdxOut] := ENTIER(data0[dataIdxIn] + 1.402*data2[dataIdxIn] + 0.5);
  3961. outData1[dataIdxOut] := ENTIER(data0[dataIdxIn] - 0.34413*data1[dataIdxIn] - 0.71414*data2[dataIdxIn] + 0.5);
  3962. outData2[dataIdxOut] := ENTIER(data0[dataIdxIn] + 1.772*data1[dataIdxIn] + 0.5);
  3963. INC(dataIdxOut);
  3964. INC(dataIdxIn);
  3965. END;
  3966. (* Go to next row *)
  3967. dataIdxOut := dataIdxOut - width + scanwOut;
  3968. dataIdxIn := dataIdxIn - width + scanwIn;
  3969. END;
  3970. RETURN TRUE;
  3971. END InverseICT;
  3972. PROCEDURE SetReBuildMode;
  3973. BEGIN
  3974. invDWT.SetReBuildMode();
  3975. END SetReBuildMode;
  3976. PROCEDURE FreeNonRebuildResources;
  3977. VAR
  3978. imgInfo : J2KCS.ImageInfo;
  3979. ntiles, i : LONGINT;
  3980. BEGIN
  3981. imgInfo := decSpec.GetImageInfo();
  3982. ntiles := imgInfo.GetNumTiles();
  3983. IF nonRebuildBuffer THEN
  3984. (* Free components and infos *)
  3985. FOR i := 0 TO ntiles - 1 DO
  3986. IF comp012[i][0] # NIL THEN
  3987. comp012[i][0].data := NIL;
  3988. comp012[i][1].data := NIL;
  3989. comp012[i][2].data := NIL;
  3990. comp012Info[i][0] := NIL;
  3991. comp012Info[i][1] := NIL;
  3992. comp012Info[i][2] := NIL;
  3993. END;
  3994. END;
  3995. END;
  3996. invDWT.FreeNonRebuildResources();
  3997. END FreeNonRebuildResources;
  3998. PROCEDURE FreeResources;
  3999. BEGIN
  4000. comp012 := NIL;
  4001. comp012Info := NIL;
  4002. transformRequired := NIL;
  4003. invDWT.FreeResources();
  4004. END FreeResources;
  4005. END InverseMCT;
  4006. (* --- END Inverse multiple component transformation types --- *)
  4007. (* --- JP2 File Format types --- *)
  4008. (*
  4009. (* This shall be the interface for applications requesting data contained in boxes. 'data' will only contain raw data, but no subboxes *)
  4010. JP2BoxHandler* = PROCEDURE {DELEGATE} (boxType : LONGINT; boxData : J2K.ByteArrayPtr; boxDataLen : HUGEINT; VAR abort : BOOLEAN);
  4011. *)
  4012. JP2Box = OBJECT
  4013. VAR
  4014. type : LONGINT;
  4015. END JP2Box;
  4016. (** Container for a codestream found in a JP2 file *)
  4017. CodestreamBox = OBJECT(JP2Box)
  4018. VAR
  4019. s : Streams.Reader;
  4020. PROCEDURE &InitNew*;
  4021. BEGIN
  4022. type := JP2CCST;
  4023. END InitNew;
  4024. END CodestreamBox;
  4025. TYPE
  4026. JP2FileFormatReader = OBJECT
  4027. VAR
  4028. s : Streams.Reader;
  4029. isJP2 : BOOLEAN;
  4030. initError : BOOLEAN;
  4031. lastBoxFound, jp2HeaderBoxFound : BOOLEAN;
  4032. curBoxType : LONGINT;
  4033. curBoxLen, curBoxContLen : HUGEINT; (* current box length: total & content length *)
  4034. PROCEDURE & InitNew *(s : Streams.Reader);
  4035. BEGIN
  4036. ReInit(s);
  4037. END InitNew;
  4038. PROCEDURE ReInit (s : Streams.Reader);
  4039. VAR
  4040. signature : LONGINT;
  4041. BEGIN
  4042. SELF.s := s;
  4043. (* First we need to check if the stream contains a JP2 file *)
  4044. (* --- JPEG 2000 Signature box --- *)
  4045. (* Check if it's possible that this is a JP2 file -> just peek *)
  4046. (* First byte should be 0x00 *)
  4047. IF ORD(s.Peek()) # 00H THEN
  4048. isJP2 := FALSE;
  4049. lastBoxFound := TRUE;
  4050. initError := FALSE;
  4051. RETURN;
  4052. END;
  4053. (* Now we need to actually read from the stream because we still don't know if it's a JP2 file *)
  4054. (* Read the first 12 bytes. They should be 0x0000 000C 6A50 2020 0D0A 870A *)
  4055. ReadBoxInfo();
  4056. (* --- DBox --- *)
  4057. signature := s.Net32();
  4058. IF (curBoxLen # 12)
  4059. OR (curBoxType # JP2SIGN)
  4060. OR (signature # 0D0A870AH)
  4061. THEN
  4062. isJP2 := FALSE;
  4063. lastBoxFound := TRUE;
  4064. (*
  4065. Issue an error, because we have already read from the stream, and
  4066. there is no JPEG 2000 - Part 1 conforming data anyway.
  4067. *)
  4068. KernelLog.String("ERROR: Not a valid JPEG 2000 - Part 1 file/stream");
  4069. KernelLog.Ln();
  4070. initError := TRUE;
  4071. RETURN;
  4072. END;
  4073. (* The checks till now have convinced us that it's a JP2 file *)
  4074. isJP2 := TRUE;
  4075. lastBoxFound := FALSE;
  4076. jp2HeaderBoxFound := FALSE;
  4077. (* --- File Type box --- *)
  4078. ReadBoxInfo();
  4079. IF curBoxType # JP2FTYP THEN
  4080. KernelLog.String("ERROR (JP2FileFormatReader.ReInit): Invalid box type (read: '");
  4081. KernelLog.Hex(curBoxType, 0);
  4082. KernelLog.String("'; required: '");
  4083. KernelLog.Hex(JP2FTYP, 0);
  4084. KernelLog.String("', i.e. File Type box)");
  4085. KernelLog.Ln();
  4086. initError := TRUE;
  4087. RETURN;
  4088. END;
  4089. initError := ~ReadFileTypeBox();
  4090. END ReInit;
  4091. PROCEDURE InitError () : BOOLEAN;
  4092. BEGIN
  4093. RETURN initError;
  4094. END InitError;
  4095. PROCEDURE IsJP2File () : BOOLEAN;
  4096. BEGIN
  4097. RETURN isJP2;
  4098. END IsJP2File;
  4099. (** Reads box type and length *)
  4100. PROCEDURE ReadBoxInfo;
  4101. VAR
  4102. tmp : LONGINT;
  4103. BEGIN
  4104. (* --- LBox --- *)
  4105. curBoxLen := s.Net32();
  4106. (* --- TBox --- *)
  4107. curBoxType := s.Net32();
  4108. IF curBoxLen = 0 THEN
  4109. curBoxLen := s.Available() + 8;
  4110. curBoxContLen := s.Available();
  4111. lastBoxFound := TRUE;
  4112. ELSIF curBoxLen = 1 THEN
  4113. (* --- XLBox --- *)
  4114. tmp := LSH(s.Net32(), 32);
  4115. curBoxLen := tmp + s.Net32();
  4116. curBoxContLen := curBoxLen - 16;
  4117. ELSE
  4118. curBoxContLen := curBoxLen - 8;
  4119. END;
  4120. END ReadBoxInfo;
  4121. PROCEDURE ReadFileTypeBox () : BOOLEAN;
  4122. VAR
  4123. br, minV : LONGINT;
  4124. clLength : HUGEINT; (* Length of compatibility list (i.e. the number of list entries) *)
  4125. jp2Comp : BOOLEAN;
  4126. BEGIN
  4127. IF ~HasNextBox() THEN
  4128. (* This can not be the last box *)
  4129. KernelLog.String("ERROR (JP2FileFormatReader.ReadFileTypeBox): File Type box is last in file");
  4130. KernelLog.Ln();
  4131. RETURN FALSE;
  4132. END;
  4133. (* --- BR --- *)
  4134. br := s.Net32(); (* NOTE: Unused *)
  4135. (* --- MinV --- *)
  4136. minV := s.Net32(); (* NOTE: Unused *)
  4137. (* --- CLi --- *)
  4138. clLength := LSH(curBoxContLen - 8, -2);
  4139. (* Compatibility list must at least contain 1 element *)
  4140. IF clLength <= 0 THEN
  4141. KernelLog.String("ERROR (JP2FileFormatReader.ReadFileTypeBox): Empty compatibility list");
  4142. KernelLog.Ln();
  4143. RETURN FALSE;
  4144. END;
  4145. (* Check that there is at least one JP2-FTBRAND entry in the compatibility list *)
  4146. jp2Comp := FALSE;
  4147. WHILE clLength > 0 DO
  4148. IF s.Net32() = JP2_FTBRAND THEN
  4149. jp2Comp := TRUE;
  4150. END;
  4151. DEC(clLength);
  4152. END;
  4153. IF ~jp2Comp THEN
  4154. KernelLog.String("ERROR (JP2FileFormatReader.ReadFileTypeBox): Compatibility list does not contain JPEG 2000 - Part 1");
  4155. KernelLog.Ln();
  4156. END;
  4157. RETURN jp2Comp;
  4158. END ReadFileTypeBox;
  4159. PROCEDURE ReadJP2HeaderBox (VAR box : JP2Box) : BOOLEAN;
  4160. VAR
  4161. headerBoxLen, nColSpecBox : HUGEINT;
  4162. ok : BOOLEAN;
  4163. BEGIN
  4164. (* We just skip the header *)
  4165. (*
  4166. Just check that there is an Image Header box and at least 1 Colour Specification box.
  4167. Don't return any content.
  4168. *)
  4169. box := NIL;
  4170. IF ~HasNextBox() THEN
  4171. KernelLog.String("ERROR (JP2FileFormatReader.ReadJP2HeaderBox): JP2 Header box is last box in file");
  4172. KernelLog.Ln();
  4173. RETURN FALSE;
  4174. END;
  4175. headerBoxLen := curBoxContLen;
  4176. (* Read next box *)
  4177. ReadBoxInfo();
  4178. IF curBoxType # JP2IHDR THEN
  4179. KernelLog.String("ERROR (JP2FileFormatReader.ReadJP2HeaderBox): Image Header box not first box in JP2 Header box");
  4180. KernelLog.Ln();
  4181. RETURN FALSE;
  4182. END;
  4183. ok := SkipBox();
  4184. DEC(headerBoxLen, curBoxLen);
  4185. nColSpecBox := 0;
  4186. WHILE ok & (headerBoxLen > 0) DO
  4187. ReadBoxInfo();
  4188. IF curBoxType = JP2BPCC THEN
  4189. (* Nothing to do (yet) *)
  4190. ELSIF curBoxType = JP2COLR THEN
  4191. INC(nColSpecBox);
  4192. ELSIF curBoxType = JP2PCLR THEN
  4193. (* Nothing to do (yet) *)
  4194. ELSIF curBoxType = JP2CMAP THEN
  4195. (* Nothing to do (yet) *)
  4196. ELSIF curBoxType = JP2CDEF THEN
  4197. (* Nothing to do (yet) *)
  4198. ELSIF curBoxType = JP2RESL THEN
  4199. (* Nothing to do (yet) *)
  4200. ELSE
  4201. KernelLog.String("NOTICE: Unknown/unexpected JP2 box type found within JP2 Header box: ");
  4202. KernelLog.Hex(curBoxType, 0);
  4203. KernelLog.Ln();
  4204. END;
  4205. ok := SkipBox();
  4206. DEC(headerBoxLen, curBoxLen);
  4207. END;
  4208. IF ok & (nColSpecBox <= 0) THEN
  4209. KernelLog.String("ERROR (JP2FileFormatReader.ReadJP2HeaderBox): No Colour Specification box found");
  4210. KernelLog.Ln();
  4211. ok := FALSE;
  4212. END;
  4213. RETURN ok;
  4214. END ReadJP2HeaderBox;
  4215. (* TODO: Maybe we should copy the stream *)
  4216. (**
  4217. Just returns a reference to the stream. So it is assumed that the codestream
  4218. will be processed before a the next call to NextBox.
  4219. *)
  4220. PROCEDURE ReadContiguousCodestreamBox (VAR box : JP2Box) : BOOLEAN;
  4221. VAR
  4222. ccBox : CodestreamBox;
  4223. BEGIN
  4224. NEW(ccBox);
  4225. ccBox.s := SELF.s;
  4226. box := ccBox;
  4227. RETURN TRUE;
  4228. END ReadContiguousCodestreamBox;
  4229. PROCEDURE ReadIPRBox (VAR box : JP2Box) : BOOLEAN;
  4230. BEGIN
  4231. (* We just skip this box *)
  4232. box := NIL;
  4233. RETURN SkipBox();
  4234. END ReadIPRBox;
  4235. PROCEDURE ReadXMLBox (VAR box : JP2Box) : BOOLEAN;
  4236. BEGIN
  4237. (* We just skip this box *)
  4238. box := NIL;
  4239. RETURN SkipBox();
  4240. END ReadXMLBox;
  4241. PROCEDURE ReadUUIDBox (VAR box : JP2Box) : BOOLEAN;
  4242. BEGIN
  4243. (* We just skip this box *)
  4244. box := NIL;
  4245. RETURN SkipBox();
  4246. END ReadUUIDBox;
  4247. PROCEDURE ReadUUIDInfoBox (VAR box : JP2Box) : BOOLEAN;
  4248. BEGIN
  4249. (* We just skip this box *)
  4250. box := NIL;
  4251. RETURN SkipBox();
  4252. END ReadUUIDInfoBox;
  4253. PROCEDURE HasNextBox () : BOOLEAN;
  4254. BEGIN
  4255. RETURN ~initError & ~lastBoxFound & (s.Available() >= 8);
  4256. END HasNextBox;
  4257. PROCEDURE NextBox (VAR boxtype : LONGINT; VAR length : HUGEINT) : BOOLEAN;
  4258. BEGIN
  4259. IF ~HasNextBox() THEN
  4260. KernelLog.String("ERROR (JP2FileFormatReader.NextBox): No (more) JP2 boxes available");
  4261. KernelLog.Ln();
  4262. RETURN FALSE;
  4263. END;
  4264. ReadBoxInfo();
  4265. (* Determine box type and check constraints *)
  4266. IF curBoxType = JP2HEAD THEN
  4267. IF jp2HeaderBoxFound THEN
  4268. KernelLog.String("ERROR (JP2FileFormatReader.NextBox): Multiple JP2 Header boxes found");
  4269. KernelLog.Ln();
  4270. RETURN FALSE;
  4271. ELSE
  4272. jp2HeaderBoxFound := TRUE;
  4273. END;
  4274. ELSIF curBoxType = JP2CCST THEN
  4275. IF ~jp2HeaderBoxFound THEN
  4276. KernelLog.String("ERROR (JP2FileFormatReader.NextBox): JP2 Header box not found before Contiguous codestream box");
  4277. KernelLog.Ln();
  4278. RETURN FALSE;
  4279. END;
  4280. ELSIF curBoxType = JP2INPR THEN
  4281. (* No constraints (yet) *)
  4282. ELSIF curBoxType = JP2XMLD THEN
  4283. (* No constraints (yet) *)
  4284. ELSIF curBoxType = JP2UUID THEN
  4285. (* No constraints (yet) *)
  4286. ELSIF curBoxType = JP2UINF THEN
  4287. (* No constraints (yet) *)
  4288. ELSE
  4289. KernelLog.String("NOTICE: Unknown/unexpected JP2 box type found in file: ");
  4290. KernelLog.Hex(curBoxType, 0);
  4291. KernelLog.Ln();
  4292. END;
  4293. boxtype := curBoxType;
  4294. length := curBoxContLen;
  4295. RETURN TRUE;
  4296. END NextBox;
  4297. PROCEDURE GetBoxContent (VAR box : JP2Box) : BOOLEAN;
  4298. BEGIN
  4299. (* Determine box type and check constraints *)
  4300. IF curBoxType = JP2HEAD THEN
  4301. RETURN ReadJP2HeaderBox(box);
  4302. ELSIF curBoxType = JP2CCST THEN
  4303. RETURN ReadContiguousCodestreamBox(box);
  4304. ELSIF curBoxType = JP2INPR THEN
  4305. RETURN ReadIPRBox(box);
  4306. ELSIF curBoxType = JP2XMLD THEN
  4307. RETURN ReadXMLBox(box);
  4308. ELSIF curBoxType = JP2UUID THEN
  4309. RETURN ReadUUIDBox(box);
  4310. ELSIF curBoxType = JP2UINF THEN
  4311. RETURN ReadUUIDInfoBox(box);
  4312. ELSE
  4313. (* Unknown box -> skip it *)
  4314. box := NIL;
  4315. RETURN SkipBox();
  4316. END;
  4317. END GetBoxContent;
  4318. PROCEDURE SkipBox () : BOOLEAN;
  4319. BEGIN
  4320. WHILE curBoxContLen > MAX(LONGINT) DO
  4321. s.SkipBytes(MAX(LONGINT));
  4322. DEC(curBoxContLen, MAX(LONGINT));
  4323. END;
  4324. s.SkipBytes(SHORT(curBoxContLen));
  4325. RETURN TRUE;
  4326. END SkipBox;
  4327. (**
  4328. Gets the (first) codestream embedded in the file, if any, and ignores
  4329. all other boxes (i.e. skips them). When soon as the first codestream is
  4330. found this method returns (or NIL if no codestream was found).
  4331. NOTE:
  4332. This method delivers a reference to its own stream object (i.e. the stream
  4333. object to which a reference was given at construction time of this JP2FileFormatReader).
  4334. So it's possible that at the end of a codestream some other data is appended,
  4335. i.e. the remainder of the file.
  4336. *)
  4337. PROCEDURE GetCodestream () : Streams.Reader;
  4338. VAR
  4339. s : Streams.Reader;
  4340. noCodestream : BOOLEAN;
  4341. box : JP2Box;
  4342. boxType : LONGINT;
  4343. boxLen : HUGEINT;
  4344. BEGIN
  4345. s := NIL;
  4346. noCodestream := TRUE;
  4347. WHILE noCodestream & HasNextBox() DO
  4348. IF ~NextBox(boxType, boxLen) THEN
  4349. (* Return on error *)
  4350. RETURN NIL;
  4351. END;
  4352. IF boxType = JP2CCST THEN
  4353. (* Codestream found *)
  4354. noCodestream := FALSE;
  4355. IF GetBoxContent(box) THEN
  4356. ASSERT(box.type = boxType);
  4357. s := box(CodestreamBox).s;
  4358. END;
  4359. ELSE
  4360. (* Skip the box *)
  4361. IF ~SkipBox() THEN
  4362. (* Return on error *)
  4363. RETURN NIL;
  4364. END;
  4365. END;
  4366. END;
  4367. IF noCodestream THEN
  4368. KernelLog.String("ERROR (JP2FileFormatReader.GetCodestream): No codestream found");
  4369. KernelLog.Ln();
  4370. END;
  4371. RETURN s;
  4372. END GetCodestream;
  4373. PROCEDURE FreeResources;
  4374. BEGIN
  4375. s := NIL;
  4376. END FreeResources;
  4377. END JP2FileFormatReader;
  4378. (* --- END JP2 File Format types --- *)
  4379. CONST
  4380. (** Image production status values (so that image consumers may be informed) *)
  4381. PROD_FAILED* = -1;
  4382. PROD_DONE* = 1;
  4383. TYPE
  4384. (**
  4385. Interface for image consumers
  4386. *)
  4387. ImageConsumer* = OBJECT
  4388. (** Set specific pixels *)
  4389. PROCEDURE SetPixels*(pixelData : J2KU.LongIntArrayPtr; xOffset, yOffset, width, height : LONGINT);
  4390. END SetPixels;
  4391. (** Called by image producer to inform about production status *)
  4392. PROCEDURE SetProductionStatus* (status : LONGINT);
  4393. END SetProductionStatus;
  4394. END ImageConsumer;
  4395. ImageProducer = OBJECT
  4396. VAR
  4397. imgFmt : LONGINT;
  4398. src : InverseMCT;
  4399. producedOnce : BOOLEAN;
  4400. imgInfo : J2KCS.ImageInfo;
  4401. PROCEDURE &InitNew*;
  4402. BEGIN
  4403. src := NIL;
  4404. imgFmt := -1;
  4405. END InitNew;
  4406. (* Initializes the image production (determines format & does some checks) *)
  4407. PROCEDURE InitProduction (src : InverseMCT; imgInfo : J2KCS.ImageInfo) : BOOLEAN;
  4408. VAR
  4409. ncomp : LONGINT;
  4410. imgWidth, imgHeight, i : LONGINT;
  4411. compWidth, compHeight : LONGINT;
  4412. BEGIN
  4413. producedOnce := FALSE;
  4414. SELF.src := src;
  4415. SELF.imgInfo := imgInfo;
  4416. ncomp := imgInfo.GetNumComponents();
  4417. (* Determine basic image type *)
  4418. CASE ncomp OF
  4419. 1 :
  4420. imgFmt := Codecs.ImgFmtGrey;
  4421. | 3:
  4422. imgFmt := Codecs.ImgFmtRGB;
  4423. |
  4424. 4:
  4425. imgFmt := Codecs.ImgFmtRGBA;
  4426. ELSE
  4427. imgFmt := -1;
  4428. KernelLog.String("ERROR (ImageProducer.InitProduction) : Only 1, 3 and 4 components supported currently");
  4429. KernelLog.Ln();
  4430. RETURN FALSE;
  4431. END;
  4432. (* Get image heigth and width *)
  4433. imgWidth := imgInfo.GetImgWidth(0);
  4434. imgHeight := imgInfo.GetImgHeight(0);
  4435. (* Check component sizes and bit-depths *)
  4436. FOR i := 0 TO ncomp - 1 DO
  4437. compWidth := imgInfo.GetCompImgWidth(i, 0);
  4438. compHeight := imgInfo.GetCompImgHeight(i, 0);
  4439. IF (compWidth # imgWidth) OR (compHeight # imgHeight) THEN
  4440. KernelLog.String("ERROR (ImageProducer.InitProduction) : Component subsampling not supported (yet)");
  4441. KernelLog.Ln();
  4442. RETURN FALSE;
  4443. ELSIF imgInfo.GetBitDepth(i) > 8 THEN
  4444. KernelLog.String("ERROR (ImageProducer.InitProduction) : Component bit-depths greater than 8 bits not supported (yet)");
  4445. KernelLog.Ln();
  4446. RETURN FALSE;
  4447. END;
  4448. END;
  4449. RETURN TRUE;
  4450. END InitProduction;
  4451. (* Delivers the image to the image consumers *)
  4452. PROCEDURE ProduceImage (VAR consumers : ARRAY OF ImageConsumer; offset, nconsumer : LONGINT);
  4453. VAR
  4454. ok : BOOLEAN;
  4455. comp : ARRAY 4 OF DataBlkInt; (* References to the components *)
  4456. compInfo : ARRAY 4 OF J2KU.BlkInfo;
  4457. data : ARRAY 4 OF J2KU.LongIntArrayPtr;
  4458. maxVal0, maxVal1, maxVal2, maxVal3 : LONGINT; (* The maximum value of each component sample *)
  4459. levShift0, levShift1, levShift2, levShift3 : LONGINT; (* The value for the DC level shifting for each component *)
  4460. tmp, tmp0, tmp1, tmp2, tmp3 : LONGINT;
  4461. tileOffX, tileOffY : LONGINT;
  4462. width, height : LONGINT;
  4463. lineBuf : J2KU.LongIntArrayPtr;
  4464. ncomp : LONGINT;
  4465. t, c, i, w, h : LONGINT;
  4466. pos, scanw, rowWrap : LONGINT;
  4467. tmpBlk : DataBlk;
  4468. dummy, curDecLvl : LONGINT;
  4469. status : LONGINT;
  4470. BEGIN
  4471. status := PROD_FAILED;
  4472. ncomp := 0;
  4473. (* Get the maximum value of each component and the level shift *)
  4474. CASE imgFmt OF
  4475. Codecs.ImgFmtGrey :
  4476. tmp := imgInfo.GetBitDepth(0); (* This returns the original component bit-depth, before any transformation has been done *)
  4477. maxVal0 := LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
  4478. levShift0 := LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
  4479. ncomp := 1;
  4480. | Codecs.ImgFmtRGB :
  4481. tmp := imgInfo.GetBitDepth(0); (* This returns the original component bit-depth, before any transformation has been done *)
  4482. maxVal0 := LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
  4483. levShift0 := LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
  4484. tmp := imgInfo.GetBitDepth(1);
  4485. maxVal1 := LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
  4486. levShift1 := LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
  4487. tmp := imgInfo.GetBitDepth(2);
  4488. maxVal2 := LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
  4489. levShift2 := LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
  4490. ncomp := 3;
  4491. | Codecs.ImgFmtRGBA :
  4492. tmp := imgInfo.GetBitDepth(0); (* This returns the original component bit-depth, before any transformation has been done *)
  4493. maxVal0 := LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
  4494. levShift0 := LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
  4495. tmp := imgInfo.GetBitDepth(1);
  4496. maxVal1 := LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
  4497. levShift1 := LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
  4498. tmp := imgInfo.GetBitDepth(2);
  4499. maxVal2 := LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
  4500. levShift2 := LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
  4501. tmp := imgInfo.GetBitDepth(3);
  4502. maxVal3 := LSH(SYSTEM.VAL(LONGINT, 1), tmp) - 1;
  4503. levShift3 := LSH(SYSTEM.VAL(LONGINT, 1), tmp - 1);
  4504. ncomp := 4;
  4505. ELSE
  4506. KernelLog.String("ERROR (ImageProducer.ProduceImage) : Invalid image format encounterd");
  4507. KernelLog.Ln();
  4508. (* Inform image consumers *)
  4509. FOR i := offset TO (offset + nconsumer - 1) DO
  4510. consumers[i].SetProductionStatus(status);
  4511. END;
  4512. RETURN;
  4513. END;
  4514. IF producedOnce THEN
  4515. src.SetReBuildMode();
  4516. END;
  4517. (* We let the source process the entire codestream *)
  4518. LOOP
  4519. ok := src.NextTilePart();
  4520. IF ~ok THEN
  4521. IF ~src.DataAvailable() THEN
  4522. status := PROD_DONE;
  4523. END;
  4524. EXIT;
  4525. END;
  4526. ok := src.FullTransform();
  4527. IF ok THEN
  4528. (* The transformation has succeeded and the components should now be ready *)
  4529. t := src.CurrentTile();
  4530. FOR c := 0 TO ncomp - 1 DO
  4531. src.GetComponent(c, tmpBlk, compInfo[c]);
  4532. comp[c] := tmpBlk(DataBlkInt);
  4533. data[c] := comp[c].data;
  4534. END;
  4535. src.GetDecLevelRange(dummy, curDecLvl);
  4536. width := compInfo[0].width;
  4537. height := compInfo[0].height;
  4538. tileOffX := compInfo[0].ulx - imgInfo.GetImgULX(curDecLvl);
  4539. tileOffY := compInfo[0].uly - imgInfo.GetImgULY(curDecLvl);
  4540. NEW(lineBuf, width);
  4541. (*
  4542. NOTE: We assume the same scan width for all components.
  4543. This is reasonable, since we don't allow any component subsampling (yet),
  4544. and we may assume that all components (in terms of data structure and memory
  4545. allocation) are all treated the same way by the data source.
  4546. *)
  4547. scanw := comp[0].scanw;
  4548. pos := comp[0].offset;
  4549. rowWrap := scanw - width;
  4550. FOR h := 0 TO height - 1 DO
  4551. CASE imgFmt OF
  4552. | Codecs.ImgFmtGrey :
  4553. FOR w := 0 TO width - 1 DO
  4554. tmp0 := data[0][pos] + levShift0;
  4555. IF tmp0 > maxVal0 THEN
  4556. tmp0 := maxVal0;
  4557. ELSIF tmp0 < 0 THEN
  4558. tmp0 := 0;
  4559. END;
  4560. lineBuf[w] := SYSTEM.VAL(LONGINT,
  4561. SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 000000FFH), 24))
  4562. + SYSTEM.VAL(SET, LSH(tmp0, 16))
  4563. + SYSTEM.VAL(SET, LSH(tmp0, 8))
  4564. + SYSTEM.VAL(SET, tmp0));
  4565. INC(pos);
  4566. END;
  4567. INC(pos, rowWrap);
  4568. | Codecs.ImgFmtRGB :
  4569. FOR w := 0 TO width - 1 DO
  4570. tmp0 := data[0][pos] + levShift0;
  4571. tmp1 := data[1][pos] + levShift1;
  4572. tmp2 := data[2][pos] + levShift2;
  4573. IF tmp0 > maxVal0 THEN
  4574. tmp0 := maxVal0;
  4575. ELSIF tmp0 < 0 THEN
  4576. tmp0 := 0;
  4577. END;
  4578. IF tmp1 > maxVal1 THEN
  4579. tmp1 := maxVal1;
  4580. ELSIF tmp1 < 0 THEN
  4581. tmp1 := 0;
  4582. END;
  4583. IF tmp2 > maxVal2 THEN
  4584. tmp2 := maxVal2;
  4585. ELSIF tmp2 < 0 THEN
  4586. tmp2 := 0;
  4587. END;
  4588. lineBuf[w] := SYSTEM.VAL(LONGINT,
  4589. SYSTEM.VAL(SET, LSH(SYSTEM.VAL(LONGINT, 000000FFH), 24))
  4590. + SYSTEM.VAL(SET, LSH(tmp0, 16))
  4591. + SYSTEM.VAL(SET, LSH(tmp1, 8))
  4592. + SYSTEM.VAL(SET, tmp2));
  4593. INC(pos);
  4594. END;
  4595. INC(pos, rowWrap);
  4596. | Codecs.ImgFmtRGBA :
  4597. FOR w := 0 TO width - 1 DO
  4598. tmp0 := data[0][pos] + levShift0;
  4599. tmp1 := data[1][pos] + levShift1;
  4600. tmp2 := data[2][pos] + levShift2;
  4601. tmp3 := data[3][pos] + levShift3;
  4602. IF tmp0 > maxVal0 THEN
  4603. tmp0 := maxVal0;
  4604. ELSIF tmp0 < 0 THEN
  4605. tmp0 := 0;
  4606. END;
  4607. IF tmp1 > maxVal1 THEN
  4608. tmp1 := maxVal1;
  4609. ELSIF tmp1 < 0 THEN
  4610. tmp1 := 0;
  4611. END;
  4612. IF tmp2 > maxVal2 THEN
  4613. tmp2 := maxVal2;
  4614. ELSIF tmp2 < 0 THEN
  4615. tmp2 := 0;
  4616. END;
  4617. IF tmp3 > maxVal3 THEN
  4618. tmp3 := maxVal3;
  4619. ELSIF tmp3 < 0 THEN
  4620. tmp3 := 0;
  4621. END;
  4622. lineBuf[w] := SYSTEM.VAL(LONGINT,
  4623. SYSTEM.VAL(SET, LSH(tmp0, 24))
  4624. + SYSTEM.VAL(SET, LSH(tmp1, 16))
  4625. + SYSTEM.VAL(SET, LSH(tmp2, 8))
  4626. + SYSTEM.VAL(SET, tmp3));
  4627. INC(pos);
  4628. END;
  4629. INC(pos, rowWrap);
  4630. END; (* NOTE: No "ELSE" case needed here since we already checked above *)
  4631. FOR i := offset TO (offset + nconsumer - 1) DO
  4632. consumers[i].SetPixels(lineBuf, tileOffX, tileOffY + h, width, 1);
  4633. END;
  4634. END;
  4635. ELSE
  4636. (* Transformation failed -> abort *)
  4637. status := PROD_FAILED;
  4638. EXIT;
  4639. END;
  4640. END;
  4641. IF ~producedOnce THEN
  4642. producedOnce := TRUE;
  4643. src.FreeNonRebuildResources();
  4644. END;
  4645. (* Inform image consumers *)
  4646. FOR i := offset TO (offset + nconsumer - 1) DO
  4647. consumers[i].SetProductionStatus(status);
  4648. END;
  4649. END ProduceImage;
  4650. PROCEDURE GetImgFormat () : LONGINT;
  4651. BEGIN
  4652. RETURN imgFmt;
  4653. END GetImgFormat;
  4654. END ImageProducer;
  4655. InternalToRaster = PROCEDURE {DELEGATE} (pixelBuf : J2KU.LongIntArrayPtr; xOffset, yOffset, length : LONGINT);
  4656. (* An adapter for Raster.Image *)
  4657. RasterImageAdapter* = OBJECT(ImageConsumer)
  4658. VAR
  4659. img : Raster.Image;
  4660. imgFmt : LONGINT;
  4661. transform : InternalToRaster;
  4662. PROCEDURE &InitNew* (img : Raster.Image);
  4663. BEGIN
  4664. SELF.img := img;
  4665. CASE img.fmt.code OF
  4666. | Raster.bgr565 :
  4667. transform := SetPixelsRGB565;
  4668. | Raster.bgr888 :
  4669. transform := SetPixelsRGB888;
  4670. | Raster.bgra8888 :
  4671. transform := SetPixelsRGBA8888;
  4672. ELSE
  4673. KernelLog.String("ERROR: Raster image type ");
  4674. KernelLog.Int(img.fmt.code, 0);
  4675. KernelLog.String(" not supported (yet)");
  4676. KernelLog.Ln();
  4677. transform := SetPixelsNIL;
  4678. END;
  4679. END InitNew;
  4680. PROCEDURE SetFormat* (fmt : LONGINT);
  4681. BEGIN
  4682. imgFmt := fmt;
  4683. END SetFormat;
  4684. PROCEDURE SetPixels*(pixelData : J2KU.LongIntArrayPtr; xOffset, yOffset, width, height : LONGINT);
  4685. VAR
  4686. len : LONGINT;
  4687. BEGIN
  4688. len := width * height;
  4689. transform(pixelData, xOffset, yOffset, len);
  4690. END SetPixels;
  4691. PROCEDURE SetPixelsRGB565 (pixelBuf : J2KU.LongIntArrayPtr; xOffset, yOffset, length : LONGINT);
  4692. VAR
  4693. adr: ADDRESS; int, i : LONGINT;
  4694. r, g, b : LONGINT;
  4695. BEGIN
  4696. adr := img.adr + (img.width*yOffset + xOffset)*2;
  4697. FOR i := 0 TO length - 1 DO
  4698. IF (SYSTEM.VAL(SET, LSH(pixelBuf[i], -24)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 000000FFH) ))# {} THEN (* model alpha as brightness *)
  4699. r := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET,LSH(pixelBuf[i], -16)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 000000FFH)));
  4700. g := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET,LSH(pixelBuf[i], -8)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 000000FFH)));
  4701. b := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, pixelBuf[i]) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 000000FFH)));
  4702. int := LSH(b, -3) + LSH(LSH(g, -2), 5) + LSH(LSH(r, -3), 11);
  4703. SYSTEM.PUT(adr, CHR(int)); SYSTEM.PUT(adr+1, CHR(LSH(int, -8)));
  4704. END;
  4705. INC(adr, 2);
  4706. END;
  4707. END SetPixelsRGB565;
  4708. PROCEDURE SetPixelsRGB888 (pixelBuf : J2KU.LongIntArrayPtr; xOffset, yOffset, length : LONGINT);
  4709. VAR
  4710. adr: ADDRESS; i : LONGINT;
  4711. BEGIN
  4712. adr := img.adr + (img.width*yOffset + xOffset)*3;
  4713. FOR i := 0 TO length - 1 DO
  4714. IF (SYSTEM.VAL(SET, pixelBuf[i]) * {23..31}) # {} THEN (* model alpha as brightness *)
  4715. SYSTEM.PUT(adr, CHR(pixelBuf[i]));
  4716. SYSTEM.PUT(adr + 1, CHR(LSH(pixelBuf[i], -8)));
  4717. SYSTEM.PUT(adr + 2, CHR(LSH(pixelBuf[i], -16)));
  4718. END;
  4719. INC(adr, 3);
  4720. END;
  4721. END SetPixelsRGB888;
  4722. PROCEDURE SetPixelsRGBA8888 (pixelBuf : J2KU.LongIntArrayPtr; xOffset, yOffset, length : LONGINT);
  4723. VAR
  4724. adr: ADDRESS; i : LONGINT;
  4725. BEGIN
  4726. adr := img.adr + (img.width*yOffset + xOffset)*4;
  4727. FOR i := 0 TO length - 1 DO
  4728. SYSTEM.PUT(adr, CHR(pixelBuf[i]));
  4729. SYSTEM.PUT(adr + 1, CHR(LSH(pixelBuf[i], -8)));
  4730. SYSTEM.PUT(adr + 2, CHR(LSH(pixelBuf[i], -16)));
  4731. SYSTEM.PUT(adr + 3, CHR(LSH(pixelBuf[i], -24)));
  4732. INC(adr, 4);
  4733. END;
  4734. END SetPixelsRGBA8888;
  4735. (** NIL handler *)
  4736. PROCEDURE SetPixelsNIL (pixelBuf : J2KU.LongIntArrayPtr; xOffset, yOffset, length : LONGINT);
  4737. (* Don't do anything *)
  4738. END SetPixelsNIL;
  4739. END RasterImageAdapter;
  4740. (* --- Decoder types --- *)
  4741. Decoder* = OBJECT(Codecs.ImageDecoder);
  4742. VAR
  4743. decOpt : J2KU.DecoderOptions;
  4744. decSpec : J2KCS.DecoderSpecs;
  4745. fr : JP2FileFormatReader;
  4746. cr : J2KCS.CodestreamReader;
  4747. ed : EntropyDecoder;
  4748. roi : ROIDescaler;
  4749. deq : Dequantizer;
  4750. invDWT : InverseDWT;
  4751. invMCT : InverseMCT;
  4752. imgProd : ImageProducer;
  4753. ready : BOOLEAN;
  4754. deliveredOnce : BOOLEAN; (* Indicates if the current (open) image stream has been reconstructed (delivered) at least once *)
  4755. minResDec, minLayDec : LONGINT;
  4756. PROCEDURE &InitNew* (decOpt : J2KU.DecoderOptions);
  4757. BEGIN
  4758. SELF.decOpt := decOpt;
  4759. ready := FALSE;
  4760. END InitNew;
  4761. (* --- Codecs.ImageDecoder methods --- *)
  4762. (* open the decoder on a file *)
  4763. PROCEDURE Open*(s : Streams.Reader; VAR res : LONGINT);
  4764. VAR
  4765. imgInfo : J2KCS.ImageInfo;
  4766. buffCr : J2KCS.BufferedCodestreamReader;
  4767. BEGIN
  4768. (* Instantiate decoder chain *)
  4769. IF fr = NIL THEN
  4770. NEW(fr, s);
  4771. IF ~fr.InitError() THEN
  4772. IF fr.IsJP2File() THEN
  4773. s := fr.GetCodestream();
  4774. END;
  4775. IF s # NIL THEN
  4776. IF decOpt.crOpt.component = J2KCS.BUF_CODESTREAM_READER THEN
  4777. NEW(buffCr, decOpt.crOpt, s);
  4778. cr := buffCr;
  4779. ELSE
  4780. NEW(cr, decOpt.crOpt, s);
  4781. END;
  4782. IF ~cr.InitError() THEN
  4783. decSpec := cr.GetDecoderSpecs();
  4784. imgInfo := decSpec.GetImageInfo();
  4785. NEW(ed, decOpt.edOpt, cr, decSpec);
  4786. NEW(roi, decOpt.roiOpt, ed, decSpec);
  4787. NEW(deq, decOpt.deqOpt, roi, decSpec);
  4788. NEW(invDWT, decOpt.invDWTOpt, deq, decSpec);
  4789. NEW(invMCT, decOpt.invMCTOpt, invDWT, decSpec);
  4790. NEW(imgProd);
  4791. ready := imgProd.InitProduction(invMCT, imgInfo);
  4792. END;
  4793. END;
  4794. END;
  4795. ELSE
  4796. fr.ReInit(s);
  4797. IF ~fr.InitError() THEN
  4798. IF fr.IsJP2File() THEN
  4799. s := fr.GetCodestream();
  4800. END;
  4801. IF s # NIL THEN
  4802. cr.ReInit(decOpt.crOpt, s);
  4803. IF ~cr.InitError() THEN
  4804. decSpec := cr.GetDecoderSpecs();
  4805. imgInfo := decSpec.GetImageInfo();
  4806. ed.ReInit(decOpt.edOpt, cr, decSpec);
  4807. roi.ReInit(decOpt.roiOpt, ed, decSpec);
  4808. deq.ReInit(decOpt.deqOpt, roi, decSpec);
  4809. invDWT.ReInit(decOpt.invDWTOpt, deq, decSpec);
  4810. invMCT.ReInit(decOpt.invMCTOpt, invDWT, decSpec);
  4811. ready := imgProd.InitProduction(invMCT, imgInfo);
  4812. END;
  4813. END;
  4814. END;
  4815. END;
  4816. minResDec := 0;
  4817. minLayDec := 0;
  4818. deliveredOnce := FALSE;
  4819. IF ready THEN
  4820. res := Codecs.ResOk;
  4821. ELSE
  4822. res := Codecs.ResFailed;
  4823. END;
  4824. END Open;
  4825. PROCEDURE GetImageInfo*(VAR width, height, format, maxProgressionLevel : LONGINT);
  4826. VAR
  4827. imgInfo : J2KCS.ImageInfo;
  4828. BEGIN
  4829. IF ready THEN
  4830. imgInfo := decSpec.GetImageInfo();
  4831. width := imgInfo.GetImgWidth(0);
  4832. height := imgInfo.GetImgHeight(0);
  4833. format := imgProd.GetImgFormat();
  4834. maxProgressionLevel := decSpec.GetMinNumLayers() - 1;
  4835. END;
  4836. END GetImageInfo;
  4837. (** Render will read and decode the image data up to progrssionLevel.
  4838. If the progressionLevel is lower than a previously rendered progressionLevel,
  4839. the new level can be ignored by the decoder. If no progressionLevel is set with
  4840. SetProgressionLevel, the level is assumed to be maxProgressionLevel of the image,
  4841. which corresponds to best image quality.
  4842. *)
  4843. PROCEDURE SetProgressionLevel*(progressionLevel: LONGINT);
  4844. VAR
  4845. dec : LONGINT;
  4846. BEGIN
  4847. IF ready THEN
  4848. (* Set image quality in terms of layers *)
  4849. dec := decSpec.GetMinNumLayers() - progressionLevel - 1;
  4850. DecreaseNumLayers(dec);
  4851. END;
  4852. END SetProgressionLevel;
  4853. (** renders the image into the given Raster.Image at the given progressionLevel *)
  4854. PROCEDURE Render*(img : Raster.Image);
  4855. VAR
  4856. imgConsumerArr : ARRAY 1 OF ImageConsumer;
  4857. imgAdapt : RasterImageAdapter;
  4858. BEGIN
  4859. IF ready THEN
  4860. NEW(imgAdapt, img);
  4861. imgConsumerArr[0] := imgAdapt;
  4862. imgProd.ProduceImage(imgConsumerArr, 0, 1);
  4863. deliveredOnce := TRUE;
  4864. ELSE
  4865. KernelLog.String("ERROR (Decoder.Render) : Cannot render image because initializing image production failed");
  4866. KernelLog.Ln();
  4867. END;
  4868. END Render;
  4869. (* --- END Codecs.ImageDecoder methods --- *)
  4870. PROCEDURE DeliverImage* (VAR consumers : ARRAY OF ImageConsumer; offset, nconsumer : LONGINT);
  4871. BEGIN
  4872. IF ready THEN
  4873. imgProd.ProduceImage(consumers, offset, nconsumer);
  4874. deliveredOnce := TRUE;
  4875. ELSE
  4876. KernelLog.String("ERROR (Decoder.DeliverImage) : Cannot deliver image because initializing image production failed");
  4877. KernelLog.Ln();
  4878. END;
  4879. END DeliverImage;
  4880. (**
  4881. Closes the input stream. All information on the image gets lost when this procedure is called.
  4882. *)
  4883. PROCEDURE CloseStream*;
  4884. BEGIN
  4885. (* Release resources *)
  4886. decSpec := NIL;
  4887. fr.FreeResources();
  4888. cr.FreeResources();
  4889. ed.FreeResources();
  4890. roi.FreeResources();
  4891. deq.FreeResources();
  4892. invDWT.FreeResources();
  4893. invMCT.FreeResources();
  4894. ready := FALSE;
  4895. END CloseStream;
  4896. (**
  4897. Gets the maximum resolution level of the image. The maximum value
  4898. is equal to the miniumum number of decomposition levels over all
  4899. (tile-) components. The lowest possible value is 0. If the decoder is
  4900. not ready or the stream is corrupted, -1 is returned.
  4901. NOTE:
  4902. The return value is equal to the maximum resolution level known at
  4903. the current stage of decoding, e.g. calling this procedure after opening
  4904. the decoder on a valid stream will return the maximum resolution level
  4905. as indicated by the main header. However this may change if for example
  4906. in a tile-header read later the minimum decomposition level over the
  4907. tile's components is lower than the minimum known that far.
  4908. *)
  4909. PROCEDURE GetNumResolutionLevels* () : LONGINT;
  4910. BEGIN
  4911. IF ready THEN
  4912. RETURN decSpec.GetImgMinDecLevels() + 1;
  4913. ELSE
  4914. RETURN 0;
  4915. END;
  4916. END GetNumResolutionLevels;
  4917. (**
  4918. Sets by how much the original resolution of the image shall be decreased at minimum.
  4919. The given parameter is an exponent. It indicates that
  4920. <image width at decreased resolution> := <orginal image width> / (2^<exponent>)
  4921. <image height at decreased resolution> := <orginal image height> / (2^<exponent>)
  4922. If the image resolution cannot be decreased by that much, then it won't be reconstructed.
  4923. NOTE: This procedure shall NOT be called after the image has been rendered/delivered once.
  4924. This procedure can be used to save some memory.
  4925. *)
  4926. PROCEDURE MinDecreaseResolutionLevel* (minResDec : LONGINT);
  4927. VAR
  4928. ndec, curStartLvl, curEndLvl : LONGINT;
  4929. BEGIN
  4930. IF ready THEN
  4931. IF ~deliveredOnce THEN
  4932. ndec := decSpec.GetImgMinDecLevels();
  4933. IF minResDec < 0 THEN
  4934. SELF.minResDec := 0;
  4935. ELSIF minResDec <= ndec THEN
  4936. SELF.minResDec := minResDec;
  4937. ELSE
  4938. KernelLog.String("WARNING (Decoder.MinDecreaseResolutionLevel): ");
  4939. KernelLog.String("Cannot decrease resolution level by ");
  4940. KernelLog.Int(minResDec, 0);
  4941. KernelLog.String(". Image has only ");
  4942. KernelLog.Int(ndec + 1, 0);
  4943. KernelLog.String(" resolution levels.");
  4944. KernelLog.Ln();
  4945. SELF.minResDec := ndec;
  4946. END;
  4947. invMCT.SetMaxDecLevelRange(MAX(LONGINT), SELF.minResDec);
  4948. (*
  4949. If the new maximum end decomposition level is higher than the current
  4950. end decomposition level, we need to lower the end decomposition level.
  4951. *)
  4952. invMCT.GetDecLevelRange(curStartLvl, curEndLvl);
  4953. IF curEndLvl < SELF.minResDec THEN
  4954. invMCT.SetDecLevelRange(curStartLvl, SELF.minResDec);
  4955. END;
  4956. ELSE
  4957. KernelLog.String("WARNING (Decoder.MinDecreaseResolutionLevel): ");
  4958. KernelLog.String("Procedure called after first image reconstruction -> won't change current value");
  4959. KernelLog.Ln();
  4960. END;
  4961. END;
  4962. END MinDecreaseResolutionLevel;
  4963. (**
  4964. Decreases the original resolution of the image. The given parameter is an
  4965. exponent. It indicates that
  4966. <image width at decreased resolution> := <orginal image width> / (2^<exponent>)
  4967. <image height at decreased resolution> := <orginal image height> / (2^<exponent>)
  4968. NOTE:
  4969. It is possible that the resolution level cannot be decreased by resDec, i.e. when a tile
  4970. does not exist in a that small resolution. Then the image may be reconstructed at the
  4971. next higher possible resolution level, if that resolution level does not violate
  4972. the minimum decrease in resolution levels (see MinDecreaseResolutionLevel).
  4973. *)
  4974. PROCEDURE DecreaseResolutionLevel* (resDec : LONGINT);
  4975. VAR
  4976. ndec, dec : LONGINT;
  4977. BEGIN
  4978. IF ready THEN
  4979. ndec := decSpec.GetImgMinDecLevels();
  4980. IF resDec < minResDec THEN
  4981. KernelLog.String("WARNING (Decoder.DecreaseResolutionLevel): ");
  4982. KernelLog.String("Cannot decrease resolution level only by ");
  4983. KernelLog.Int(resDec, 0);
  4984. KernelLog.String(". Res. level has to be decreased by at least ");
  4985. KernelLog.Int(minResDec, 0);
  4986. KernelLog.String(".");
  4987. KernelLog.Ln();
  4988. dec := minResDec;
  4989. ELSIF resDec <= ndec THEN
  4990. dec := resDec;
  4991. ELSE
  4992. KernelLog.String("WARNING (Decoder.DecreaseResolutionLevel): ");
  4993. KernelLog.String("Cannot decrease resolution level by ");
  4994. KernelLog.Int(resDec, 0);
  4995. KernelLog.String(". Image has only ");
  4996. KernelLog.Int(ndec + 1, 0);
  4997. KernelLog.String(" resolution levels.");
  4998. KernelLog.Ln();
  4999. dec := ndec;
  5000. END;
  5001. (* We always start building from the lowest possible decomposition level *)
  5002. invMCT.SetDecLevelRange(MAX(LONGINT), dec);
  5003. END;
  5004. END DecreaseResolutionLevel;
  5005. (**
  5006. This procedure is meant to be called after a first image rendering.
  5007. It then provides the the decomposition level at which the image got
  5008. rendered (not the requested decomposition level, since a it's possible
  5009. that a rebuild had to be performed, e.g. when the image, that is a tile
  5010. of the image, did not have the requested decomposition level)
  5011. *)
  5012. PROCEDURE GetCurrentDecompositionLevel* () : LONGINT;
  5013. VAR
  5014. decLvl, minNumDecLvls, dummy : LONGINT;
  5015. BEGIN
  5016. IF ready THEN
  5017. invMCT.GetDecLevelRange(dummy, decLvl);
  5018. minNumDecLvls := decSpec.GetImgMinDecLevels();
  5019. IF decLvl > minNumDecLvls THEN
  5020. RETURN minNumDecLvls;
  5021. ELSE
  5022. RETURN decLvl;
  5023. END;
  5024. ELSE
  5025. RETURN -1;
  5026. END;
  5027. END GetCurrentDecompositionLevel;
  5028. (**
  5029. Gets the number of layers for the image. This value is equal to
  5030. miniumum number of layers over all tiles. If the decoder is
  5031. not ready or the stream is corrupted, -1 is returned.
  5032. NOTE:
  5033. The return value is equal to the minimum number of layers known at
  5034. the current stage of decoding, e.g. calling this procedure after opening
  5035. the decoder on a valid stream will return the number of layers
  5036. as indicated by the main header. However this may change if for example
  5037. in a tile-header read later the number of layers for that tile is lower than
  5038. the minimum known that far.
  5039. *)
  5040. PROCEDURE GetNumLayers* () : LONGINT;
  5041. BEGIN
  5042. IF ready THEN
  5043. RETURN decSpec.GetMinNumLayers();
  5044. ELSE
  5045. RETURN 0;
  5046. END;
  5047. END GetNumLayers;
  5048. (**
  5049. Sets by how much the number of layers shall be decreased at minimum. Note
  5050. that this procedure uses the current state of knowledge, meaning that a subsequent
  5051. tile could have too few layers. In that case all layers for that tile will be decoded.
  5052. NOTE: This procedure shall NOT be called after the image has been rendered/delivered once.
  5053. This procedure can be used to save some memory.
  5054. *)
  5055. PROCEDURE MinDecreaseNumLayers* (minLayers : LONGINT);
  5056. VAR
  5057. maxlayer, maxEndLayer, curStartLayer, curEndLayer : LONGINT;
  5058. BEGIN
  5059. IF ready THEN
  5060. IF ~deliveredOnce THEN
  5061. maxlayer := decSpec.GetMinNumLayers() - 1;
  5062. IF minLayers < 0 THEN
  5063. SELF.minLayDec := 0;
  5064. ELSIF minLayers <= maxlayer THEN
  5065. SELF.minLayDec := minLayers;
  5066. ELSE
  5067. KernelLog.String("WARNING (Decoder.MinDecreaseNumLayers): ");
  5068. KernelLog.String("Cannot decrease number of layers by ");
  5069. KernelLog.Int(minLayers, 0);
  5070. KernelLog.String(". Image has only ");
  5071. KernelLog.Int(maxlayer + 1, 0);
  5072. KernelLog.String(" layers.");
  5073. KernelLog.Ln();
  5074. SELF.minLayDec := maxlayer;
  5075. END;
  5076. maxEndLayer := maxlayer - SELF.minLayDec;
  5077. invMCT.SetMaxLayerRange(0, maxEndLayer);
  5078. (*
  5079. If the new maximum end layer is lower than the current
  5080. end layer, we need to lower the end layer
  5081. *)
  5082. invMCT.GetLayerRange(curStartLayer, curEndLayer);
  5083. IF curEndLayer > maxEndLayer THEN
  5084. invMCT.SetLayerRange(curStartLayer, maxEndLayer);
  5085. END;
  5086. ELSE
  5087. KernelLog.String("WARNING (Decoder.MinDecreaseNumLayers): ");
  5088. KernelLog.String("Procedure called after first image reconstruction -> won't change current value");
  5089. KernelLog.Ln();
  5090. END;
  5091. END;
  5092. END MinDecreaseNumLayers;
  5093. (**
  5094. Decreases the number of layers for the image. If it's not possible to decrease the
  5095. number of layers by as much as indicated, then at least 1 layer will be decoded. Note
  5096. that this procedure uses the current state of knowledge, meaning that a subsequent
  5097. tile could have too few layers. In that case all layers for that tile will be decoded.
  5098. *)
  5099. PROCEDURE DecreaseNumLayers* (layers : LONGINT);
  5100. VAR
  5101. maxlayer, dec : LONGINT;
  5102. BEGIN
  5103. IF ready THEN
  5104. maxlayer := decSpec.GetMinNumLayers() - 1;
  5105. IF layers < minLayDec THEN
  5106. KernelLog.String("WARNING (Decoder.DecreaseNumLayers): ");
  5107. KernelLog.String("Cannot decrease number of layers only by ");
  5108. KernelLog.Int(layers, 0);
  5109. KernelLog.String(". Num. of layers has to be decreased by at least ");
  5110. KernelLog.Int(minLayDec, 0);
  5111. KernelLog.String(".");
  5112. KernelLog.Ln();
  5113. dec := minLayDec;
  5114. ELSIF layers <= maxlayer THEN
  5115. dec := layers;
  5116. ELSE
  5117. KernelLog.String("WARNING (Decoder.DecreaseNumLayers): ");
  5118. KernelLog.String("Cannot decrease number of layers by ");
  5119. KernelLog.Int(layers, 0);
  5120. KernelLog.String(". Image has only ");
  5121. KernelLog.Int(maxlayer + 1, 0);
  5122. KernelLog.String(" layers.");
  5123. KernelLog.Ln();
  5124. dec := maxlayer;
  5125. END;
  5126. invMCT.SetLayerRange(0, maxlayer - dec);
  5127. END;
  5128. END DecreaseNumLayers;
  5129. (**
  5130. This procedure return the number of layers that where used
  5131. to render the image (NOTE: The return value gives the maximum
  5132. number of layers used; it's possible that some tiles have fewer layers).
  5133. *)
  5134. PROCEDURE GetCurrentNumLayers* () : LONGINT;
  5135. VAR
  5136. minNumLayers, curNumLayers, maxLayer, dummy : LONGINT;
  5137. BEGIN
  5138. IF ready THEN
  5139. invMCT.GetLayerRange(dummy, maxLayer);
  5140. curNumLayers := maxLayer + 1;
  5141. minNumLayers := decSpec.GetMinNumLayers();
  5142. IF curNumLayers > minNumLayers THEN
  5143. RETURN minNumLayers;
  5144. ELSE
  5145. RETURN curNumLayers;
  5146. END;
  5147. ELSE
  5148. RETURN -1;
  5149. END;
  5150. END GetCurrentNumLayers;
  5151. PROCEDURE GetNumTiles* () : LONGINT;
  5152. VAR
  5153. imgInfo : J2KCS.ImageInfo;
  5154. BEGIN
  5155. IF ready THEN
  5156. imgInfo := decSpec.GetImageInfo();
  5157. RETURN imgInfo.GetNumTiles();
  5158. ELSE
  5159. RETURN 0;
  5160. END;
  5161. END GetNumTiles;
  5162. PROCEDURE GetNumComponents* () : LONGINT;
  5163. VAR
  5164. imgInfo : J2KCS.ImageInfo;
  5165. BEGIN
  5166. IF ready THEN
  5167. imgInfo := decSpec.GetImageInfo();
  5168. RETURN imgInfo.GetNumComponents();
  5169. ELSE
  5170. RETURN 0;
  5171. END;
  5172. END GetNumComponents;
  5173. (**
  5174. Gets image width & height at a given decomposition level.
  5175. -1 for width & height, if there decoder is not ready yet or an error occured
  5176. *)
  5177. PROCEDURE GetImageSize* (declevel : LONGINT; VAR width, height : LONGINT);
  5178. VAR
  5179. imgInfo : J2KCS.ImageInfo;
  5180. minDec : LONGINT;
  5181. BEGIN
  5182. IF ready THEN
  5183. imgInfo := decSpec.GetImageInfo();
  5184. minDec := decSpec.GetImgMinDecLevels();
  5185. IF declevel <= minDec THEN
  5186. width := imgInfo.GetImgWidth(declevel);
  5187. height := imgInfo.GetImgHeight(declevel);
  5188. END;
  5189. ELSE
  5190. width := -1;
  5191. height := -1;
  5192. END;
  5193. END GetImageSize;
  5194. (**
  5195. Gets the image format (-> see Codecs).
  5196. -1 if there decoder is not ready yet or an error occured
  5197. *)
  5198. PROCEDURE GetImageFormat* () : LONGINT;
  5199. BEGIN
  5200. IF ready THEN
  5201. RETURN imgProd.GetImgFormat();
  5202. ELSE
  5203. RETURN -1;
  5204. END;
  5205. END GetImageFormat;
  5206. (**
  5207. Gets tile horizontal/vertical offset, tile width & height at a given tile and decomposition level.
  5208. -1 for toffx, toffy, width, height, if there decoder is not ready yet or an error occured
  5209. *)
  5210. PROCEDURE GetTileSize* (tile, declevel : LONGINT; VAR toffx, toffy, twidth, theight : LONGINT);
  5211. VAR
  5212. imgInfo : J2KCS.ImageInfo;
  5213. BEGIN
  5214. IF ready THEN
  5215. imgInfo := decSpec.GetImageInfo();
  5216. IF (tile < imgInfo.GetNumTiles()) & (declevel <= decSpec.GetMinDecLevels(tile)) THEN
  5217. toffx := imgInfo.GetTileULX(tile, declevel) - imgInfo.GetImgULX(declevel);
  5218. toffy := imgInfo.GetTileULY(tile, declevel) - imgInfo.GetImgULX(declevel);
  5219. twidth := imgInfo.GetTileWidth(tile, declevel);
  5220. theight := imgInfo.GetTileHeight(tile, declevel);
  5221. END;
  5222. ELSE
  5223. toffx := -1;
  5224. toffy := -1;
  5225. twidth := -1;
  5226. theight := -1;
  5227. END;
  5228. END GetTileSize;
  5229. END Decoder;
  5230. (* --- END Decoder types --- *)
  5231. VAR
  5232. filter5x3Lift : FilterSyn5x3Lifting;
  5233. filter9x7Lift : FilterSyn9x7Lifting;
  5234. (* --- Variables used by entropy decoder --- *)
  5235. (* Tables used to determine the proper context depending on the neighbor states *)
  5236. ENTROPY_ZEROLL_LUT, ENTROPY_ZEROHL_LUT, ENTROPY_ZEROHH_LUT : J2KU.LongIntArrayPtr;
  5237. (* Table used in sign decoding process *)
  5238. ENTROPY_SIGN_LUT : ARRAY LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_SIGN_BITS) OF LONGINT;
  5239. (* --- END Variables used by entropy decoder --- *)
  5240. (* The initial states and MPS symbols for each context passed to the MQ-Decoder *)
  5241. MQ_INITSTATES, MQ_INITMPS : J2KU.LongIntArrayPtr;
  5242. (* --- Variables used by MQ-Decoder --- *)
  5243. (* "Table" used by the MQ coder to look up probability estimations (2nd dim. index 0), nmps (2nd dim. index 1), nlps (2nd dim. index 2) and switch values (2nd dim. index 3) *)
  5244. MQPROB, MQNMPS, MQNLPS, MQSWITCH : ARRAY MQTABSIZ OF LONGINT;
  5245. (* --- END Variables used by MQ-Decoder --- *)
  5246. (* Initializes the lookup tables used in the MQ and Entropy Coder units *)
  5247. PROCEDURE InitEntropyTables;
  5248. VAR
  5249. i, j : LONGINT;
  5250. twoAtLeast : ARRAY 11 OF LONGINT; (* All 4 bit values with at least 2 bits = 1 *)
  5251. threeAtLeast : ARRAY 5 OF LONGINT; (* All 4 bit values with at least 3 bits = 1 *)
  5252. twoBits : ARRAY 6 OF LONGINT; (* All 4 bit values with 2 bits = 1 *)
  5253. oneBit : ARRAY 4 OF LONGINT; (* All 4 bit values with 1 bit = 1 *)
  5254. h, v, hl, hr, vu, vd, hlsig, hrsig, vusig, vdsig : LONGINT;
  5255. tmpSignLut : ARRAY 16 OF LONGINT;
  5256. BEGIN
  5257. (* Fill up the lookup table needed for significance propagation and cleanup pass for code-blocks in the LL/LH subband *)
  5258. (* Initialize locally needed arrays here *)
  5259. twoAtLeast[0] := 3;
  5260. twoAtLeast[1] := 5;
  5261. twoAtLeast[2] := 6;
  5262. twoAtLeast[3] := 7;
  5263. twoAtLeast[4] := 9;
  5264. twoAtLeast[5] := 10;
  5265. twoAtLeast[6] := 11;
  5266. twoAtLeast[7] := 12;
  5267. twoAtLeast[8] := 13;
  5268. twoAtLeast[9] := 14;
  5269. twoAtLeast[10] := 15;
  5270. threeAtLeast[0] := 7;
  5271. threeAtLeast[1] := 11;
  5272. threeAtLeast[2] := 13;
  5273. threeAtLeast[3] := 14;
  5274. threeAtLeast[4] := 15;
  5275. twoBits[0] := 3;
  5276. twoBits[1] := 5;
  5277. twoBits[2] := 6;
  5278. twoBits[3] := 9;
  5279. twoBits[4] := 10;
  5280. twoBits[5] := 12;
  5281. oneBit[0] := 1;
  5282. oneBit[1] := 2;
  5283. oneBit[2] := 4;
  5284. oneBit[3] := 8;
  5285. (* The context vector contains the significance of each neighbor of a coefficient in the follwing order: *)
  5286. (* HL - HR - VU - VD - DUL - DUR - DDL - DDR *)
  5287. NEW(ENTROPY_ZEROLL_LUT, LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_ZERO_BITS));
  5288. NEW(ENTROPY_ZEROHL_LUT, LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_ZERO_BITS));
  5289. NEW(ENTROPY_ZEROHH_LUT, LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_ZERO_BITS));
  5290. (* LL / LH subband *)
  5291. (* 2 horizontal significant *)
  5292. FOR i := 0 TO 63 DO
  5293. ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGHL) + SYSTEM.VAL(SET, ENTROPY_SIGHR)) + SYSTEM.VAL(SET, i))] := 8;
  5294. END;
  5295. (* 1 horizontal significant, at least 1 vertical significant *)
  5296. FOR i := 1 TO 3 DO
  5297. FOR j := 0 TO 15 DO
  5298. ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGHL) + SYSTEM.VAL(SET, LSH(i, 4))) + SYSTEM.VAL(SET, j))] := 7;
  5299. ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGHR) + SYSTEM.VAL(SET, LSH(i, 4))) + SYSTEM.VAL(SET, j))] := 7
  5300. END;
  5301. END;
  5302. (* 1 horizontal significant, 0 vertical significant, at least 1 diagonal significant *)
  5303. FOR i := 1 TO 15 DO
  5304. ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGHL) + SYSTEM.VAL(SET, i))] := 6;
  5305. ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGHR) + SYSTEM.VAL(SET, i))] := 6;
  5306. END;
  5307. (* 1 horizontal significant, 0 vertical significant, 0 diagonal significant *)
  5308. ENTROPY_ZEROLL_LUT[ENTROPY_SIGHL] := 5;
  5309. ENTROPY_ZEROLL_LUT[ENTROPY_SIGHR] := 5;
  5310. (* 0 horizontal significant, 2 vertical significant *)
  5311. FOR i := 0 TO 15 DO
  5312. ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGVU) + SYSTEM.VAL(SET, ENTROPY_SIGVD)) + SYSTEM.VAL(SET, i))] := 4;
  5313. END;
  5314. (* 0 horizontal significant, 1 vertical significant *)
  5315. FOR i := 0 TO 15 DO
  5316. ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGVU) + SYSTEM.VAL(SET, i))] := 3;
  5317. ENTROPY_ZEROLL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGVD) + SYSTEM.VAL(SET, i))] := 3;
  5318. END;
  5319. (* 0 horizontal significant, 0 vertical significant, at least 2 diagonal significant *)
  5320. FOR i := 0 TO LEN(twoAtLeast) - 1 DO
  5321. ENTROPY_ZEROLL_LUT[twoAtLeast[i]] := 2;
  5322. END;
  5323. (* 0 horizontal significant, 0 vertical significant, 1 diagonal significant *)
  5324. FOR i := 0 TO LEN(oneBit) - 1 DO
  5325. ENTROPY_ZEROLL_LUT[oneBit[i]] := 1;
  5326. END;
  5327. (* 0 horizontal significant, 0 vertical significant, 0 diagonal significant *)
  5328. ENTROPY_ZEROLL_LUT[0] := 0;
  5329. (* HL subband *)
  5330. (* 2 vertical significant *)
  5331. FOR i := 0 TO 3 DO
  5332. FOR j := 0 TO 15 DO
  5333. ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGVU) + SYSTEM.VAL(SET, ENTROPY_SIGVD)) + SYSTEM.VAL(SET, LSH(i, 6) ) + SYSTEM.VAL(SET, j))] := 8;
  5334. END;
  5335. END;
  5336. (* 1 vertical significant, at least 1 horizontal significant *)
  5337. FOR i := 1 TO 3 DO
  5338. FOR j := 0 TO 15 DO
  5339. ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGVU) + SYSTEM.VAL(SET, LSH(i, 6))) + SYSTEM.VAL(SET, j))] := 7;
  5340. ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGVD) + SYSTEM.VAL(SET, LSH(i, 6))) + SYSTEM.VAL(SET, j))] := 7
  5341. END;
  5342. END;
  5343. (* 1 vertical significant, 0 horizontal significant, at least 1 diagonal significant *)
  5344. FOR i := 1 TO 15 DO
  5345. ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGVU) + SYSTEM.VAL(SET, i))] := 6;
  5346. ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGVD) + SYSTEM.VAL(SET, i))] := 6;
  5347. END;
  5348. (* 1 vertical significant, 0 horizontal significant, 0 diagonal significant *)
  5349. ENTROPY_ZEROHL_LUT[ENTROPY_SIGVU] := 5;
  5350. ENTROPY_ZEROHL_LUT[ENTROPY_SIGVD] := 5;
  5351. (* 0 vertical significant, 2 horizontal significant *)
  5352. FOR i := 0 TO 15 DO
  5353. ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, (SYSTEM.VAL(SET, ENTROPY_SIGHL) + SYSTEM.VAL(SET, ENTROPY_SIGHR)) + SYSTEM.VAL(SET, i))] := 4;
  5354. END;
  5355. (* 0 vertical significant, 1 horizontal significant *)
  5356. FOR i := 0 TO 15 DO
  5357. ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGHL) + SYSTEM.VAL(SET, i))] := 3;
  5358. ENTROPY_ZEROHL_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, ENTROPY_SIGHR) + SYSTEM.VAL(SET, i))] := 3;
  5359. END;
  5360. (* 0 horizontal significant, 0 vertical significant, at least 2 diagonal significant *)
  5361. FOR i := 0 TO LEN(twoAtLeast) - 1 DO
  5362. ENTROPY_ZEROHL_LUT[twoAtLeast[i]] := 2;
  5363. END;
  5364. (* 0 horizontal significant, 0 vertical significant, 1 diagonal significant *)
  5365. FOR i := 0 TO LEN(oneBit) - 1 DO
  5366. ENTROPY_ZEROHL_LUT[oneBit[i]] := 1;
  5367. END;
  5368. (* 0 horizontal significant, 0 vertical significant, 0 diagonal significant *)
  5369. ENTROPY_ZEROHL_LUT[0] := 0;
  5370. (* HH subband *)
  5371. (* At least 3 diagonal significant *)
  5372. FOR i := 0 TO 15 DO
  5373. FOR j := 0 TO LEN(threeAtLeast) - 1 DO
  5374. ENTROPY_ZEROHH_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(i, 4)) + SYSTEM.VAL(SET, threeAtLeast[j]))] := 8;
  5375. END;
  5376. END;
  5377. (* 2 diagonal significant, at least 1 horizontal or vertical significant *)
  5378. FOR i := 1 TO 15 DO
  5379. FOR j := 0 TO LEN(twoBits) - 1 DO
  5380. ENTROPY_ZEROHH_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(i, 4)) + SYSTEM.VAL(SET, twoBits[j]))] := 7;
  5381. END;
  5382. END;
  5383. (* 2 diagonal significant, 0 horizontal or vertical significant *)
  5384. FOR i := 0 TO LEN(twoBits) - 1 DO
  5385. ENTROPY_ZEROHH_LUT[twoBits[i]] := 6;
  5386. END;
  5387. (* 1 diagonal significant, at least 2 horizontal or vertical significant *)
  5388. FOR i := 0 TO LEN(twoAtLeast) - 1 DO
  5389. FOR j := 0 TO LEN(oneBit) - 1 DO
  5390. ENTROPY_ZEROHH_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(twoAtLeast[i], 4)) + SYSTEM.VAL(SET, oneBit[j]))] := 5;
  5391. END;
  5392. END;
  5393. (* 1 diagonal significant, 1 horizontal or vertical significant *)
  5394. FOR i := 0 TO LEN(oneBit) - 1 DO
  5395. FOR j := 0 TO LEN(oneBit) - 1 DO
  5396. ENTROPY_ZEROHH_LUT[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(oneBit[i], 4)) + SYSTEM.VAL(SET, oneBit[j]))] := 4;
  5397. END;
  5398. END;
  5399. (* 1 diagonal significant, 0 horizontal or vertical significant *)
  5400. FOR i := 0 TO LEN(oneBit) - 1 DO
  5401. ENTROPY_ZEROHH_LUT[oneBit[i]] := 3;
  5402. END;
  5403. (* 0 diagonal significant, at least 2 horizontal or vertical significant *)
  5404. FOR i := 0 TO LEN(twoAtLeast) - 1 DO
  5405. ENTROPY_ZEROHH_LUT[LSH(twoAtLeast[i], 4)] := 2;
  5406. END;
  5407. (* 0 diagonal significant, 1 horizontal or vertical significant *)
  5408. FOR i := 0 TO LEN(oneBit) - 1 DO
  5409. ENTROPY_ZEROHH_LUT[LSH(oneBit[i], 4)] := 1;
  5410. END;
  5411. (* 0 horizontal significant, 0 vertical significant, 0 diagonal significant *)
  5412. ENTROPY_ZEROHH_LUT[0] := 0;
  5413. (* Fill up the lookup table needed for sign bit decoding *)
  5414. (* The context vector contains the significance and sign of the horizontal and vertical neighbors of a coefficient in the following way: *)
  5415. (* Sign HL - Sign HR - Sign VU - Sign VD - HL - HR - VU - VD *)
  5416. (*
  5417. First fill up the temporary context lookup table. This table is needed to fill up
  5418. the "real" table (i.e. the proper index of in the temporary table will be computed -> see below).
  5419. *)
  5420. (* Horizontal contrib. 1, vertical contrib. 1 *)
  5421. tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(2, 2)) + SYSTEM.VAL(SET, 2))] := 13;
  5422. (* Horizontal contrib. 1, vertical contrib. 0 *)
  5423. tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(2, 2)) + SYSTEM.VAL(SET, 1))] := 12;
  5424. (* Horizontal contrib. 1, vertical contrib. -1 *)
  5425. tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(2, 2)) + SYSTEM.VAL(SET, 0))] := 11;
  5426. (* Horizontal contrib. 0, vertical contrib. 1 *)
  5427. tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(1, 2)) + SYSTEM.VAL(SET, 2))] := 10;
  5428. (* Horizontal contrib. 0, vertical contrib. 0 *)
  5429. tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(1, 2)) + SYSTEM.VAL(SET, 1))] := 9;
  5430. (* Horizontal contrib. 0, vertical contrib. -1 *)
  5431. tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(1, 2)) + SYSTEM.VAL(SET, 0))] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 10)) + J2KU.LONGINT_SIGN_BIT);
  5432. (* Horizontal contrib. -1, vertical contrib. 1 *)
  5433. tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(0, 2)) + SYSTEM.VAL(SET, 2))] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 11)) + J2KU.LONGINT_SIGN_BIT);
  5434. (* Horizontal contrib. -1, vertical contrib. 0 *)
  5435. tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(0, 2)) + SYSTEM.VAL(SET, 1))] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 12)) + J2KU.LONGINT_SIGN_BIT);
  5436. (* Horizontal contrib. -1, vertical contrib. -1 *)
  5437. tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(0, 2)) + SYSTEM.VAL(SET, 0))] := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 13)) + J2KU.LONGINT_SIGN_BIT);
  5438. FOR i := 0 TO LSH(SYSTEM.VAL(LONGINT, 1), ENTROPY_SIGN_BITS) - 1 DO
  5439. hlsig := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(i, -7)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
  5440. hrsig := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(i, -6)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
  5441. vusig := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(i, -5)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
  5442. vdsig := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(i, -4)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
  5443. hl := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(i, -3)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
  5444. hr := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(i, -2)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
  5445. vu := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(i, -1)) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
  5446. vd := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, i) * SYSTEM.VAL(SET, SYSTEM.VAL(LONGINT, 1)));
  5447. h := hl * (1 - 2 * hlsig) + hr * (1 - 2 * hrsig);
  5448. v := vu * (1 - 2 * vusig) + vd * (1 - 2 * vdsig);
  5449. IF h > 1 THEN h := 1; END;
  5450. IF h < -1 THEN h := -1; END;
  5451. IF v > 1 THEN v := 1; END;
  5452. IF v < -1 THEN v := -1 END;
  5453. ENTROPY_SIGN_LUT[i] := tmpSignLut[SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, LSH(h+1, 2)) + SYSTEM.VAL(SET, v+1))]
  5454. END;
  5455. (* Initialize the initial states and MPS symbols for each context. These arrays will be passed on to the MQ-Decoder *)
  5456. NEW(MQ_INITSTATES, 19);
  5457. NEW(MQ_INITMPS, 19);
  5458. (* The zero context *)
  5459. MQ_INITSTATES[0] := 4;
  5460. MQ_INITMPS[0] := 0;
  5461. (* The UNIFORM context *)
  5462. MQ_INITSTATES[ENTROPY_UNICTX] := 46;
  5463. MQ_INITMPS[ENTROPY_UNICTX] := 0;
  5464. (* The run-length context *)
  5465. MQ_INITSTATES[ENTROPY_RUNCTX] := 3;
  5466. MQ_INITMPS[ENTROPY_RUNCTX] := 0;
  5467. (* All other contexts *)
  5468. FOR i := 1 TO 16 DO
  5469. MQ_INITSTATES[i] := 0;
  5470. MQ_INITMPS[i] := 0;
  5471. END;
  5472. END InitEntropyTables;
  5473. PROCEDURE InitMQTables;
  5474. BEGIN
  5475. (* Probability estimation Qe *) (* NMPS *) (* LPS *) (* SWITCH *)
  5476. MQPROB[0] := 00005601H; MQNMPS[0] := 1; MQNLPS[0] := 1; MQSWITCH[0] := 1;
  5477. MQPROB[1] := 00003401H; MQNMPS[1] := 2; MQNLPS[1] := 6; MQSWITCH[1] := 0;
  5478. MQPROB[2] := 00001801H; MQNMPS[2] := 3; MQNLPS[2] := 9; MQSWITCH[2] := 0;
  5479. MQPROB[3] := 00000AC1H; MQNMPS[3] := 4; MQNLPS[3] := 12; MQSWITCH[3] := 0;
  5480. MQPROB[4] := 00000521H; MQNMPS[4] := 5; MQNLPS[4] := 29; MQSWITCH[4] := 0;
  5481. MQPROB[5] := 00000221H; MQNMPS[5] := 38; MQNLPS[5] := 33; MQSWITCH[5] := 0;
  5482. MQPROB[6] := 00005601H; MQNMPS[6] := 7; MQNLPS[6] := 6; MQSWITCH[6] := 1;
  5483. MQPROB[7] := 00005401H; MQNMPS[7] := 8; MQNLPS[7] := 14; MQSWITCH[7] := 0;
  5484. MQPROB[8] := 00004801H; MQNMPS[8] := 9; MQNLPS[8] := 14; MQSWITCH[8] := 0;
  5485. MQPROB[9] := 00003801H; MQNMPS[9] := 10; MQNLPS[9] := 14; MQSWITCH[9] := 0;
  5486. MQPROB[10] := 00003001H; MQNMPS[10] := 11; MQNLPS[10] := 17; MQSWITCH[10] := 0;
  5487. MQPROB[11] := 00002401H; MQNMPS[11] := 12; MQNLPS[11] := 18; MQSWITCH[11] := 0;
  5488. MQPROB[12] := 00001C01H; MQNMPS[12] := 13; MQNLPS[12] := 20; MQSWITCH[12] := 0;
  5489. MQPROB[13] := 00001601H; MQNMPS[13] := 29; MQNLPS[13] := 21; MQSWITCH[13] := 0;
  5490. MQPROB[14] := 00005601H; MQNMPS[14] := 15; MQNLPS[14] := 14; MQSWITCH[14] := 1;
  5491. MQPROB[15] := 00005401H; MQNMPS[15] := 16; MQNLPS[15] := 14; MQSWITCH[15] := 0;
  5492. MQPROB[16] := 00005101H; MQNMPS[16] := 17; MQNLPS[16] := 15; MQSWITCH[16] := 0;
  5493. MQPROB[17] := 00004801H; MQNMPS[17] := 18; MQNLPS[17] := 16; MQSWITCH[17] := 0;
  5494. MQPROB[18] := 00003801H; MQNMPS[18] := 19; MQNLPS[18] := 17; MQSWITCH[18] := 0;
  5495. MQPROB[19] := 00003401H; MQNMPS[19] := 20; MQNLPS[19] := 18; MQSWITCH[19] := 0;
  5496. MQPROB[20] := 00003001H; MQNMPS[20] := 21; MQNLPS[20] := 19; MQSWITCH[20] := 0;
  5497. MQPROB[21] := 00002801H; MQNMPS[21] := 22; MQNLPS[21] := 19; MQSWITCH[21] := 0;
  5498. MQPROB[22] := 00002401H; MQNMPS[22] := 23; MQNLPS[22] := 20; MQSWITCH[22] := 0;
  5499. MQPROB[23] := 00002201H; MQNMPS[23] := 24; MQNLPS[23] := 21; MQSWITCH[23] := 0;
  5500. MQPROB[24] := 00001C01H; MQNMPS[24] := 25; MQNLPS[24] := 22; MQSWITCH[24] := 0;
  5501. MQPROB[25] := 00001801H; MQNMPS[25] := 26; MQNLPS[25] := 23; MQSWITCH[25] := 0;
  5502. MQPROB[26] := 00001601H; MQNMPS[26] := 27; MQNLPS[26] := 24; MQSWITCH[26] := 0;
  5503. MQPROB[27] := 00001401H; MQNMPS[27] := 28; MQNLPS[27] := 25; MQSWITCH[27] := 0;
  5504. MQPROB[28] := 00001201H; MQNMPS[28] := 29; MQNLPS[28] := 26; MQSWITCH[28] := 0;
  5505. MQPROB[29] := 00001101H; MQNMPS[29] := 30; MQNLPS[29] := 27; MQSWITCH[29] := 0;
  5506. MQPROB[30] := 00000AC1H; MQNMPS[30] := 31; MQNLPS[30] := 28; MQSWITCH[30] := 0;
  5507. MQPROB[31] := 000009C1H; MQNMPS[31] := 32; MQNLPS[31] := 29; MQSWITCH[31] := 0;
  5508. MQPROB[32] := 000008A1H; MQNMPS[32] := 33; MQNLPS[32] := 30; MQSWITCH[32] := 0;
  5509. MQPROB[33] := 00000521H; MQNMPS[33] := 34; MQNLPS[33] := 31; MQSWITCH[33] := 0;
  5510. MQPROB[34] := 00000441H; MQNMPS[34] := 35; MQNLPS[34] := 32; MQSWITCH[34] := 0;
  5511. MQPROB[35] := 000002A1H; MQNMPS[35] := 36; MQNLPS[35] := 33; MQSWITCH[35] := 0;
  5512. MQPROB[36] := 00000221H; MQNMPS[36] := 37; MQNLPS[36] := 34; MQSWITCH[36] := 0;
  5513. MQPROB[37] := 00000141H; MQNMPS[37] := 38; MQNLPS[37] := 35; MQSWITCH[37] := 0;
  5514. MQPROB[38] := 00000111H; MQNMPS[38] := 39; MQNLPS[38] := 36; MQSWITCH[38] := 0;
  5515. MQPROB[39] := 00000085H; MQNMPS[39] := 40; MQNLPS[39] := 37; MQSWITCH[39] := 0;
  5516. MQPROB[40] := 00000049H; MQNMPS[40] := 41; MQNLPS[40] := 38; MQSWITCH[40] := 0;
  5517. MQPROB[41] := 00000025H; MQNMPS[41] := 42; MQNLPS[41] := 39; MQSWITCH[41] := 0;
  5518. MQPROB[42] := 00000015H; MQNMPS[42] := 43; MQNLPS[42] := 40; MQSWITCH[42] := 0;
  5519. MQPROB[43] := 00000009H; MQNMPS[43] := 44; MQNLPS[43] := 41; MQSWITCH[43] := 0;
  5520. MQPROB[44] := 00000005H; MQNMPS[44] := 45; MQNLPS[44] := 42; MQSWITCH[44] := 0;
  5521. MQPROB[45] := 00000001H; MQNMPS[45] := 45; MQNLPS[45] := 43; MQSWITCH[45] := 0;
  5522. MQPROB[46] := 00005601H; MQNMPS[46] := 46; MQNLPS[46] := 46; MQSWITCH[46] := 0;
  5523. END InitMQTables;
  5524. (* TODO: What are the correct formulas to compute the bit-depths of the untransformed components
  5525. (**
  5526. Computes the bit-depth of each component before inverse MCT is performed
  5527. *)
  5528. PROCEDURE ComputeUntransformedBitDepths (VAR utdepth, tdepth : ARRAY OF LONGINT; ttype : LONGINT ) : BOOLEAN;
  5529. VAR
  5530. pow2ut0, pow2ut1, pow2ut2 : LONGINT;
  5531. BEGIN
  5532. ASSERT(LEN(utdepth) >= LEN(tdepth));
  5533. (*
  5534. If there are less than three components and a multiple
  5535. component transformation is used, then this violates the
  5536. constraints imposed by the specification
  5537. *)
  5538. IF (LEN(utdepth) < 3) & (ttype # MCT_NONE) THEN
  5539. KernelLog.String("ERROR: Computation of original component bit depths failed because there are less than 3 components ");
  5540. KernelLog.String(" and multiple component transformation is used");
  5541. KernelLog.Ln();
  5542. RETURN FALSE;
  5543. END;
  5544. (* The bit depths of the transformed components depends on the component transformation used *)
  5545. CASE ttype OF
  5546. MCT_NONE :
  5547. (* The bit depths of the transformed and un-transformed components are equal *)
  5548. SYSTEM.MOVE(ADDRESSOF(utdepth[0]), ADDRESSOF(tdepth[0]), LEN(utdepth)*SIZEOF(LONGINT));
  5549. | MCT_RCT :
  5550. (*
  5551. The formulas are:
  5552. tdepth[0] = ceil(log2( 2^(utdepth[0]) + 2^(utdepth[1]) + 2^(utdepth[2]) )) - 2 + 1
  5553. tdepth[1] = ceil(log2( 2^(utdepth[0]) + 2^(utdepth[1]) - 1 )) + 1
  5554. tdepth[2] = ceil(log2( 2^(utdepth[1]) + 2^(utdepth[2]) - 1 )) + 1
  5555. Since 'Log2Floor(x)' computes floor(log2(x)) we use 'Log2Floor(2*x-1) + 1',
  5556. which calculates ceil(log2(x)), for any x >= 1, x integer
  5557. *)
  5558. (* Precalculate the 2^utdepth[x] *)
  5559. pow2ut0 := LSH(SYSTEM.VAL(LONGINT, 1), utdepth[0]);
  5560. pow2ut1 := LSH(SYSTEM.VAL(LONGINT, 1), utdepth[1]);
  5561. pow2ut2 := LSH(SYSTEM.VAL(LONGINT, 1), utdepth[2]);
  5562. tdepth[0] := J2KU.Log2Floor(pow2ut0 + 2*pow2ut1 + pow2ut2 - 1) - 1;
  5563. tdepth[1] := J2KU.Log2Floor(pow2ut2 + pow2ut1 - 1) + 1;
  5564. tdepth[2] := J2KU.Log2Floor(pow2ut0 + pow2ut1 - 1) + 1;
  5565. | MCT_ICT :
  5566. (* Precalculate the 2^utdepth[x] *)
  5567. pow2ut0 := LSH(SYSTEM.VAL(LONGINT, 1), utdepth[0]);
  5568. pow2ut1 := LSH(SYSTEM.VAL(LONGINT, 1), utdepth[1]);
  5569. pow2ut2 := LSH(SYSTEM.VAL(LONGINT, 1), utdepth[2]);
  5570. tdepth[0] := J2KU.Log2Floor(ENTIER(pow2ut0*0.299072
  5571. + pow2ut1*0.586914
  5572. + pow2ut2*0.114014 - 0.5) - 1) + 1;
  5573. tdepth[1] := J2KU.Log2Floor(ENTIER(pow2ut0*0.168701
  5574. + pow2ut1*0.331299
  5575. + pow2ut2*0.5 - 0.5) - 1) + 1;
  5576. tdepth[2] := J2KU.Log2Floor(ENTIER(pow2ut0*0.5
  5577. + pow2ut1*0.418701
  5578. + pow2ut2*0.081299 - 0.5) - 1) + 1;
  5579. ELSE
  5580. KernelLog.String("ERROR: Computation of original component bit depths failed because ");
  5581. KernelLog.String(" the component transformation type is unknown");
  5582. KernelLog.Ln();
  5583. RETURN FALSE;
  5584. END;
  5585. RETURN TRUE;
  5586. END ComputeUntransformedBitDepths;
  5587. *)
  5588. (**
  5589. Returns the default options for the decoder
  5590. (i.e. default components and default options for those components)
  5591. *)
  5592. PROCEDURE GetDefaultDecoderOptions* () : J2KU.DecoderOptions;
  5593. VAR
  5594. decOpt : J2KU.DecoderOptions;
  5595. crOpt : J2KU.CodestreamReaderOptions;
  5596. edOpt : J2KU.EntropyDecoderOptions;
  5597. roiOpt : J2KU.ROIDescalerOptions;
  5598. deqOpt : J2KU.DequantizerOptions;
  5599. invDWTOpt : J2KU.InverseDWTOptions;
  5600. invMCTOpt : J2KU.InverseMCTOptions;
  5601. BEGIN
  5602. (* NOTE: We set the minimum decomposition level and maximum number of layers as fixed *)
  5603. NEW(decOpt);
  5604. (* --- Options for codestream reader --- *)
  5605. NEW(crOpt);
  5606. (* We use the buffered codestream reader by default *)
  5607. crOpt.component := J2KCS.BUF_CODESTREAM_READER;
  5608. crOpt.printComments := FALSE;
  5609. decOpt.crOpt := crOpt;
  5610. (* --- Options for entropy decoder --- *)
  5611. NEW(edOpt);
  5612. edOpt.component := ENTROPY_DECODER;
  5613. (* By default, we don't conceal errors *)
  5614. edOpt.concealError := FALSE;
  5615. decOpt.edOpt := edOpt;
  5616. (* --- Options for ROI de-scaler --- *)
  5617. NEW(roiOpt);
  5618. roiOpt.component := ROI_DESCALER;
  5619. (* By default ROIs shall not be ignored *)
  5620. roiOpt.noROI := FALSE;
  5621. decOpt.roiOpt := roiOpt;
  5622. (* --- Options for dequantizer --- *)
  5623. NEW(deqOpt);
  5624. deqOpt.component := DEQUANTIZER;
  5625. decOpt.deqOpt := deqOpt;
  5626. (* --- Options for inverse wavelet transformation --- *)
  5627. NEW(invDWTOpt);
  5628. invDWTOpt.component := INVERSE_DWT;
  5629. invDWTOpt.filterRev := FILTER_5X3_LIFTING;
  5630. invDWTOpt.filterIrrev := FILTER_9X7_LIFTING;
  5631. decOpt.invDWTOpt := invDWTOpt;
  5632. (* --- Options for inverse multiple component transformation --- *)
  5633. NEW(invMCTOpt);
  5634. invMCTOpt.component := INVERSE_MCT;
  5635. (* Buffer is not considered as rebuild component by default *)
  5636. invMCTOpt.nonRebuildBuffer := TRUE;
  5637. decOpt.invMCTOpt := invMCTOpt;
  5638. RETURN decOpt;
  5639. END GetDefaultDecoderOptions;
  5640. (**
  5641. Decoder factory procedure
  5642. *)
  5643. PROCEDURE Factory*() : Codecs.ImageDecoder;
  5644. VAR
  5645. decOpt : J2KU.DecoderOptions;
  5646. dec : Decoder;
  5647. BEGIN
  5648. (* Set default decoder options *)
  5649. decOpt := GetDefaultDecoderOptions();
  5650. NEW(dec, decOpt);
  5651. RETURN dec;
  5652. END Factory;
  5653. (*
  5654. PROCEDURE DecodeUsage(out : Streams.Writer);
  5655. BEGIN
  5656. out.String("Usage: JPEG2000Decoder.Decode {<option>} <fileName>");
  5657. out.Ln();
  5658. out.Ln();
  5659. out.String(" <option> can be any of the following:");
  5660. out.Ln();
  5661. out.Ln();
  5662. out.String(" /v : View the image. If /bmp option is not used, this option is enabeld automatically");
  5663. out.Ln();
  5664. out.Ln();
  5665. out.String(" /bmp <BMP format> <BMP file name> : write decoded image to a BMP file. ");
  5666. out.Ln();
  5667. out.String(" where <BMP format> may be one of the following:");
  5668. out.Ln();
  5669. out.String(" 32 (32 bit rgba, 8 bits for r,g,b and alpha)");
  5670. out.Ln();
  5671. out.String(" 24 (24 bit rgb, 8 bits for r,g and b)");
  5672. out.Ln();
  5673. out.String(" 16 (16 bit rgb, 5 bits for r & b, 6 bits for g)");
  5674. out.Ln();
  5675. out.Ln();
  5676. out.String(" /decrl <decrease in resolution level>: Decreases the resolution level (0 - 32)");
  5677. out.Ln();
  5678. out.Ln();
  5679. out.String(" /decly <decrease in # layers> : Decreases the number of layers (-> decreases the image quality) (0 - 65535)");
  5680. out.Ln();
  5681. out.Ln();
  5682. out.String(" /com : Print comments. If /csinfo option is used then the comments will be embedded in the codestream info output");
  5683. out.Ln();
  5684. out.Ln();
  5685. out.String(" /noroi : Makes sure that no ROI de-scaling is performed. Decompression is done like there was no ROI in the image");
  5686. out.Ln();
  5687. out.Ln();
  5688. out.String(" /errdet : Error detection shall be performed by the entropy decoder. If errors are detected they will be concealed ");
  5689. out.Ln();
  5690. out.String(" and the resulting distortion will be less significant. Note that errors can only be detected if the the encoder ");
  5691. out.Ln();
  5692. out.String(" that generated the data included error resilience information");
  5693. out.Ln();
  5694. END DecodeUsage;
  5695. (**
  5696. Mini decoder application for viewing and storing (as BMP files) JPEG2000 images.
  5697. *)
  5698. PROCEDURE Decode* (context : Commands.Context);
  5699. VAR
  5700. noFile : BOOLEAN;
  5701. file : Files.File;
  5702. fileName : ARRAY 255 OF CHAR;
  5703. fs : J2KU.FileInputStream;
  5704. window : WM.BufferWindow;
  5705. decOpt : J2KU.DecoderOptions;
  5706. decoder : Decoder;
  5707. imgConsumerArr : ARRAY 2 OF ImageConsumer;
  5708. nconsumer : LONGINT;
  5709. rasterImgAdapt : RasterImageAdapter;
  5710. imgWidth, imgHeight, maxProg, format : LONGINT;
  5711. (* --- Variables used in option parsing --- *)
  5712. view : BOOLEAN;
  5713. decResStr : ARRAY 3 OF CHAR;
  5714. decLayStr : ARRAY 6 OF CHAR;
  5715. decRes : LONGINT;
  5716. decLay : LONGINT;
  5717. bmpFormatStr : ARRAY 3 OF CHAR;
  5718. bmpFileName : ARRAY 128 OF CHAR;
  5719. bmpFormat : LONGINT;
  5720. bmpRasterFormat : Raster.Format;
  5721. bmpOut : BOOLEAN;
  5722. bmpImg : Raster.Image;
  5723. bmpTransPar : Raster.PictureTransferParameters;
  5724. bmpStoreRet : ANY;
  5725. opt : ARRAY 255 OF CHAR;
  5726. res : LONGINT;
  5727. (* --- END Variables used in option parsing --- *)
  5728. BEGIN
  5729. noFile := TRUE;
  5730. fs := NIL;
  5731. decRes := 0;
  5732. decLay := 0;
  5733. bmpOut := FALSE;
  5734. view := FALSE;
  5735. nconsumer := 0;
  5736. decOpt := GetDefaultDecoderOptions();
  5737. (* Option parsing loop *)
  5738. WHILE context.arg..Available() > 0 DO
  5739. context.arg.SkipSpaces();
  5740. context.arg.String(opt);
  5741. IF opt = "/v" THEN
  5742. view := TRUE;
  5743. ELSIF opt = "/decrl" THEN
  5744. context.arg.SkipSpaces();
  5745. IF context.arg.Available() = 0 THEN
  5746. context.error.String("No resolution decrease value specified");
  5747. context.error.Ln();
  5748. DecodeUsage();
  5749. RETURN NIL;
  5750. ELSE
  5751. context.arg.String(decResStr);
  5752. decRes := -1;
  5753. Strings.StrToInt(decResStr, decRes);
  5754. IF (decRes < 0) OR (decRes > 32) THEN
  5755. context.error.String("Invalid resolution decrease value");
  5756. context.error.Ln();
  5757. DecodeUsage();
  5758. RETURN NIL;
  5759. END;
  5760. END;
  5761. ELSIF opt = "/decly" THEN
  5762. context.arg.SkipSpaces();
  5763. IF context.arg.Available() = 0 THEN
  5764. context.error.String("No layer decrease value specified");
  5765. context.error.Ln();
  5766. DecodeUsage();
  5767. RETURN NIL;
  5768. ELSE
  5769. context.arg.String(decLayStr);
  5770. decLay := -1;
  5771. Strings.StrToInt(decLayStr, decLay);
  5772. IF (decLay < 0) OR (decLay > 65535) THEN
  5773. context.error.String("Invalid layer decrease value");
  5774. context.error.Ln();
  5775. DecodeUsage();
  5776. RETURN NIL;
  5777. END;
  5778. END;
  5779. ELSIF opt = "/bmp" THEN
  5780. context.arg.SkipSpaces();
  5781. IF strReader.Available() = 0 THEN
  5782. context.error.String("No BMP format specified");
  5783. context.error.Ln();
  5784. DecodeUsage();
  5785. RETURN NIL;
  5786. END;
  5787. context.arg.String(bmpFormatStr);
  5788. bmpFormat := -1;
  5789. Strings.StrToInt(bmpFormatStr, bmpFormat);
  5790. IF bmpFormat = 16 THEN
  5791. bmpRasterFormat := Raster.BGR565;
  5792. ELSIF bmpFormat = 24 THEN
  5793. bmpRasterFormat := Raster.BGR888;
  5794. ELSIF bmpFormat = 32 THEN
  5795. bmpRasterFormat := Raster.BGRA8888;
  5796. ELSE
  5797. context.error.String("Invalid BMP format specified");
  5798. context.error.Ln();
  5799. DecodeUsage();
  5800. RETURN NIL;
  5801. END;
  5802. context.arg.SkipSpaces();
  5803. IF context.arg.Available() = 0 THEN
  5804. context.error.String("No BMP output file specified");
  5805. context.error.Ln();
  5806. DecodeUsage();
  5807. RETURN NIL;
  5808. END;
  5809. context.arg.String(bmpFileName);
  5810. bmpOut := TRUE;
  5811. ELSIF opt = "/com" THEN
  5812. decOpt.crOpt.printComments := TRUE;
  5813. ELSIF opt = "/noroi" THEN
  5814. decOpt.roiOpt.noROI := TRUE;
  5815. ELSIF opt = "/errdet" THEN
  5816. decOpt.edOpt.concealError := TRUE;
  5817. ELSIF context.arg.Available() = 0 THEN
  5818. COPY(opt, fileName);
  5819. noFile := FALSE;
  5820. ELSE
  5821. context.error.String("Invalid option '");
  5822. context.error.String(opt);
  5823. context.error.String("'");
  5824. context.error.Ln();
  5825. DecodeUsage();
  5826. RETURN NIL;
  5827. END;
  5828. END;
  5829. IF noFile THEN
  5830. context.error.String("No file specified");
  5831. context.error.Ln();
  5832. DecodeUsage();
  5833. RETURN NIL;
  5834. END;
  5835. file := Files.Old(fileName);
  5836. IF file = NIL THEN
  5837. context.error.String("Couldn't open file ");
  5838. context.error.String(fileName);
  5839. context.error.Ln();
  5840. RETURN NIL;
  5841. END;
  5842. NEW(fs, file, 0);
  5843. IF (fs = NIL) THEN
  5844. context.error.String("Couldn't open reader on file");
  5845. context.error.Ln();
  5846. RETURN NIL;
  5847. END;
  5848. NEW(decoder, decOpt);
  5849. decoder.Open(fs, res);
  5850. IF decoder.GetNumResolutionLevels() < decRes THEN
  5851. context.out.String("WARNING: Cannot decrease resolution level by ");
  5852. context.out.Int(decRes, 0);
  5853. context.out.String(": Image has only ");
  5854. context.out.Int(decoder.GetNumResolutionLevels(), 0);
  5855. context.out.String(" resolution levels");
  5856. context.out.Ln();
  5857. decRes := decoder.GetNumResolutionLevels();
  5858. ELSIF decoder.GetNumLayers() < decLay THEN
  5859. context.out.String("WARNING: Cannot decrease number of layers by ");
  5860. context.out.Int(decLay, 0);
  5861. context.out.String(": Image has only ");
  5862. context.out.Int(decoder.GetNumLayers(), 0);
  5863. context.out.String(" layers");
  5864. context.out.Ln();
  5865. decLay := decoder.GetNumLayers() - 1;
  5866. END;
  5867. decoder.GetImageSize(decRes, imgWidth, imgHeight);
  5868. (* Check if valid size *)
  5869. IF (imgWidth <= 0) OR (imgHeight <= 0) THEN
  5870. RETURN NIL;
  5871. END;
  5872. decoder.DecreaseResolutionLevel(decRes);
  5873. decoder.DecreaseNumLayers(decLay);
  5874. (* Set up output window and/or file *)
  5875. (* Display the image if the "view" option has been set, or the "output-to-file" option is not set *)
  5876. IF view OR ~bmpOut THEN
  5877. NEW(window, imgWidth, imgHeight, FALSE);
  5878. window.SetTitle(WM.NewString(fileName));
  5879. WM.DefaultAddWindow(window);
  5880. NEW(rasterImgAdapt, window.img);
  5881. imgConsumerArr[nconsumer] := rasterImgAdapt;
  5882. INC(nconsumer);
  5883. END;
  5884. IF bmpOut THEN
  5885. IF view & (window.img.fmt.code = bmpRasterFormat.code) THEN
  5886. bmpImg := window.img;
  5887. ELSE
  5888. NEW(bmpImg);
  5889. Raster.Create(bmpImg, imgWidth, imgHeight, bmpRasterFormat);
  5890. NEW(rasterImgAdapt, bmpImg);
  5891. imgConsumerArr[nconsumer] := rasterImgAdapt;
  5892. INC(nconsumer);
  5893. END;
  5894. END;
  5895. (* Deliver the image to the image consumers *)
  5896. decoder.DeliverImage(imgConsumerArr, 0, nconsumer);
  5897. IF view OR ~bmpOut THEN
  5898. window.Invalidate( Rectangles.MakeRect( 0, 0, window.img.width, window.img.height ) );
  5899. END;
  5900. IF bmpOut THEN
  5901. NEW(bmpTransPar);
  5902. bmpTransPar.img := bmpImg;
  5903. COPY(bmpFileName, bmpTransPar.name);
  5904. bmpTransPar.done := FALSE;
  5905. bmpStoreRet := AosBMPImages.AosStore(bmpTransPar);
  5906. IF ~bmpTransPar.done THEN
  5907. context.error.String("Writing decoded image to BMP file failed");
  5908. context.error.Ln;
  5909. END;
  5910. END;
  5911. END Decode;
  5912. *)
  5913. BEGIN
  5914. InitEntropyTables();
  5915. InitMQTables();
  5916. NEW(filter5x3Lift);
  5917. NEW(filter9x7Lift);
  5918. END JPEG2000Decoder.
  5919. SystemTools.Free JPEG2000Decoder~
  5920. SystemTools.Free JPEG2000DecoderCS~
  5921. SystemTools.Free JPEG2000Util~