strdec.c 139 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628
  1. //*@@@+++@@@@******************************************************************
  2. //
  3. // Copyright © Microsoft Corp.
  4. // All rights reserved.
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions are met:
  8. //
  9. // • Redistributions of source code must retain the above copyright notice,
  10. // this list of conditions and the following disclaimer.
  11. // • Redistributions in binary form must reproduce the above copyright notice,
  12. // this list of conditions and the following disclaimer in the documentation
  13. // and/or other materials provided with the distribution.
  14. //
  15. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  19. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. // POSSIBILITY OF SUCH DAMAGE.
  26. //
  27. //*@@@---@@@@******************************************************************
  28. #include "strcodec.h"
  29. #include "decode.h"
  30. #include "strTransform.h"
  31. #include <math.h>
  32. #include "perfTimer.h"
  33. #ifdef MEM_TRACE
  34. #define TRACE_MALLOC 1
  35. #define TRACE_NEW 0
  36. #define TRACE_HEAP 0
  37. #include "memtrace.h"
  38. #endif
  39. #ifdef X86OPT_INLINE
  40. #define _FORCEINLINE __forceinline
  41. #else // X86OPT_INLINE
  42. #define _FORCEINLINE
  43. #endif // X86OPT_INLINE
  44. #if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_DEC) || defined(WMP_OPT_TRFM_DEC)
  45. void StrDecOpt(CWMImageStrCodec* pSC);
  46. #endif // OPT defined
  47. Int processMacroblockDec(CWMImageStrCodec *);
  48. U8 readQuantizerSB(U8 pQPIndex[MAX_CHANNELS], SimpleBitIO * pIO, size_t cChannel)
  49. {
  50. U8 cChMode = 0;
  51. if(cChannel >= MAX_CHANNELS)
  52. return 0;
  53. if(cChannel > 1)
  54. cChMode = (U8)getBit32_SB(pIO, 2); // Channel mode
  55. pQPIndex[0] = (U8)getBit32_SB(pIO, 8); // Y
  56. if(cChMode == 1) // MIXED
  57. pQPIndex[1] = (U8)getBit32_SB(pIO, 8); // UV
  58. else if(cChMode > 0){ // INDEPENDENT
  59. size_t i;
  60. for(i = 1; i < cChannel; i ++)
  61. #pragma prefast(suppress: __WARNING_UNRELATED_LOOP_TERMINATION_NO_SIZEEXPR, "PREfast false alarm: 1 <= i < MAX_CHANNELS, no buffer over/underrun!")
  62. pQPIndex[i] = (U8)getBit32_SB(pIO, 8); // UV
  63. }
  64. return cChMode;
  65. }
  66. U8 readQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], BitIOInfo * pIO, size_t cChannel, size_t iPos)
  67. {
  68. U8 cChMode = 0;
  69. if(cChannel > 1)
  70. cChMode = (U8)getBit16(pIO, 2); // Channel mode
  71. pQuantizer[0][iPos].iIndex = (U8)getBit16(pIO, 8); // Y
  72. if(cChMode == 1) // MIXED
  73. pQuantizer[1][iPos].iIndex = (U8)getBit16(pIO, 8); // UV
  74. else if(cChMode > 0){ // INDEPENDENT
  75. size_t i;
  76. for(i = 1; i < cChannel; i ++)
  77. pQuantizer[i][iPos].iIndex = (U8)getBit16(pIO, 8); // UV
  78. }
  79. return cChMode;
  80. }
  81. // packet header: 00000000 00000000 00000001 ?????xxx
  82. // xxx: 000(spatial) 001(DC) 010(AD) 011(AC) 100(FL) 101-111(reserved)
  83. // ?????: (iTileY * cNumOfSliceV + iTileX) % 32
  84. Int readPacketHeader(BitIOInfo * pIO, U8 ptPacketType, U8 pID)
  85. {
  86. UNREFERENCED_PARAMETER( ptPacketType );
  87. UNREFERENCED_PARAMETER( pID );
  88. if(getBit16(pIO, 8) != 0 || getBit16(pIO, 8) != 0 || getBit16(pIO, 8) != 1)
  89. return ICERR_ERROR;
  90. getBit16(pIO, 8);
  91. return ICERR_OK;
  92. }
  93. Int readTileHeaderDC(CWMImageStrCodec * pSC, BitIOInfo * pIO)
  94. {
  95. if((pSC->m_param.uQPMode & 1) != 0){ // not DC uniform
  96. size_t iTile;
  97. CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
  98. if(pSC->cTileRow + pSC->cTileColumn == 0) // allocate DC QP info
  99. for(iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile ++)
  100. if(allocateQuantizer(pSC->pTile[iTile].pQuantizerDC, pSC->m_param.cNumChannels, 1) != ICERR_OK)
  101. return ICERR_ERROR;
  102. pTile->cChModeDC = readQuantizer(pTile->pQuantizerDC, pIO, pSC->m_param.cNumChannels, 0);
  103. formatQuantizer(pTile->pQuantizerDC, pTile->cChModeDC, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith);
  104. }
  105. return ICERR_OK;
  106. }
  107. Int readTileHeaderLP(CWMImageStrCodec * pSC, BitIOInfo * pIO)
  108. {
  109. if(pSC->WMISCP.sbSubband != SB_DC_ONLY && (pSC->m_param.uQPMode & 2) != 0){ // not LP uniform
  110. CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
  111. U8 i;
  112. pTile->bUseDC = (getBit16(pIO, 1) == 1 ? TRUE : FALSE);
  113. pTile->cBitsLP = 0;
  114. pTile->cNumQPLP = 1;
  115. if(pSC->cTileRow > 0)
  116. freeQuantizer(pTile->pQuantizerLP);
  117. if(pTile->bUseDC == TRUE){
  118. if(allocateQuantizer(pTile->pQuantizerLP, pSC->m_param.cNumChannels, pTile->cNumQPLP) != ICERR_OK)
  119. return ICERR_ERROR;
  120. useDCQuantizer(pSC, pSC->cTileColumn);
  121. }
  122. else{
  123. pTile->cNumQPLP = (U8)getBit16(pIO, 4) + 1;
  124. pTile->cBitsLP = dquantBits(pTile->cNumQPLP);
  125. if(allocateQuantizer(pTile->pQuantizerLP, pSC->m_param.cNumChannels, pTile->cNumQPLP) != ICERR_OK)
  126. return ICERR_ERROR;
  127. for(i = 0; i < pTile->cNumQPLP; i ++){
  128. pTile->cChModeLP[i] = readQuantizer(pTile->pQuantizerLP, pIO, pSC->m_param.cNumChannels, i);
  129. formatQuantizer(pTile->pQuantizerLP, pTile->cChModeLP[i], pSC->m_param.cNumChannels, i, TRUE, pSC->m_param.bScaledArith);
  130. }
  131. }
  132. }
  133. return ICERR_OK;
  134. }
  135. Int readTileHeaderHP(CWMImageStrCodec * pSC, BitIOInfo * pIO)
  136. {
  137. if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS && (pSC->m_param.uQPMode & 4) != 0){ // not HP uniform
  138. CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
  139. U8 i;
  140. pTile->bUseLP = (getBit16(pIO, 1) == 1 ? TRUE : FALSE);
  141. pTile->cBitsHP = 0;
  142. pTile->cNumQPHP = 1;
  143. if(pSC->cTileRow > 0)
  144. freeQuantizer(pTile->pQuantizerHP);
  145. if(pTile->bUseLP == TRUE){
  146. pTile->cNumQPHP = pTile->cNumQPLP;
  147. if(allocateQuantizer(pTile->pQuantizerHP, pSC->m_param.cNumChannels, pTile->cNumQPHP) != ICERR_OK)
  148. return ICERR_ERROR;
  149. useLPQuantizer(pSC, pTile->cNumQPHP, pSC->cTileColumn);
  150. }
  151. else{
  152. pTile->cNumQPHP = (U8)getBit16(pIO, 4) + 1;
  153. pTile->cBitsHP = dquantBits(pTile->cNumQPHP);
  154. if(allocateQuantizer(pTile->pQuantizerHP, pSC->m_param.cNumChannels, pTile->cNumQPHP) != ICERR_OK)
  155. return ICERR_ERROR;
  156. for(i = 0; i < pTile->cNumQPHP; i ++){
  157. pTile->cChModeHP[i] = readQuantizer(pTile->pQuantizerHP, pIO, pSC->m_param.cNumChannels, i);
  158. formatQuantizer(pTile->pQuantizerHP, pTile->cChModeHP[i], pSC->m_param.cNumChannels, i, FALSE, pSC->m_param.bScaledArith);
  159. }
  160. }
  161. }
  162. return ICERR_OK;
  163. }
  164. Int readPackets(CWMImageStrCodec * pSC)
  165. {
  166. if(pSC->cColumn == 0 && pSC->cRow == pSC->WMISCP.uiTileY[pSC->cTileRow]){ // start of a new horizontal slice
  167. size_t k;
  168. if (pSC->m_bSecondary) {
  169. if(pSC->cNumBitIO > 0){
  170. for(k = 0; k <= pSC->WMISCP.cNumOfSliceMinus1V; k ++){
  171. // reset coding contexts
  172. ResetCodingContextDec(&pSC->m_pCodingContext[k]);
  173. }
  174. }
  175. else{ // for multiple decoding calls!
  176. ResetCodingContextDec(&pSC->m_pCodingContext[0]);
  177. }
  178. }
  179. else {
  180. // get sizes of each packet and update index table
  181. for(k = 0; k < pSC->cNumBitIO; k ++){
  182. if(pSC->ppWStream != NULL){ // new API
  183. unsigned cBands = (pSC->WMISCP.bfBitstreamFormat == SPATIAL ? 1 : pSC->cSB);
  184. struct WMPStream ** ppWS = pSC->ppWStream + (pSC->WMISCP.cNumOfSliceMinus1V + 1) * pSC->cTileRow * cBands
  185. + k / cBands * cBands + (k % cBands);
  186. if(pSC->cTileRow > 0 && pSC->m_ppBitIO[k]->pWS != NULL) // attached to the same packet of the tile on top
  187. detachISRead(pSC, pSC->m_ppBitIO[k]); // detach it
  188. if(ppWS[0] != NULL)
  189. attachISRead(pSC->m_ppBitIO[k], ppWS[0], pSC); // need to attach it
  190. }
  191. else{
  192. if(pSC->cTileRow > 0)
  193. detachISRead(pSC, pSC->m_ppBitIO[k]);
  194. pSC->WMISCP.pWStream->SetPos(pSC->WMISCP.pWStream, pSC->pIndexTable[pSC->cNumBitIO * pSC->cTileRow + k] + pSC->cHeaderSize);
  195. attachISRead(pSC->m_ppBitIO[k], pSC->WMISCP.pWStream, pSC);
  196. }
  197. }
  198. if(pSC->cNumBitIO == 0){
  199. detachISRead(pSC, pSC->pIOHeader);
  200. if(pSC->ppWStream != NULL){// new API
  201. attachISRead(pSC->pIOHeader, pSC->ppWStream[0], pSC); // need to attach it
  202. }
  203. else{
  204. pSC->WMISCP.pWStream->SetPos(pSC->WMISCP.pWStream, pSC->cHeaderSize);
  205. attachISRead(pSC->pIOHeader, pSC->WMISCP.pWStream, pSC);
  206. }
  207. }
  208. for(k = 0; k <= pSC->WMISCP.cNumOfSliceMinus1V; k ++){
  209. U8 pID = (U8)((pSC->cTileRow * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + k) & 0x1F);
  210. // read packet header
  211. if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){
  212. BitIOInfo * pIO = (pSC->cNumBitIO == 0 ? pSC->pIOHeader : pSC->m_ppBitIO[k]);
  213. if(pIO->pWS == NULL || readPacketHeader(pIO, 0, pID) != ICERR_OK)
  214. return ICERR_ERROR;
  215. pSC->m_pCodingContext[k].m_iTrimFlexBits = (pSC->m_param.bTrimFlexbitsFlag) ? getBit16(pIO, 4) : 0;
  216. }
  217. else{
  218. if(pSC->m_ppBitIO[k * pSC->cSB + 0] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 0], 1, pID) != ICERR_OK)
  219. return ICERR_ERROR;
  220. if(pSC->cSB > 1){
  221. if(pSC->m_ppBitIO[k * pSC->cSB + 1] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 1], 2, pID) != ICERR_OK)
  222. return ICERR_ERROR;
  223. }
  224. if(pSC->cSB > 2){
  225. if(pSC->m_ppBitIO[k * pSC->cSB + 2] == NULL || readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 2], 3, pID) != ICERR_OK)
  226. return ICERR_ERROR;
  227. // readTileHeaderHP(pSC, pSC->m_ppBitIO[k * pSC->cSB + 2]);
  228. }
  229. if(pSC->cSB > 3){
  230. if(pSC->m_ppBitIO[k * pSC->cSB + 3] == NULL)
  231. return ICERR_ERROR;
  232. readPacketHeader(pSC->m_ppBitIO[k * pSC->cSB + 3], 4, pID); // bad flexbits packet doesn't generate an error
  233. pSC->m_pCodingContext[k].m_iTrimFlexBits = (pSC->m_param.bTrimFlexbitsFlag) ? getBit16(pSC->m_ppBitIO[k * pSC->cSB + 3], 4) : 0;
  234. }
  235. }
  236. // reset coding contexts
  237. ResetCodingContextDec(&pSC->m_pCodingContext[k]);
  238. }
  239. }
  240. }
  241. if(pSC->m_bCtxLeft && pSC->m_bCtxTop && pSC->m_bSecondary == FALSE){
  242. CCodingContext *pContext = &pSC->m_pCodingContext[pSC->cTileColumn];
  243. readTileHeaderDC(pSC, pContext->m_pIODC);
  244. if(pSC->m_pNextSC != NULL)
  245. readTileHeaderDC(pSC->m_pNextSC, pContext->m_pIODC);
  246. if(pSC->cSB > 1){
  247. readTileHeaderLP(pSC, pContext->m_pIOLP);
  248. if(pSC->m_pNextSC != NULL)
  249. readTileHeaderLP(pSC->m_pNextSC, pContext->m_pIOLP);
  250. }
  251. if(pSC->cSB > 2){
  252. readTileHeaderHP(pSC, pContext->m_pIOAC);
  253. if(pSC->m_pNextSC != NULL)
  254. readTileHeaderHP(pSC->m_pNextSC, pContext->m_pIOAC);
  255. }
  256. }
  257. return ICERR_OK;
  258. }
  259. /* inverse transform and overlap possible part of a macroblock */
  260. Int processMacroblockDec(CWMImageStrCodec * pSC)
  261. {
  262. const OVERLAP olOverlap = pSC->WMISCP.olOverlap;
  263. // const Bool left = (pSC->cColumn == 0);
  264. const Bool /*top = (pSC->cRow == 0),*/ bottom = (pSC->cRow == pSC->cmbHeight);
  265. const Bool bottomORright = (bottom || pSC->cColumn == pSC->cmbWidth);
  266. // const size_t mbWidth = pSC->cmbWidth, mbX = pSC->cColumn;
  267. // Int iQIndex = 0;
  268. ERR_CODE result = ICERR_OK;
  269. size_t j, jend = (pSC->m_pNextSC != NULL);
  270. for (j = 0; j <= jend; j++) {
  271. if(!bottomORright){
  272. CCodingContext *pContext;
  273. getTilePos(pSC, pSC->cColumn, pSC->cRow);
  274. if(jend){
  275. pSC->m_pNextSC->cTileColumn = pSC->cTileColumn;
  276. pSC->m_pNextSC->cTileRow = pSC->cTileRow;
  277. }
  278. pContext = &pSC->m_pCodingContext[pSC->cTileColumn];
  279. if(readPackets(pSC) != ICERR_OK)
  280. return ICERR_ERROR;
  281. // check if we need to do entropy decode
  282. if(!pSC->m_Dparam->bDecodeFullFrame){
  283. if(pSC->cColumn == pSC->WMISCP.uiTileX[pSC->cTileColumn]){ // switching to a new tile
  284. size_t rLeft = pSC->m_Dparam->cROILeftX, rRight = pSC->m_Dparam->cROIRightX;
  285. size_t rTop = pSC->m_Dparam->cROITopY, rBottom = pSC->m_Dparam->cROIBottomY;
  286. size_t rExt = (olOverlap == OL_NONE ? 0 : olOverlap == OL_ONE ? 2 : 10);
  287. size_t tLeft = pSC->cColumn * 16, tTop = pSC->WMISCP.uiTileY[pSC->cTileRow] * 16;
  288. size_t tRight = (pSC->cTileColumn != pSC->WMISCP.cNumOfSliceMinus1V ? pSC->WMISCP.uiTileX[pSC->cTileColumn + 1] : pSC->cmbWidth) * 16;
  289. size_t tBottom = (pSC->cTileRow != pSC->WMISCP.cNumOfSliceMinus1H ? pSC->WMISCP.uiTileY[pSC->cTileRow + 1] : pSC->cmbHeight) * 16;
  290. // tile overlaps with ROI?
  291. pContext->m_bInROI = ((rLeft >= tRight + rExt || rTop >= tBottom + rExt || tLeft > rRight + rExt ||
  292. tTop > rBottom + rExt || pSC->cRow * 16 > rBottom + rExt) ? FALSE : TRUE);
  293. }
  294. }
  295. if(pSC->m_Dparam->bDecodeFullFrame || pContext->m_bInROI){
  296. if ((result = DecodeMacroblockDC(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK)
  297. return result;
  298. if(pSC->m_Dparam->bDecodeLP){
  299. if ((result = DecodeMacroblockLowpass(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK)
  300. return result;
  301. }
  302. predDCACDec(pSC);
  303. dequantizeMacroblock(pSC);
  304. if(pSC->m_Dparam->bDecodeHP){
  305. if ((result = DecodeMacroblockHighpass(pSC, pContext, (Int)pSC->cColumn, (Int)pSC->cRow)) != ICERR_OK)
  306. return result;
  307. predACDec(pSC);
  308. }
  309. /* keep necessary info for future prediction */
  310. updatePredInfo(pSC, &pSC->MBInfo, (Int)pSC->cColumn, pSC->m_param.cfColorFormat);
  311. }
  312. }
  313. if((!pSC->m_Dparam->bDecodeFullFrame) &&
  314. ((pSC->cColumn * 16 > pSC->m_Dparam->cROIRightX + 25) || (pSC->cColumn * 16 + 25 < pSC->m_Dparam->cROILeftX)
  315. || (pSC->cRow * 16 > pSC->m_Dparam->cROIBottomY + 25) || (pSC->cRow * 16 + 25 < pSC->m_Dparam->cROITopY)))
  316. {
  317. // do nothing
  318. }
  319. else {
  320. pSC->Transform(pSC);
  321. }
  322. if (jend) {
  323. pSC->m_pNextSC->cRow = pSC->cRow;
  324. pSC->m_pNextSC->cColumn = pSC->cColumn;
  325. pSC = pSC->m_pNextSC;
  326. }
  327. }
  328. return result;
  329. }
  330. //================================================================
  331. // Inverse Color Conversion
  332. //#define _ICC1(r, g, b) (g^=b^=g^=b, r^=g^=r^=g, b += ((g) >> 1), r += ((g) >> 1), g -= (b+3*r+2) >> 2)
  333. //#define _ICC(r, g, b) (g^=b^=g^=b, r^=g^=r^=g, b += ((g) >> 1), r += ((g) >> 1), g -= (b+3*r+2) >> 2)
  334. //================================================================
  335. //#define _ICC1(r, g, b) r -= (g >> 1), g += r, r -= ((b + 1) >> 1), b += r
  336. //#define _ICC(r, g, b) r -= (g >> 1), g += r, r -= (b >> 1), b += r
  337. #define _ICC(r, g, b) (g -= ((r + 0) >> 1), r -= ((b + 1) >> 1) - g, b += r)
  338. #define _ICC_CMYK(c, m, y, k) (k -= ((m + 1) >> 1), m -= (c >> 1) - k, c -= ((y + 1) >> 1) - m, y += c)
  339. #define _CLIP2(l, v, h) ((v) < (l) ? (l) : ((h) < (v) ? (h) : (v)))
  340. #define _CLIP8(v) ((U8)_CLIP2(0, v, 255))
  341. #define _CLIP16(v) ((I16)_CLIP2(-32768, v, 32767))
  342. #define _CLIPU16(v) ((U16)_CLIP2(0, v, 65535))
  343. #define min(a,b) (((a) < (b)) ? (a) : (b))
  344. //inverseConvert: Inverse conversion from float RGB to RGBE
  345. static _FORCEINLINE void inverseConvert (PixelI iF, U8 *pRGB, U8 *pE)
  346. {
  347. if (iF <= 0) {
  348. *pRGB = *pE = 0;
  349. }
  350. else if ((iF >> 7) > 1) {
  351. /** normal form **/
  352. *pE = (U8) (iF >> 7); //+ 1;
  353. *pRGB = (iF & 0x7f) | 0x80;
  354. }
  355. else {
  356. /** denormal form **/
  357. *pE = 1;
  358. *pRGB = (U8) iF;
  359. }
  360. }
  361. #ifdef __ANSI__
  362. #define max(a,b) ((a) > (b) ? (a) : (b))
  363. #endif // __ANSI__
  364. static _FORCEINLINE void inverseConvertRGBE (PixelI iFr, PixelI iFg, PixelI iFb, U8 *pR, U8 *pG, U8 *pB, U8 *pE)
  365. {
  366. U8 iShift;
  367. U8 pR_E, pG_E, pB_E;
  368. inverseConvert (iFr, pR, &pR_E);
  369. inverseConvert (iFg, pG, &pG_E);
  370. inverseConvert (iFb, pB, &pB_E);
  371. *pE = max(max(pR_E, pG_E), pB_E);
  372. if(*pE > pR_E){
  373. iShift = (*pE - pR_E);
  374. *pR = (U8)((((int)*pR) * 2 + 1) >> (iShift + 1));
  375. }
  376. if(*pE > pG_E){
  377. iShift = (*pE - pG_E);
  378. *pG = (U8)((((int)*pG) * 2 + 1) >> (iShift + 1));
  379. }
  380. if(*pE > pB_E){
  381. iShift = (*pE - pB_E);
  382. *pB = (U8)((((int)*pB) * 2 + 1) >> (iShift + 1));
  383. }
  384. }
  385. //pixel to float 32!
  386. static _FORCEINLINE float pixel2float(PixelI _h, const char _c, const unsigned char _lm)
  387. {
  388. union uif
  389. {
  390. I32 i;
  391. float f;
  392. } x;
  393. I32 s, iTempH, m, e, lmshift = (1 << _lm);
  394. // assert (_c <= 127);
  395. iTempH = (I32) _h ;
  396. s = (iTempH >> 31);
  397. iTempH = (iTempH ^ s) - s; // abs(iTempH)
  398. e = (U32) iTempH >> _lm;// & ((1 << (31 - _lm)) - 1);
  399. m = (iTempH & (lmshift - 1)) | lmshift; // actual mantissa, with normalizer
  400. if (e == 0) { // denormal land
  401. m ^= lmshift; // normalizer removed
  402. e = 1; // actual exponent
  403. }
  404. e += (127 - _c);
  405. while (m < lmshift && e > 1 && m > 0) { // denormal originally, see if normal is possible
  406. e--;
  407. m <<= 1;
  408. }
  409. if (m < lmshift) // truly denormal
  410. e = 0;
  411. else
  412. m ^= lmshift;
  413. m <<= (23 - _lm);
  414. x.i = (s & 0x80000000) | (e << 23) | m;
  415. return x.f;
  416. }
  417. //convert Half-16 to internal format, only need to handle sign bit
  418. static _FORCEINLINE U16 backwardHalf (PixelI hHalf)
  419. {
  420. PixelI s;
  421. s = hHalf >> 31;
  422. hHalf = ((hHalf & 0x7fff) ^ s) - s; // don't worry about overflow
  423. return (U16) hHalf;
  424. }
  425. Void interpolateUV(CWMImageStrCodec * pSC)
  426. {
  427. const COLORFORMAT cfExt = pSC->WMII.cfColorFormat;
  428. const size_t cWidth = pSC->cmbWidth * 16;
  429. PixelI * pSrcU = pSC->a0MBbuffer[1], * pSrcV = pSC->a0MBbuffer[2];
  430. PixelI * pDstU = pSC->pResU, * pDstV = pSC->pResV;
  431. size_t iRow, iColumn;
  432. size_t iIdxS = 0, iIdxD = 0;
  433. if(pSC->m_param.cfColorFormat == YUV_422){ // 422 => 444, interpolate horizontally
  434. for(iRow = 0; iRow < 16; iRow ++){
  435. for(iColumn = 0; iColumn < cWidth; iColumn += 2){
  436. iIdxS = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7];
  437. iIdxD = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  438. // copy over
  439. pDstU[iIdxD] = pSrcU[iIdxS];
  440. pDstV[iIdxD] = pSrcV[iIdxS];
  441. if(iColumn > 0){
  442. size_t iL = iColumn - 2, iIdxL = ((iL >> 4) << 8) + idxCC[iRow][iL & 15];
  443. size_t iC = iColumn - 1, iIdxC = ((iC >> 4) << 8) + idxCC[iRow][iC & 15];
  444. // interpolate
  445. pDstU[iIdxC] = ((pDstU[iIdxL] + pDstU[iIdxD] + 1) >> 1);
  446. pDstV[iIdxC] = ((pDstV[iIdxL] + pDstV[iIdxD] + 1) >> 1);
  447. }
  448. }
  449. //last pixel
  450. iIdxS = (((iColumn - 1) >> 4) << 8) + idxCC[iRow][(iColumn - 1) & 15];
  451. pDstU[iIdxS] = pDstU[iIdxD];
  452. pDstV[iIdxS] = pDstV[iIdxD];
  453. }
  454. }
  455. else{ // 420 => 422 or 444, interpolate vertically
  456. const size_t cShift = (cfExt == YUV_422 ? 3 : 4);
  457. for(iColumn = 0; iColumn < cWidth; iColumn += 2){
  458. const size_t cMB = ((iColumn >> 4) << (4 + cShift)), cPix = (iColumn >> (4 - cShift)) & ((1 << cShift) - 1);
  459. for(iRow = 0; iRow < 16; iRow += 2){
  460. iIdxS = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7];
  461. iIdxD = cMB + idxCC[iRow][cPix];
  462. // copy over
  463. pDstU[iIdxD] = pSrcU[iIdxS];
  464. pDstV[iIdxD] = pSrcV[iIdxS];
  465. if(iRow > 0){
  466. size_t iIdxT = cMB + idxCC[iRow - 2][cPix];
  467. size_t iIdxC = cMB + idxCC[iRow - 1][cPix];
  468. // interpolate
  469. pDstU[iIdxC] = ((pDstU[iIdxT] + pDstU[iIdxD] + 1) >> 1);
  470. pDstV[iIdxC] = ((pDstV[iIdxT] + pDstV[iIdxD] + 1) >> 1);
  471. }
  472. }
  473. //last row
  474. iIdxS = cMB + idxCC[15][cPix];
  475. if(pSC->cRow == pSC->cmbHeight){ // image boundary
  476. pDstU[iIdxS] = pDstU[iIdxD];
  477. pDstV[iIdxS] = pDstV[iIdxD];
  478. }
  479. else{ // need next MB row
  480. size_t iIdxB = ((iColumn >> 4) << 6) + idxCC_420[0][(iColumn >> 1) & 7];
  481. pDstU[iIdxS] = ((pSC->a1MBbuffer[1][iIdxB] + pDstU[iIdxD] + 1) >> 1);
  482. pDstV[iIdxS] = ((pSC->a1MBbuffer[2][iIdxB] + pDstV[iIdxD] + 1) >> 1);
  483. }
  484. }
  485. if(cfExt != YUV_422){ // 420 => 444, interpolate horizontally
  486. for(iRow = 0; iRow < 16; iRow ++){
  487. for(iColumn = 1; iColumn < cWidth - 2; iColumn += 2){
  488. size_t iIdxL = (((iColumn - 1) >> 4) << 8) + idxCC[iRow][(iColumn - 1) & 15];
  489. iIdxD = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  490. iIdxS = (((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15];
  491. pDstU[iIdxD] = ((pDstU[iIdxS] + pDstU[iIdxL] + 1) >> 1);
  492. pDstV[iIdxD] = ((pDstV[iIdxS] + pDstV[iIdxL] + 1) >> 1);
  493. }
  494. // last pixel
  495. iIdxD = (((cWidth - 1) >> 4) << 8) + idxCC[iRow][(cWidth - 1) & 15];
  496. pDstU[iIdxD] = pDstU[iIdxS];
  497. pDstV[iIdxD] = pDstV[iIdxS];
  498. }
  499. }
  500. }
  501. }
  502. // write one MB row of Y_ONLY/CF_ALPHA/YUV_444/N_CHANNEL to output buffer
  503. Void outputNChannel(CWMImageStrCodec * pSC, size_t iFirstRow, size_t iFirstColumn, size_t cWidth, size_t cHeight, size_t iShift, PixelI iBias)
  504. {
  505. const CWMImageInfo* pII = &pSC->WMII;
  506. const size_t cChannel = pII->cfColorFormat == Y_ONLY ? 1 : pSC->WMISCP.cChannel;
  507. // const U8 cbChannels[BDB_MAX] = {-1, 1, 2, 2, 2, 4, 4, -1, -1, };
  508. const U8 nLen = pSC->WMISCP.nLenMantissaOrShift;
  509. const I8 nExpBias = pSC->WMISCP.nExpBias;
  510. PixelI * pChannel[16];
  511. size_t iChannel, iRow, iColumn;
  512. size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16, iY;
  513. assert(cChannel <= 16);
  514. for(iChannel = 0; iChannel < cChannel; iChannel ++)
  515. pChannel[iChannel & 15] = pSC->a0MBbuffer[iChannel];
  516. if(pSC->m_bUVResolutionChange)
  517. pChannel[1] = pSC->pResU, pChannel[2] = pSC->pResV;
  518. switch(pSC->WMII.bdBitDepth){
  519. case BD_8:
  520. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  521. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  522. U8 * pDst = (U8 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];
  523. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  524. PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
  525. pDst[iChannel] = _CLIP8(p);
  526. }
  527. }
  528. }
  529. break;
  530. case BD_16:
  531. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  532. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  533. U16 * pDst = (U16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];
  534. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  535. PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
  536. p <<= nLen;
  537. pDst[iChannel] = _CLIPU16(p);
  538. }
  539. }
  540. }
  541. break;
  542. case BD_16S:
  543. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  544. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  545. I16 * pDst = (I16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];
  546. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  547. PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
  548. p <<= nLen;
  549. pDst[iChannel] = _CLIP16(p);
  550. }
  551. }
  552. }
  553. break;
  554. case BD_16F:
  555. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  556. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  557. U16 * pDst = (U16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];
  558. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  559. PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift);
  560. pDst[iChannel] = backwardHalf(p);
  561. }
  562. }
  563. }
  564. break;
  565. case BD_32:
  566. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  567. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  568. U32 * pDst = (U32 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];
  569. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  570. PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift);
  571. p <<= nLen;
  572. pDst[iChannel] = (U32)(p);
  573. }
  574. }
  575. }
  576. break;
  577. case BD_32S:
  578. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  579. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  580. I32 * pDst = (I32 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];
  581. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  582. PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift);
  583. p <<= nLen;
  584. pDst[iChannel] = (I32)(p);
  585. }
  586. }
  587. }
  588. break;
  589. case BD_32F:
  590. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  591. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  592. float * pDst = (float *)pSC->WMIBI.pv + iY + pOffsetX[iColumn];
  593. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  594. PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + iBias) >> iShift);
  595. pDst[iChannel] = pixel2float (p, nExpBias, nLen);
  596. }
  597. }
  598. }
  599. break;
  600. default:
  601. assert(0);
  602. break;
  603. }
  604. }
  605. static void fixup_Y_ONLY_to_Others(
  606. const CWMImageStrCodec* pSC,
  607. const CWMImageBufferInfo* pBI)
  608. {
  609. const CWMImageInfo* pII = &pSC->WMII;
  610. const CWMIStrCodecParam* pSCP = &pSC->WMISCP;
  611. size_t cWidth = 0, cHeight = 0;
  612. size_t idxY = 0, idxX = 0;
  613. if (CF_RGB != pII->cfColorFormat || Y_ONLY != pSCP->cfColorFormat)
  614. return;
  615. cWidth = 0 != pII->cROIWidth ? pII->cROIWidth : pII->cWidth;
  616. cHeight = 0 != pII->cROIHeight ? pII->cROIHeight : pII->cHeight;
  617. #define fixup(type, nCh) \
  618. for (idxY = 0; idxY < cHeight; ++idxY) \
  619. { \
  620. type * pT = (type *)((U8*)pBI->pv + pBI->cbStride * idxY); \
  621. for (idxX = 0; idxX < cWidth; ++idxX) \
  622. { \
  623. pT[2] = pT[1] = pT[0]; \
  624. pT += nCh; \
  625. } \
  626. } \
  627. break
  628. switch (pII->bdBitDepth)
  629. {
  630. case BD_8:
  631. fixup(U8, (pII->cBitsPerUnit >> 3));
  632. break;
  633. case BD_16:
  634. case BD_16S:
  635. case BD_16F:
  636. fixup(U16, (pII->cBitsPerUnit >> 3) / sizeof(U16));
  637. break;
  638. case BD_32:
  639. case BD_32S:
  640. case BD_32F:
  641. fixup(U32, (pII->cBitsPerUnit >> 3) / sizeof(float));
  642. break;
  643. case BD_5:
  644. case BD_10:
  645. case BD_565:
  646. default:
  647. break;
  648. }
  649. }
  650. // centralized alpha channel color conversion, small perf penalty
  651. Int outputMBRowAlpha(CWMImageStrCodec * pSC)
  652. {
  653. if(pSC->WMII.bdBitDepth == BD_8 && pSC->WMISCP.cfColorFormat == CF_RGB) // has been taken care of and optimized out
  654. return ICERR_OK;
  655. if(pSC->m_bSecondary == FALSE && pSC->m_pNextSC != NULL){ // with alpha channel
  656. const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth;
  657. const PixelI iShift = (pSC->m_param.bScaledArith ? SHIFTZERO + QPFRACBITS : 0);
  658. const size_t cHeight = min((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16);
  659. const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1);
  660. const size_t iFirstRow = ((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)), iFirstColumn = pSC->m_Dparam->cROILeftX;
  661. const size_t iAlphaPos = pSC->WMII.cLeadingPadding + (pSC->WMII.cfColorFormat == CMYK ? 4 : 3);//only RGB and CMYK may have interleaved alpha
  662. const PixelI * pA = pSC->m_pNextSC->a0MBbuffer[0];
  663. const U8 nLen = pSC->WMISCP.nLenMantissaOrShift;
  664. const I8 nExpBias = pSC->WMISCP.nExpBias;
  665. size_t iRow, iColumn;
  666. size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16, iY;
  667. if (CF_RGB != pSC->WMII.cfColorFormat && CMYK != pSC->WMII.cfColorFormat)
  668. return ICERR_ERROR;
  669. if(bd == BD_8){
  670. const PixelI iBias = (1 << (iShift + 7)) + (iShift == 0 ? 0 : (1 << (iShift - 1)));
  671. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  672. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  673. PixelI a = ((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
  674. ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = _CLIP8(a);
  675. }
  676. }
  677. else if(bd == BD_16){
  678. const PixelI iBias = (1 << (iShift + 15)) + (iShift == 0 ? 0 : (1 << (iShift - 1)));
  679. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  680. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  681. PixelI a = (((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen);
  682. ((U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = _CLIPU16(a);
  683. }
  684. }
  685. else if(bd == BD_16S){
  686. const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1)));
  687. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  688. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  689. PixelI a = (((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen);
  690. ((I16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = _CLIP16(a);
  691. }
  692. }
  693. else if(bd == BD_16F){
  694. const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1)));
  695. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  696. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  697. PixelI a = ((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
  698. ((U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = backwardHalf(a);
  699. }
  700. }
  701. else if(bd == BD_32S){
  702. const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1)));
  703. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  704. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  705. PixelI a = (((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen);
  706. ((I32 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = a;
  707. }
  708. }
  709. else if(bd == BD_32F){
  710. const PixelI iBias = (iShift == 0 ? 0 : (1 << (iShift - 1)));
  711. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  712. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  713. PixelI a = ((pA[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
  714. ((float *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY)[iAlphaPos] = pixel2float (a, nExpBias, nLen);
  715. }
  716. }
  717. else // not supported
  718. return ICERR_ERROR;
  719. }
  720. return ICERR_OK;
  721. }
  722. Int outputMBRow(CWMImageStrCodec * pSC)
  723. {
  724. const COLORFORMAT cfExt = (pSC->m_param.cfColorFormat == Y_ONLY ? Y_ONLY : pSC->WMII.cfColorFormat);
  725. const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth;
  726. const PixelI iShift = (pSC->m_param.bScaledArith ? SHIFTZERO + QPFRACBITS : 0);
  727. const size_t cHeight = min((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16);
  728. const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1);
  729. const size_t iFirstRow = ((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)), iFirstColumn = pSC->m_Dparam->cROILeftX;
  730. const PixelI *pY = pSC->a0MBbuffer[0];
  731. const PixelI *pU = (pSC->m_bUVResolutionChange ? pSC->pResU : pSC->a0MBbuffer[1]);
  732. const PixelI *pV = (pSC->m_bUVResolutionChange ? pSC->pResV : pSC->a0MBbuffer[2]);
  733. const PixelI *pA = NULL;
  734. const size_t iB = (pSC->WMII.bRGB ? 2 : 0);
  735. const size_t iR = 2 - iB;
  736. const U8 nLen = pSC->WMISCP.nLenMantissaOrShift;
  737. const I8 nExpBias = pSC->WMISCP.nExpBias;
  738. size_t iRow, iColumn, iIdx;
  739. size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * (cfExt == YUV_420 ? 8 : 16), iY;
  740. if (pSC->m_pNextSC) {
  741. assert (pSC->m_param.bScaledArith == pSC->m_pNextSC->m_param.bScaledArith); // will be relaxed later
  742. }
  743. // guard output buffer
  744. if(checkImageBuffer(pSC, pSC->WMII.oOrientation >= O_RCW ? pSC->WMII.cROIHeight : pSC->WMII.cROIWidth, cHeight - iFirstRow) != ICERR_OK)
  745. return ICERR_ERROR;
  746. if(pSC->m_bUVResolutionChange)
  747. interpolateUV(pSC);
  748. if(pSC->WMISCP.bYUVData){
  749. I32 * pDst = (I32 *)pSC->WMIBI.pv + (pSC->cRow - 1) *
  750. (pSC->m_param.cfColorFormat == YUV_420 ? 8 : 16) * pSC->WMIBI.cbStride / sizeof(I32);
  751. switch(pSC->m_param.cfColorFormat){
  752. case Y_ONLY:
  753. case YUV_444:
  754. case NCOMPONENT:
  755. {
  756. PixelI * pChannel[16];
  757. size_t iChannel;
  758. const size_t cChannel = pSC->WMII.cfColorFormat == Y_ONLY ? 1 : pSC->WMISCP.cChannel;
  759. assert(cChannel <= 16);
  760. for(iChannel = 0; iChannel < cChannel; iChannel ++)
  761. pChannel[iChannel & 15] = pSC->a0MBbuffer[iChannel];
  762. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  763. I32 * pRow = pDst;
  764. for(iColumn = iFirstColumn; iColumn < cWidth; iColumn ++){
  765. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  766. PixelI p = pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]];
  767. *pRow++ = p;
  768. }
  769. }
  770. pDst += pSC->WMIBI.cbStride / sizeof(I32);
  771. }
  772. }
  773. break;
  774. case YUV_422:
  775. {
  776. PixelI y0, y1, u, v;
  777. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  778. I32 * pRow = pDst;
  779. for(iColumn = iFirstColumn; iColumn < cWidth; iColumn += 2){
  780. iIdx = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7];
  781. u = pU[iIdx], v = pV[iIdx];
  782. y0 = pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]];
  783. y1 = pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]];
  784. pRow[0] = u, pRow[1] = y0, pRow[2] = v, pRow[3] = y1;
  785. pRow += 4;
  786. }
  787. pDst += pSC->WMIBI.cbStride / sizeof(I32);
  788. }
  789. }
  790. break;
  791. case YUV_420:
  792. {
  793. PixelI y0, y1, y2, y3, u, v;
  794. // const size_t iS4[8][4] = {{0, 1, 2, 3}, {2, 3, 0, 1}, {1, 0, 3, 2}, {3, 2, 1, 0}, {1, 3, 0, 2}, {3, 1, 2, 0}, {0, 2, 1, 3}, {2, 0, 3, 1}};
  795. for(iRow = iFirstRow; iRow < cHeight; iRow += 2){
  796. I32 * pRow = pDst;
  797. for(iColumn = iFirstColumn; iColumn < cWidth; iColumn += 2){
  798. iIdx = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7];
  799. u = pU[iIdx], v = pV[iIdx];
  800. y0 = pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]];
  801. y1 = pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]];
  802. y2 = pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]];
  803. y3 = pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]];
  804. pRow[0] = y0, pRow[1] = y1, pRow[2] = y2, pRow[3] = y3, pRow[4] = u, pRow[5] = v;
  805. pRow += 6;
  806. }
  807. pDst += pSC->WMIBI.cbStride / sizeof(I32);
  808. }
  809. }
  810. break;
  811. default:
  812. assert(0);
  813. break;
  814. }
  815. }
  816. else if(bd == BD_8){
  817. U8 * pDst;
  818. const PixelI iBias1 = 128 << iShift;
  819. const PixelI iBias2 = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0;
  820. const PixelI iBias = iBias1 + iBias2;
  821. switch(cfExt){
  822. case CF_RGB:
  823. {
  824. PixelI r, g, b, a;
  825. if (pSC->m_pNextSC && pSC->WMISCP.uAlphaMode > 0) { // RGBA
  826. pA = pSC->m_pNextSC->a0MBbuffer[0];
  827. if (pSC->m_param.bScaledArith == FALSE) {
  828. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  829. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  830. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  831. g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
  832. a = pA[iIdx] + iBias;
  833. _ICC(r, g, b);
  834. pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  835. if ((g | b | r | a) & ~0xff)
  836. pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b), pDst[3] = _CLIP8(a);
  837. else
  838. pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b, pDst[3] = (U8)(a);
  839. }
  840. }
  841. else{
  842. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  843. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  844. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  845. g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
  846. a = pA[iIdx] + iBias;
  847. _ICC(r, g, b);
  848. g >>= iShift, b >>= iShift, r >>= iShift, a >>= iShift;
  849. pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  850. if ((g | b | r | a) & ~0xff)
  851. pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b), pDst[3] = _CLIP8(a);
  852. else
  853. pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b, pDst[3] = (U8)(a);
  854. }
  855. }
  856. }
  857. else {
  858. if (pSC->m_param.bScaledArith == FALSE) {
  859. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  860. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  861. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  862. g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
  863. _ICC(r, g, b);
  864. pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  865. if ((g | b | r) & ~0xff)
  866. pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b);
  867. else
  868. pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b;
  869. }
  870. }
  871. else{
  872. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  873. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  874. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  875. g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
  876. _ICC(r, g, b);
  877. g >>= iShift, b >>= iShift, r >>= iShift;
  878. pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  879. if ((g | b | r) & ~0xff)
  880. pDst[iR] = _CLIP8(r), pDst[1] = _CLIP8(g), pDst[iB] = _CLIP8(b);
  881. else
  882. pDst[iR] = (U8)r, pDst[1] = (U8)g, pDst[iB] = (U8)b;
  883. }
  884. }
  885. }
  886. break;
  887. }
  888. case Y_ONLY:
  889. case YUV_444:
  890. case NCOMPONENT:
  891. outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias);
  892. break;
  893. case YUV_422:
  894. {
  895. PixelI y0, y1, u, v;
  896. // const ORIENTATION oO = pSC->WMII.oOrientation;
  897. // const size_t i0 = ((oO > O_FLIPV && oO <= O_RCW_FLIPVH) ? 1 : 0), i1 = 1 - i0;
  898. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  899. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn += 2){
  900. iIdx = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7];
  901. u = ((pU[iIdx] + iBias) >> iShift), v = ((pV[iIdx] + iBias) >> iShift);
  902. y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
  903. y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift);
  904. pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY;
  905. if ((y0 | y1 | u | v) & ~0xff)//UYVY
  906. pDst[0] = _CLIP8(u), pDst[1] = _CLIP8(y0), pDst[2] = _CLIP8(v), pDst[3] = _CLIP8(y1);
  907. else
  908. pDst[0] = (U8)u, pDst[1] = (U8)y0, pDst[2] = (U8)v, pDst[3] = (U8)y1;
  909. }
  910. }
  911. }
  912. break;
  913. case YUV_420:
  914. {
  915. PixelI y0, y1, y2, y3, u, v;
  916. const size_t iS4[8][4] = {{0, 1, 2, 3}, {2, 3, 0, 1}, {1, 0, 3, 2}, {3, 2, 1, 0}, {1, 3, 0, 2}, {3, 1, 2, 0}, {0, 2, 1, 3}, {2, 0, 3, 1}};
  917. const ORIENTATION oO = pSC->WMII.oOrientation;
  918. const size_t i0 = iS4[oO][0], i1 = iS4[oO][1], i2 = iS4[oO][2], i3 = iS4[oO][3];
  919. for(iRow = iFirstRow; iRow < cHeight; iRow += 2){
  920. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> 1]; iColumn < cWidth; iColumn += 2){
  921. iIdx = ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7];
  922. u = ((pU[iIdx] + iBias) >> iShift), v = ((pV[iIdx] + iBias) >> iShift);
  923. y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift);
  924. y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift);
  925. y2 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] + iBias) >> iShift);
  926. y3 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] + iBias) >> iShift);
  927. pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY;
  928. if ((y0 | y1 | y2 | y3 | u | v) & ~0xff)
  929. pDst[i0] = _CLIP8(y0), pDst[i1] = _CLIP8(y1), pDst[i2] = _CLIP8(y2), pDst[i3] = _CLIP8(y3), pDst[4] = _CLIP8(u), pDst[5] = _CLIP8(v);
  930. else
  931. pDst[i0] = (U8)y0, pDst[i1] = (U8)y1, pDst[i2] = (U8)y2, pDst[i3] = (U8)y3, pDst[4] = (U8)u, pDst[5] = (U8)v;
  932. }
  933. }
  934. }
  935. break;
  936. case CMYK:
  937. {
  938. PixelI c, m, y, k;
  939. PixelI * pK = pSC->a0MBbuffer[3];
  940. for(iRow = iFirstRow; iRow < cHeight; iRow++){
  941. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++){
  942. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  943. m = -pY[iIdx] + iBias1, c = pU[iIdx], y = -pV[iIdx], k = pK[iIdx] + iBias2;
  944. _ICC_CMYK(c, m, y, k); // color conversion
  945. c >>= iShift, m >>= iShift, y >>= iShift, k >>= iShift;
  946. pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  947. if ((c | m | y | k) & ~0xff)
  948. pDst[0] = _CLIP8(c), pDst[1] = _CLIP8(m), pDst[2] = _CLIP8(y), pDst[3] = _CLIP8(k);
  949. else
  950. pDst[0] = (U8)c, pDst[1] = (U8)m, pDst[2] = (U8)y, pDst[3] = (U8)k;
  951. }
  952. }
  953. }
  954. break;
  955. case CF_RGBE:
  956. {
  957. PixelI r, g, b;
  958. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  959. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  960. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  961. g = pY[iIdx] + iBias2, r = -pU[iIdx], b = pV[iIdx];
  962. _ICC(r, g, b);
  963. pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  964. inverseConvertRGBE (r >> iShift, g >> iShift, b >> iShift, pDst, pDst + 1, pDst + 2, pDst + 3);
  965. }
  966. }
  967. }
  968. break;
  969. default:
  970. assert(0);
  971. break;
  972. }
  973. }
  974. else if(bd == BD_16){
  975. const PixelI iBias = (((1 << 15) >> nLen) << iShift) + (iShift == 0 ? 0 : (1 << (iShift - 1)));
  976. U16 * pDst;
  977. switch(cfExt){
  978. case CF_RGB:
  979. {
  980. PixelI r, g, b;
  981. if (pSC->m_param.bScaledArith == FALSE) {
  982. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  983. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  984. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  985. g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
  986. _ICC(r, g, b);
  987. g <<= nLen, b <<= nLen, r <<= nLen;
  988. pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  989. if ((g | b | r) & ~0xffff)
  990. pDst[0] = _CLIPU16(r), pDst[1] = _CLIPU16(g), pDst[2] = _CLIPU16(b);
  991. else
  992. pDst[0] = (U16)r, pDst[1] = (U16)g, pDst[2] = (U16)b;
  993. }
  994. }
  995. else{
  996. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  997. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  998. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  999. g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
  1000. _ICC(r, g, b);
  1001. g = (g >> iShift) << nLen, b = (b >> iShift) << nLen, r = (r >> iShift) << nLen;
  1002. pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  1003. if ((g | b | r) & ~0xffff)
  1004. pDst[0] = _CLIPU16(r), pDst[1] = _CLIPU16(g), pDst[2] = _CLIPU16(b);
  1005. else
  1006. pDst[0] = (U16)r, pDst[1] = (U16)g, pDst[2] = (U16)b;
  1007. }
  1008. }
  1009. break;
  1010. }
  1011. case Y_ONLY:
  1012. case YUV_444:
  1013. case NCOMPONENT:
  1014. outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias);
  1015. break;
  1016. case YUV_422:
  1017. {
  1018. PixelI y0, y1, u, v;
  1019. const ORIENTATION oO = pSC->WMII.oOrientation;
  1020. const size_t i0 = ((oO == O_FLIPH || oO == O_FLIPVH || oO == O_RCW_FLIPV || oO == O_RCW_FLIPVH) ? 1 : 0), i1 = 1 - i0;
  1021. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  1022. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn += 2){
  1023. iIdx = ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7];
  1024. u = ((pU[iIdx] + iBias) >> iShift) << nLen, v = ((pV[iIdx] + iBias) >> iShift) << nLen;
  1025. y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen;
  1026. y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift) << nLen;
  1027. pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY;
  1028. if ((y0 | y1 | u | v) & ~0xffff)
  1029. {
  1030. pDst[i0] = _CLIPU16(u);
  1031. pDst[i1] = _CLIPU16(y0);
  1032. pDst[2] = _CLIPU16(v);
  1033. pDst[3] = _CLIPU16(y1);
  1034. }
  1035. else
  1036. {
  1037. pDst[i0] = (U16)(u);
  1038. pDst[i1] = (U16)(y0);
  1039. pDst[2] = (U16)(v);
  1040. pDst[3] = (U16)(y1);
  1041. }
  1042. }
  1043. }
  1044. }
  1045. break;
  1046. case YUV_420:
  1047. {
  1048. PixelI y0, y1, y2, y3, u, v;
  1049. const size_t iS4[8][4] = {{0, 1, 2, 3}, {2, 3, 0, 1}, {1, 0, 3, 2}, {3, 2, 1, 0}, {1, 3, 0, 2}, {3, 1, 2, 0}, {0, 2, 1, 3}, {2, 0, 3, 1}};
  1050. const ORIENTATION oO = pSC->WMII.oOrientation;
  1051. const size_t i0 = iS4[oO][0], i1 = iS4[oO][1], i2 = iS4[oO][2], i3 = iS4[oO][3];
  1052. for(iRow = iFirstRow; iRow < cHeight; iRow += 2){
  1053. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> 1]; iColumn < cWidth; iColumn += 2){
  1054. iIdx = ((iColumn >> 3) << 6) + idxCC[iRow][(iColumn >> 1) & 7];
  1055. u = ((pU[iIdx] + iBias) >> iShift) << nLen, v = ((pV[iIdx] + iBias) >> iShift) << nLen;
  1056. y0 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iBias) >> iShift) << nLen;
  1057. y1 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow][(iColumn + 1) & 15]] + iBias) >> iShift) << nLen;
  1058. y2 = ((pY[((iColumn >> 4) << 8) + idxCC[iRow + 1][iColumn & 15]] + iBias) >> iShift) << nLen;
  1059. y3 = ((pY[(((iColumn + 1) >> 4) << 8) + idxCC[iRow + 1][(iColumn + 1) & 15]] + iBias) >> iShift) << nLen;
  1060. pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> 1] + iY;
  1061. if ((y0 | y1 | y2 | y3 | u | v) & ~0xffff)
  1062. {
  1063. pDst[i0] = _CLIPU16(y0);
  1064. pDst[i1] = _CLIPU16(y1);
  1065. pDst[i2] = _CLIPU16(y2);
  1066. pDst[i3] = _CLIPU16(y3);
  1067. pDst[4] = _CLIPU16(u);
  1068. pDst[5] = _CLIPU16(v);
  1069. }
  1070. else
  1071. {
  1072. pDst[i0] = (U16)(y0);
  1073. pDst[i1] = (U16)(y1);
  1074. pDst[i2] = (U16)(y2);
  1075. pDst[i3] = (U16)(y3);
  1076. pDst[4] = (U16)(u);
  1077. pDst[5] = (U16)(v);
  1078. }
  1079. }
  1080. }
  1081. }
  1082. break;
  1083. case CMYK:
  1084. {
  1085. PixelI c, m, y, k;
  1086. PixelI * pK = pSC->a0MBbuffer[3];
  1087. const PixelI iBias1 = (32768 >> nLen) << iShift;
  1088. const PixelI iBias2 = iBias - iBias1;
  1089. for(iRow = iFirstRow; iRow < cHeight; iRow++){
  1090. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++){
  1091. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  1092. m = -pY[iIdx] + iBias1, c = pU[iIdx], y = -pV[iIdx], k = pK[iIdx] + iBias2;
  1093. _ICC_CMYK(c, m, y, k); // color conversion
  1094. c = (c >> iShift) << nLen, m = (m >> iShift) << nLen, y = (y >> iShift) << nLen, k = (k >> iShift) << nLen;
  1095. pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  1096. if ((c | m | y | k) & ~0xffff)
  1097. pDst[0] = _CLIPU16(c), pDst[1] = _CLIPU16(m), pDst[2] = _CLIPU16(y), pDst[3] = _CLIPU16(k);
  1098. else
  1099. pDst[0] = (U16)(c), pDst[1] = (U16)(m), pDst[2] = (U16)(y), pDst[3] = (U16)(k);
  1100. }
  1101. }
  1102. }
  1103. break;
  1104. default:
  1105. assert(0);
  1106. break;
  1107. }
  1108. }
  1109. else if(bd == BD_16S){
  1110. const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0;
  1111. I16 * pDst;
  1112. switch(cfExt){
  1113. case CF_RGB:
  1114. {
  1115. PixelI r, g, b;
  1116. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  1117. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  1118. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  1119. g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
  1120. _ICC(r, g, b);
  1121. r = (r >> iShift) << nLen, g = (g >> iShift) << nLen, b = (b >> iShift) << nLen;
  1122. pDst = (I16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  1123. pDst[0] = _CLIP16(r), pDst[1] = _CLIP16(g), pDst[2] = _CLIP16(b);
  1124. }
  1125. break;
  1126. }
  1127. case Y_ONLY:
  1128. case YUV_444:
  1129. case NCOMPONENT:
  1130. outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias);
  1131. break;
  1132. case CMYK:
  1133. {
  1134. PixelI c, m, y, k;
  1135. PixelI * pK = pSC->a0MBbuffer[3];
  1136. for(iRow = iFirstRow; iRow < cHeight; iRow++){
  1137. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn++){
  1138. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  1139. m = -pY[iIdx], c = pU[iIdx], y = -pV[iIdx], k = pK[iIdx] + iBias;
  1140. _ICC_CMYK(c, m, y, k); // color conversion
  1141. c = (c >> iShift) << nLen, m = (m >> iShift) << nLen, y = (y >> iShift) << nLen, k = (k >> iShift) << nLen;
  1142. pDst = (I16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  1143. pDst[0] = (I16)(c), pDst[1] = (I16)(m), pDst[2] = (I16)(y), pDst[3] = (I16)(k);
  1144. }
  1145. }
  1146. }
  1147. break;
  1148. default:
  1149. assert(0);
  1150. break;
  1151. }
  1152. }
  1153. else if(bd == BD_16F){
  1154. const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0;
  1155. U16 *pDst;
  1156. switch (cfExt)
  1157. {
  1158. case CF_RGB:
  1159. {
  1160. PixelI r, g, b;
  1161. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  1162. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  1163. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  1164. g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
  1165. _ICC(r, g, b);
  1166. pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  1167. pDst[0] = backwardHalf(r >> iShift);
  1168. pDst[1] = backwardHalf(g >> iShift);
  1169. pDst[2] = backwardHalf(b >> iShift);
  1170. }
  1171. }
  1172. break;
  1173. }
  1174. case Y_ONLY:
  1175. case YUV_444:
  1176. case NCOMPONENT:
  1177. outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias);
  1178. break;
  1179. default:
  1180. assert(0);
  1181. break;
  1182. }
  1183. }
  1184. else if(bd == BD_32){
  1185. const PixelI iBias = (((1 << 31) >> nLen) << iShift) + (iShift == 0 ? 0 : (1 << (iShift - 1)));
  1186. U32 * pDst;
  1187. switch (cfExt)
  1188. {
  1189. case CF_RGB:
  1190. {
  1191. PixelI r, g, b;
  1192. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  1193. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  1194. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  1195. g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
  1196. _ICC(r, g, b);
  1197. pDst = (U32 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  1198. pDst[0] = ((r >> iShift) << nLen);
  1199. pDst[1] = ((g >> iShift) << nLen);
  1200. pDst[2] = ((b >> iShift) << nLen);
  1201. }
  1202. }
  1203. }
  1204. break;
  1205. case Y_ONLY:
  1206. case YUV_444:
  1207. case NCOMPONENT:
  1208. {
  1209. outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias);
  1210. break;
  1211. }
  1212. default:
  1213. assert(0);
  1214. break;
  1215. }
  1216. }
  1217. else if(bd == BD_32S){
  1218. const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0;
  1219. int * pDst;
  1220. switch (cfExt)
  1221. {
  1222. case CF_RGB:
  1223. {
  1224. PixelI r, g, b;
  1225. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  1226. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  1227. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  1228. g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
  1229. _ICC(r, g, b);
  1230. pDst = (int *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  1231. pDst[0] = ((r >> iShift) << nLen);
  1232. pDst[1] = ((g >> iShift) << nLen);
  1233. pDst[2] = ((b >> iShift) << nLen);
  1234. }
  1235. }
  1236. break;
  1237. }
  1238. case Y_ONLY:
  1239. case YUV_444:
  1240. case NCOMPONENT:
  1241. outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias);
  1242. break;
  1243. default:
  1244. assert(0);
  1245. break;
  1246. }
  1247. }
  1248. else if(bd == BD_32F){
  1249. const PixelI iBias = pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0;
  1250. float * pDst;
  1251. switch (cfExt)
  1252. {
  1253. case CF_RGB:
  1254. {
  1255. PixelI r, g, b;
  1256. for(iRow = iFirstRow; iRow < cHeight; iRow ++){
  1257. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  1258. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  1259. g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
  1260. _ICC(r, g, b);
  1261. pDst = (float *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  1262. pDst[0] = pixel2float (r >> iShift, nExpBias, nLen);
  1263. pDst[1] = pixel2float (g >> iShift, nExpBias, nLen);
  1264. pDst[2] = pixel2float (b >> iShift, nExpBias, nLen);
  1265. }
  1266. }
  1267. break;
  1268. }
  1269. case Y_ONLY:
  1270. case YUV_444:
  1271. case NCOMPONENT:
  1272. outputNChannel(pSC, iFirstRow, iFirstColumn, cWidth, cHeight, iShift, iBias);
  1273. break;
  1274. default:
  1275. assert(0);
  1276. break;
  1277. }
  1278. }
  1279. else if(bd == BD_5){
  1280. const PixelI iBias = (16 << iShift) + (pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0);
  1281. PixelI r, g, b;
  1282. U16 * pDst;
  1283. assert(cfExt == CF_RGB);
  1284. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  1285. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  1286. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  1287. g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
  1288. _ICC(r, g, b);
  1289. g >>= iShift, b >>= iShift, r >>= iShift;
  1290. pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  1291. if (pSC->m_param.bRBSwapped)
  1292. pDst[0] = (U16)_CLIP2(0, b, 31) + (((U16)_CLIP2(0, g, 31)) << 5) + (((U16)_CLIP2(0, r, 31)) << 10);
  1293. else
  1294. pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 31)) << 5) + (((U16)_CLIP2(0, b, 31)) << 10);
  1295. }
  1296. }
  1297. else if(bd == BD_565){
  1298. const PixelI iBias = (32 << iShift) + (pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0);
  1299. PixelI r, g, b;
  1300. U16 * pDst;
  1301. assert(cfExt == CF_RGB);
  1302. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  1303. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  1304. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  1305. g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
  1306. _ICC(r, g, b);
  1307. g >>= iShift, b >>= iShift + 1, r >>= iShift + 1;
  1308. pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  1309. if (pSC->m_param.bRBSwapped)
  1310. pDst[0] = (U16)_CLIP2(0, b, 31) + (((U16)_CLIP2(0, g, 63)) << 5) + (((U16)_CLIP2(0, r, 31)) << 11);
  1311. else
  1312. pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 63)) << 5) + (((U16)_CLIP2(0, b, 31)) << 11);
  1313. }
  1314. }
  1315. else if(bd == BD_10){
  1316. const PixelI iBias = (512 << iShift) + (pSC->m_param.bScaledArith ? ((1 << (SHIFTZERO + QPFRACBITS - 1)) - 1) : 0);
  1317. PixelI r, g, b;
  1318. U32 * pDst;
  1319. assert(cfExt == CF_RGB);
  1320. for(iRow = iFirstRow; iRow < cHeight; iRow ++)
  1321. for(iColumn = iFirstColumn, iY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){
  1322. iIdx = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  1323. g = pY[iIdx] + iBias, r = -pU[iIdx], b = pV[iIdx];
  1324. _ICC(r, g, b);
  1325. g >>= iShift, b >>= iShift, r >>= iShift;
  1326. pDst = (U32 *)pSC->WMIBI.pv + pOffsetX[iColumn] + iY;
  1327. if (pSC->m_param.bRBSwapped)
  1328. pDst[0] = (U32)_CLIP2(0, b, 1023) +
  1329. (((U32)_CLIP2(0, g, 1023)) << 10) +
  1330. (((U32)_CLIP2(0, r, 1023)) << 20);
  1331. else
  1332. pDst[0] = (U32)_CLIP2(0, r, 1023) +
  1333. (((U32)_CLIP2(0, g, 1023)) << 10) +
  1334. (((U32)_CLIP2(0, b, 1023)) << 20);
  1335. }
  1336. }
  1337. else if(bd == BD_1){
  1338. const size_t iPos = pSC->WMII.cLeadingPadding;
  1339. const Int iTh = (iShift > 0) ? (1 << (iShift - 1)) : 1;
  1340. assert(cfExt == Y_ONLY && pSC->m_param.cfColorFormat == Y_ONLY);
  1341. if(pSC->WMII.oOrientation < O_RCW)
  1342. for(iRow = iFirstRow; iRow < cHeight; iRow ++) {
  1343. iY = pOffsetY[iRow] + iPos;
  1344. for(iColumn = iFirstColumn; iColumn < cWidth; iColumn ++) {
  1345. U8 cByte = ((U8 *)pSC->WMIBI.pv + (pOffsetX[iColumn] >> 3) + iY)[0];
  1346. U8 cShift = (U8)(7 - (pOffsetX[iColumn] & 7));
  1347. ((U8 *)pSC->WMIBI.pv + (pOffsetX[iColumn] >> 3) + iY)[0] ^= // exor is used because we can't assume the byte was originally zero
  1348. (((pSC->WMISCP.bBlackWhite + (pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] >= iTh)
  1349. + (cByte >> cShift)) & 0x1) << cShift);
  1350. }
  1351. }
  1352. else
  1353. for(iRow = iFirstRow; iRow < cHeight; iRow ++) {
  1354. iY = pOffsetY[iRow] + iPos;
  1355. for(iColumn = iFirstColumn; iColumn < cWidth; iColumn ++) {
  1356. U8 cByte = ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + (iY >> 3))[0];
  1357. U8 cShift = (U8)(7 - (iY & 7)); // should be optimized out
  1358. ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn] + (iY >> 3))[0] ^= // exor is used because we can't assume the byte was originally zero
  1359. (((pSC->WMISCP.bBlackWhite + (pY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] >= iTh)
  1360. + (cByte >> cShift)) & 0x1) << cShift);
  1361. }
  1362. }
  1363. }
  1364. if(pSC->WMISCP.uAlphaMode > 0)
  1365. if(outputMBRowAlpha(pSC) != ICERR_OK)
  1366. return ICERR_ERROR;
  1367. #ifdef REENTRANT_MODE
  1368. pSC->WMIBI.cLinesDecoded = cHeight - iFirstRow;
  1369. if (CF_RGB == pSC->WMII.cfColorFormat && Y_ONLY == pSC->WMISCP.cfColorFormat)
  1370. {
  1371. const CWMImageInfo* pII = &pSC->WMII;
  1372. #define fixupFullSize(type, nCh) \
  1373. for(iRow = iFirstRow; iRow < cHeight; iRow ++) {\
  1374. size_t iOffsetY;\
  1375. for(iColumn = iFirstColumn, iOffsetY = pOffsetY[iRow]; iColumn < cWidth; iColumn ++){\
  1376. type *pT = (type*)(U8 *)pSC->WMIBI.pv + iOffsetY + pOffsetX[iColumn];\
  1377. pT[2] = pT[1] = pT[0]; \
  1378. pT += nCh; \
  1379. } \
  1380. } \
  1381. break
  1382. switch (pII->bdBitDepth)
  1383. {
  1384. case BD_8:
  1385. fixupFullSize(U8, (pII->cBitsPerUnit >> 3));
  1386. break;
  1387. case BD_16:
  1388. case BD_16S:
  1389. case BD_16F:
  1390. fixupFullSize(U16, (pII->cBitsPerUnit >> 3) / sizeof(U16));
  1391. break;
  1392. case BD_32:
  1393. case BD_32S:
  1394. case BD_32F:
  1395. fixupFullSize(U32, (pII->cBitsPerUnit >> 3) / sizeof(float));
  1396. break;
  1397. case BD_5:
  1398. case BD_10:
  1399. case BD_565:
  1400. default:
  1401. break;
  1402. }
  1403. }
  1404. #endif
  1405. return ICERR_OK;
  1406. }
  1407. // Y_ONLY/CF_ALPHA/YUV_444/N_CHANNEL thumbnail decode
  1408. Void outputNChannelThumbnail(CWMImageStrCodec * pSC, const PixelI cMul, const size_t rShiftY, size_t iFirstRow, size_t iFirstColumn)
  1409. {
  1410. const size_t tScale = pSC->m_Dparam->cThumbnailScale;
  1411. const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1);
  1412. const size_t cHeight = min((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16);
  1413. const size_t cChannel = pSC->WMISCP.cChannel;
  1414. const U8 nLen = pSC->WMISCP.nLenMantissaOrShift;
  1415. const I8 nExpBias = pSC->WMISCP.nExpBias;
  1416. size_t nBits = 0;
  1417. PixelI iOffset;
  1418. PixelI * pChannel[16];
  1419. size_t iChannel, iRow, iColumn;
  1420. size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16 / tScale, iY;
  1421. while((size_t)(1U << nBits) < tScale)
  1422. nBits ++;
  1423. assert(cChannel <= 16);
  1424. for(iChannel = 0; iChannel < cChannel; iChannel ++)
  1425. pChannel[iChannel & 15] = pSC->a0MBbuffer[iChannel];
  1426. if(pSC->m_bUVResolutionChange)
  1427. pChannel[1] = pSC->pResU, pChannel[2] = pSC->pResV;
  1428. switch(pSC->WMII.bdBitDepth){
  1429. case BD_8:
  1430. for(iOffset = (128 << rShiftY) / cMul, iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1431. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1432. U8 * pDst = (U8 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits];
  1433. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  1434. PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iOffset) * cMul) >> rShiftY;
  1435. pDst[iChannel] = _CLIP8(p);
  1436. }
  1437. }
  1438. }
  1439. break;
  1440. case BD_16:
  1441. for(iOffset = (32768 << rShiftY) / cMul, iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1442. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1443. U16 * pDst = (U16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits];
  1444. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  1445. PixelI p = (((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iOffset) * cMul) >> rShiftY) << nLen;
  1446. pDst[iChannel] = _CLIPU16(p);
  1447. }
  1448. }
  1449. }
  1450. break;
  1451. case BD_16S:
  1452. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1453. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1454. I16 * pDst = (I16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits];
  1455. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  1456. PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY) << nLen;
  1457. pDst[iChannel] = _CLIP16(p);
  1458. }
  1459. }
  1460. }
  1461. break;
  1462. case BD_16F:
  1463. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1464. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1465. U16 * pDst = (U16 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits];
  1466. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  1467. PixelI p = (pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY;
  1468. pDst[iChannel] = backwardHalf(p);
  1469. }
  1470. }
  1471. }
  1472. break;
  1473. case BD_32:
  1474. for(iOffset = (((1 << 31) >> nLen) << rShiftY) / cMul, iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1475. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1476. U32 * pDst = (U32 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits];
  1477. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  1478. PixelI p = (((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] + iOffset) * cMul) >> rShiftY) << nLen;
  1479. pDst[iChannel] = (U32)(p);
  1480. }
  1481. }
  1482. }
  1483. break;
  1484. case BD_32S:
  1485. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1486. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1487. I32 * pDst = (I32 *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits];
  1488. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  1489. PixelI p = ((pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY) << nLen;
  1490. pDst[iChannel] = (I32)(p);
  1491. }
  1492. }
  1493. }
  1494. break;
  1495. case BD_32F:
  1496. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1497. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1498. float * pDst = (float *)pSC->WMIBI.pv + iY + pOffsetX[iColumn >> nBits];
  1499. for(iChannel = 0; iChannel < cChannel; iChannel ++){
  1500. PixelI p = (pChannel[iChannel & 15][((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] * cMul) >> rShiftY;
  1501. pDst[iChannel] = pixel2float (p, nExpBias, nLen);
  1502. }
  1503. }
  1504. }
  1505. break;
  1506. default:
  1507. assert(0);
  1508. break;
  1509. }
  1510. }
  1511. // centralized alpha channel thumbnail, small perf penalty
  1512. Int decodeThumbnailAlpha(CWMImageStrCodec * pSC, const size_t nBits, const PixelI cMul, const size_t rShiftY)
  1513. {
  1514. if(pSC->m_bSecondary == FALSE && pSC->m_pNextSC != NULL){ // with alpha channel
  1515. const size_t tScale = (size_t)(1U << nBits);
  1516. const size_t cHeight = min((pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16);
  1517. const size_t cWidth = (pSC->m_Dparam->cROIRightX + 1);
  1518. const size_t iFirstRow = ((((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)) + tScale - 1) / tScale * tScale);
  1519. const size_t iFirstColumn = (pSC->m_Dparam->cROILeftX + tScale - 1) / tScale * tScale;
  1520. const size_t iAlphaPos = pSC->WMII.cLeadingPadding + (pSC->WMII.cfColorFormat == CMYK ? 4 : 3);//only RGB and CMYK may have interleaved alpha
  1521. const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth;
  1522. const PixelI * pSrc = pSC->m_pNextSC->a0MBbuffer[0];
  1523. const U8 nLen = pSC->m_pNextSC->WMISCP.nLenMantissaOrShift;
  1524. const I8 nExpBias = pSC->m_pNextSC->WMISCP.nExpBias;
  1525. size_t iRow, iColumn;
  1526. size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16 / tScale, iY;
  1527. if (CF_RGB != pSC->WMII.cfColorFormat && CMYK != pSC->WMII.cfColorFormat)
  1528. return ICERR_ERROR;
  1529. if(bd == BD_8){
  1530. const PixelI offset = (128 << rShiftY) / cMul;
  1531. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
  1532. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1533. PixelI a = ((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + offset) * cMul) >> rShiftY;
  1534. ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = _CLIP8(a);
  1535. }
  1536. }
  1537. else if(bd == BD_16){
  1538. const PixelI offset = (32768 << rShiftY) / cMul;
  1539. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
  1540. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1541. PixelI a = (((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] + offset) * cMul) >> rShiftY) << nLen;
  1542. ((U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = _CLIPU16(a);
  1543. }
  1544. }
  1545. else if(bd == BD_16S){
  1546. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
  1547. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1548. PixelI a = ((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY) << nLen;
  1549. ((I16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = _CLIP16(a);
  1550. }
  1551. }
  1552. else if(bd == BD_16F){
  1553. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
  1554. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1555. PixelI a = (pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY;
  1556. ((U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = backwardHalf(a);
  1557. }
  1558. }
  1559. else if(bd == BD_32S){
  1560. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
  1561. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1562. PixelI a = ((pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY) << nLen;
  1563. ((I32 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = a;
  1564. }
  1565. }
  1566. else if(bd == BD_32F){
  1567. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
  1568. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1569. PixelI a = (pSrc[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf]] * cMul) >> rShiftY;
  1570. ((float *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY)[iAlphaPos] = pixel2float (a, nExpBias, nLen);
  1571. }
  1572. }
  1573. else // not supported
  1574. return ICERR_ERROR;
  1575. }
  1576. return ICERR_OK;
  1577. }
  1578. Int decodeThumbnail(CWMImageStrCodec * pSC)
  1579. {
  1580. const size_t tScale = pSC->m_Dparam->cThumbnailScale;
  1581. const size_t cHeight = min((pSC->m_Dparam->bDecodeFullFrame ? pSC->WMII.cHeight : pSC->m_Dparam->cROIBottomY + 1) - (pSC->cRow - 1) * 16, 16);
  1582. const size_t cWidth = (pSC->m_Dparam->bDecodeFullFrame ? pSC->WMII.cWidth : pSC->m_Dparam->cROIRightX + 1);
  1583. const size_t iFirstRow = ((((pSC->cRow - 1) * 16 > pSC->m_Dparam->cROITopY ? 0 : (pSC->m_Dparam->cROITopY & 0xf)) + tScale - 1) / tScale * tScale);
  1584. const size_t iFirstColumn = (pSC->m_Dparam->cROILeftX + tScale - 1) / tScale * tScale;
  1585. const COLORFORMAT cfInt = pSC->m_param.cfColorFormat;
  1586. const COLORFORMAT cfExt = (pSC->m_param.cfColorFormat == Y_ONLY ? Y_ONLY : pSC->WMII.cfColorFormat);
  1587. const BITDEPTH_BITS bd = pSC->WMII.bdBitDepth;
  1588. const OVERLAP ol = pSC->WMISCP.olOverlap;
  1589. const size_t iB = (pSC->WMII.bRGB ? 2 : 0);
  1590. const size_t iR = 2 - iB;
  1591. const U8 nLen = pSC->WMISCP.nLenMantissaOrShift;
  1592. const I8 nExpBias = pSC->WMISCP.nExpBias;
  1593. PixelI offset;
  1594. size_t iRow, iColumn, iIdx1, iIdx2, iIdx3 = 0, nBits = 0;
  1595. PixelI * pSrcY = pSC->a0MBbuffer[0];
  1596. PixelI * pSrcU = pSC->a0MBbuffer[1], * pSrcV = pSC->a0MBbuffer[2];
  1597. size_t * pOffsetX = pSC->m_Dparam->pOffsetX, * pOffsetY = pSC->m_Dparam->pOffsetY + (pSC->cRow - 1) * 16 / tScale, iY;
  1598. const PixelI cMul = (tScale >= 16 ? (ol == OL_NONE ? 16 : (ol == OL_ONE ? 23 : 34)) : (tScale >= 4 ? (ol == OL_NONE ? 64 : 93) : 258));
  1599. const size_t rShiftY = 8 + (pSC->m_param.bScaledArith ? (SHIFTZERO + QPFRACBITS) : 0);
  1600. const size_t rShiftUV = rShiftY - ((pSC->m_param.bScaledArith && tScale >= 16) ? ((cfInt == YUV_420 || cfInt == YUV_422) ? 2 : 1) : 0);
  1601. while((size_t)(1U << nBits) < tScale)
  1602. nBits ++;
  1603. assert(tScale == (size_t)(1U << nBits));
  1604. // guard output buffer
  1605. if(checkImageBuffer(pSC, pSC->WMII.oOrientation < O_RCW ? pSC->WMII.cROIWidth : pSC->WMII.cROIHeight, (cHeight - iFirstRow) / pSC->m_Dparam->cThumbnailScale) != ICERR_OK)
  1606. return ICERR_ERROR;
  1607. if((((pSC->cRow - 1) * 16) % tScale) != 0)
  1608. return ICERR_OK;
  1609. if(pSC->cRow * 16 <= pSC->m_Dparam->cROITopY || pSC->cRow * 16 > pSC->m_Dparam->cROIBottomY + 16)
  1610. return ICERR_OK;
  1611. if((cfInt == YUV_422 || cfInt == YUV_420) && cfExt != Y_ONLY){
  1612. PixelI * pDstU = pSC->pResU, * pDstV = pSC->pResV;
  1613. for(iRow = 0; iRow < 16; iRow += tScale){
  1614. for(iColumn = 0; iColumn < cWidth; iColumn += tScale){
  1615. iIdx1 = (cfInt == YUV_422 ? ((iColumn >> 4) << 7) + idxCC[iRow][(iColumn >> 1) & 7] : ((iColumn >> 4) << 6) + idxCC_420[iRow >> 1][(iColumn >> 1) & 7]);
  1616. iIdx2 = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  1617. // copy over
  1618. pDstU[iIdx2] = pSrcU[iIdx1];
  1619. pDstV[iIdx2] = pSrcV[iIdx1];
  1620. }
  1621. }
  1622. if(tScale == 4){
  1623. if(cfInt == YUV_420){
  1624. for(iColumn = 0; iColumn < cWidth; iColumn += 8){
  1625. iIdx1 = ((iColumn >> 4) << 8) + idxCC[0][iColumn & 15];
  1626. iIdx2 = ((iColumn >> 4) << 8) + idxCC[4][iColumn & 15];
  1627. iIdx3 = ((iColumn >> 4) << 8) + idxCC[8][iColumn & 15];
  1628. pDstU[iIdx2] = ((pDstU[iIdx1] + pDstU[iIdx3] + 1) >> 1);
  1629. pDstV[iIdx2] = ((pDstV[iIdx1] + pDstV[iIdx3] + 1) >> 1);
  1630. iIdx1 = ((iColumn >> 4) << 8) + idxCC[12][iColumn & 15];
  1631. pDstU[iIdx1] = pDstU[iIdx3];
  1632. pDstV[iIdx1] = pDstV[iIdx3];
  1633. }
  1634. }
  1635. for(iRow = 0; iRow < 16; iRow += 4){
  1636. for(iColumn = 0; iColumn < cWidth - 8; iColumn += 8){
  1637. iIdx1 = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15];
  1638. iIdx2 = ((iColumn >> 4) << 8) + idxCC[iRow][(iColumn + 4) & 15];
  1639. iIdx3 = ((iColumn >> 4) << 8) + idxCC[iRow][(iColumn + 8) & 15];
  1640. pDstU[iIdx2] = ((pDstU[iIdx1] + pDstU[iIdx3] + 1) >> 1);
  1641. pDstV[iIdx2] = ((pDstV[iIdx1] + pDstV[iIdx3] + 1) >> 1);
  1642. }
  1643. iIdx2 = ((iColumn >> 4) << 8) + idxCC[iRow][(iColumn + 4) & 15];
  1644. pDstU[iIdx2] = pDstU[iIdx3];
  1645. pDstV[iIdx2] = pDstV[iIdx3];
  1646. }
  1647. }
  1648. pSrcU = pDstU, pSrcV = pDstV;
  1649. }
  1650. if(bd == BD_8){
  1651. U8 * pDst;
  1652. offset = (128 << rShiftY) / cMul;
  1653. switch(cfExt){
  1654. case CF_RGB:
  1655. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1656. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1657. size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
  1658. PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
  1659. _ICC(r, g, b);
  1660. pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
  1661. pDst[iB] = _CLIP8(b), pDst[1] = _CLIP8(g), pDst[iR] = _CLIP8(r);
  1662. }
  1663. }
  1664. break;
  1665. case Y_ONLY:
  1666. case YUV_444:
  1667. case NCOMPONENT:
  1668. outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn);
  1669. break;
  1670. case CF_RGBE:
  1671. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1672. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1673. size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
  1674. PixelI g = ((pSrcY[iPos] * cMul) >> rShiftY), r = - ((pSrcU[iPos] * cMul) >> rShiftUV), b = ((pSrcV[iPos] * cMul) >> rShiftUV);
  1675. _ICC(r, g, b);
  1676. pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
  1677. inverseConvertRGBE (r, g, b, pDst, pDst + 1, pDst + 2, pDst + 3);
  1678. }
  1679. }
  1680. break;
  1681. case CMYK:
  1682. {
  1683. PixelI * pSrcK = pSC->a0MBbuffer[3];
  1684. PixelI iBias1 = (128 << rShiftY) / cMul, iBias2 = (((128 << rShiftUV) / cMul) >> 1);
  1685. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1686. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1687. size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
  1688. PixelI m = ((-pSrcY[iPos] + iBias1) * cMul) >> rShiftY, c = (pSrcU[iPos] * cMul) >> rShiftUV, y = -(pSrcV[iPos] * cMul) >> rShiftUV, k = ((pSrcK[iPos] + iBias2) * cMul) >> rShiftUV;
  1689. _ICC_CMYK(c, m, y, k);
  1690. pDst = (U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
  1691. pDst[0] = _CLIP8(c), pDst[1] = _CLIP8(m), pDst[2] = _CLIP8(y), pDst[3] = _CLIP8(k);
  1692. }
  1693. }
  1694. break;
  1695. }
  1696. default:
  1697. assert(0);
  1698. break;
  1699. }
  1700. }
  1701. if(bd == BD_16){
  1702. U16 * pDst;
  1703. offset = (((1 << 15) >> nLen) << rShiftY) / cMul;
  1704. switch(cfExt){
  1705. case CF_RGB:
  1706. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1707. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1708. size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
  1709. PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
  1710. _ICC(r, g, b);
  1711. pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
  1712. r <<= nLen, g <<= nLen, b <<= nLen;
  1713. pDst[0] = _CLIPU16(r);
  1714. pDst[1] = _CLIPU16(g);
  1715. pDst[2] = _CLIPU16(b);
  1716. }
  1717. }
  1718. break;
  1719. case Y_ONLY:
  1720. case YUV_444:
  1721. case NCOMPONENT:
  1722. outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn);
  1723. break;
  1724. case CMYK:
  1725. {
  1726. PixelI * pSrcK = pSC->a0MBbuffer[3];
  1727. PixelI iBias1 = (32768 << rShiftY) / cMul, iBias2 = (((32768 << rShiftUV) / cMul) >> 1);
  1728. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1729. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1730. size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
  1731. PixelI m = ((-pSrcY[iPos] + iBias1) * cMul) >> rShiftY, c = (pSrcU[iPos] * cMul) >> rShiftUV, y = -(pSrcV[iPos] * cMul) >> rShiftUV, k = ((pSrcK[iPos] + iBias2) * cMul) >> rShiftUV;
  1732. _ICC_CMYK(c, m, y, k);
  1733. pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
  1734. c <<= nLen, m <<= nLen, y <<= nLen, k <<= nLen;
  1735. pDst[0] = _CLIPU16(c);
  1736. pDst[1] = _CLIPU16(m);
  1737. pDst[2] = _CLIPU16(y);
  1738. pDst[3] = _CLIPU16(k);
  1739. }
  1740. }
  1741. break;
  1742. }
  1743. default:
  1744. assert(0);
  1745. break;
  1746. }
  1747. }
  1748. if(bd == BD_16S){
  1749. I16 * pDst;
  1750. switch(cfExt){
  1751. case CF_RGB:
  1752. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1753. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1754. size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
  1755. PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
  1756. _ICC(r, g, b);
  1757. pDst = (I16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
  1758. r <<= nLen, g <<= nLen, b <<= nLen;
  1759. pDst[0] = _CLIP16(r);
  1760. pDst[1] = _CLIP16(g);
  1761. pDst[2] = _CLIP16(b);
  1762. }
  1763. }
  1764. break;
  1765. case Y_ONLY:
  1766. case YUV_444:
  1767. case NCOMPONENT:
  1768. outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn);
  1769. break;
  1770. case CMYK:
  1771. {
  1772. PixelI * pSrcK = pSC->a0MBbuffer[3];
  1773. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1774. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1775. size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
  1776. PixelI m = -(pSrcY[iPos] * cMul) >> rShiftY, c = (pSrcU[iPos] * cMul) >> rShiftUV, y = -(pSrcV[iPos] * cMul) >> rShiftUV, k = (pSrcK[iPos] * cMul) >> rShiftUV;
  1777. _ICC_CMYK(c, m, y, k);
  1778. pDst = (I16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
  1779. c <<= nLen, m <<= nLen, y <<= nLen, k <<= nLen;
  1780. pDst[0] = _CLIP16(c);
  1781. pDst[1] = _CLIP16(m);
  1782. pDst[2] = _CLIP16(y);
  1783. pDst[3] = _CLIP16(k);
  1784. }
  1785. }
  1786. }
  1787. break;
  1788. default:
  1789. assert(0);
  1790. break;
  1791. }
  1792. }
  1793. else if(bd == BD_16F){
  1794. U16 * pDst;
  1795. switch(cfExt){
  1796. case CF_RGB:
  1797. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1798. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1799. size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
  1800. PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
  1801. _ICC(r, g, b);
  1802. pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
  1803. pDst[0] = backwardHalf (r);
  1804. pDst[1] = backwardHalf (g);
  1805. pDst[2] = backwardHalf (b);
  1806. }
  1807. }
  1808. break;
  1809. case Y_ONLY:
  1810. case YUV_444:
  1811. case NCOMPONENT:
  1812. outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn);
  1813. break;
  1814. default:
  1815. assert(0);
  1816. break;
  1817. }
  1818. }
  1819. else if(bd == BD_32){
  1820. U32 * pDst;
  1821. offset = (((1 << 31) >> nLen) << rShiftY) / cMul;
  1822. switch(cfExt){
  1823. case CF_RGB:
  1824. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1825. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1826. size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
  1827. PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
  1828. _ICC(r, g, b);
  1829. pDst = (U32 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
  1830. pDst[0] = (U32)(r << nLen);
  1831. pDst[1] = (U32)(g << nLen);
  1832. pDst[2] = (U32)(b << nLen);
  1833. }
  1834. }
  1835. break;
  1836. case Y_ONLY:
  1837. case YUV_444:
  1838. case NCOMPONENT:
  1839. outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn);
  1840. break;
  1841. default:
  1842. assert(0);
  1843. break;
  1844. }
  1845. }
  1846. else if(bd == BD_32S){
  1847. I32 * pDst;
  1848. switch(cfExt){
  1849. case CF_RGB:
  1850. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1851. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1852. size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
  1853. PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
  1854. _ICC(r, g, b);
  1855. pDst = (I32 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
  1856. pDst[0] = (I32)(r << nLen);
  1857. pDst[1] = (I32)(g << nLen);
  1858. pDst[2] = (I32)(b << nLen);
  1859. }
  1860. }
  1861. break;
  1862. case Y_ONLY:
  1863. case YUV_444:
  1864. case NCOMPONENT:
  1865. outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn);
  1866. break;
  1867. default:
  1868. assert(0);
  1869. break;
  1870. }
  1871. }
  1872. else if(bd == BD_32F){
  1873. float * pDst;
  1874. switch(cfExt){
  1875. case CF_RGB:
  1876. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1877. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1878. size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
  1879. PixelI g = (pSrcY[iPos] * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
  1880. _ICC(r, g, b);
  1881. pDst = (float *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
  1882. pDst[0] = pixel2float (r, nExpBias, nLen);
  1883. pDst[1] = pixel2float (g, nExpBias, nLen);
  1884. pDst[2] = pixel2float (b, nExpBias, nLen);
  1885. }
  1886. }
  1887. break;
  1888. case Y_ONLY:
  1889. case YUV_444:
  1890. case NCOMPONENT:
  1891. outputNChannelThumbnail(pSC, cMul, rShiftY, iFirstRow, iFirstColumn);
  1892. break;
  1893. default:
  1894. assert(0);
  1895. break;
  1896. }
  1897. }
  1898. else if(bd == BD_1){
  1899. const size_t iPos = pSC->WMII.cLeadingPadding;
  1900. Bool bBW;
  1901. U8 cByte, cShift;
  1902. assert(cfExt == Y_ONLY && pSC->m_param.cfColorFormat == Y_ONLY);
  1903. if(pSC->WMII.oOrientation < O_RCW){
  1904. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
  1905. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits] + iPos; iColumn < cWidth; iColumn += tScale){
  1906. bBW = (pSC->WMISCP.bBlackWhite ^ (pSrcY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] > 0));
  1907. cByte = ((U8 *)pSC->WMIBI.pv + (pOffsetX[iColumn >> nBits] >> 3) + iY)[0];
  1908. cShift = (U8)(7 - (pOffsetX[iColumn >> nBits] & 7));
  1909. ((U8 *)pSC->WMIBI.pv + (pOffsetX[iColumn >> nBits] >> 3) + iY)[0] ^= ((((bBW + (cByte >> cShift)) & 0x1)) << cShift);
  1910. }
  1911. }
  1912. else{
  1913. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale)
  1914. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits] + iPos; iColumn < cWidth; iColumn += tScale){
  1915. bBW = (pSC->WMISCP.bBlackWhite ^ (pSrcY[((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 15]] > 0));
  1916. cByte = ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + (iY >> 3))[0];
  1917. cShift = (U8)(7 - (iY & 7));
  1918. ((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + (iY >> 3))[0] ^= ((((bBW + (cByte >> cShift)) & 0x1)) << cShift);
  1919. }
  1920. }
  1921. }
  1922. else if(bd == BD_5){
  1923. U16 * pDst;
  1924. offset = (16 << rShiftY) / cMul;
  1925. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1926. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1927. size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
  1928. PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
  1929. _ICC(r, g, b);
  1930. pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
  1931. pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 31)) << 5) + (((U16)_CLIP2(0, b, 31)) << 10);
  1932. }
  1933. }
  1934. }
  1935. else if(bd == BD_565){
  1936. U16 * pDst;
  1937. offset = (32 << rShiftY) / cMul;
  1938. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1939. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1940. size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
  1941. PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
  1942. _ICC(r, g, b);
  1943. r /= 2, b /= 2;
  1944. pDst = (U16 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
  1945. pDst[0] = (U16)_CLIP2(0, r, 31) + (((U16)_CLIP2(0, g, 63)) << 5) + (((U16)_CLIP2(0, b, 31)) << 11);
  1946. }
  1947. }
  1948. }
  1949. else if(bd == BD_10){
  1950. U32 * pDst;
  1951. offset = (512 << rShiftY) / cMul;
  1952. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale){
  1953. for(iColumn = iFirstColumn, iY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){
  1954. size_t iPos = ((iColumn >> 4) << 8) + idxCC[iRow][iColumn & 0xf];
  1955. PixelI g = ((pSrcY[iPos] + offset) * cMul) >> rShiftY, r = -(pSrcU[iPos] * cMul) >> rShiftUV, b = (pSrcV[iPos] * cMul) >> rShiftUV;
  1956. _ICC(r, g, b);
  1957. pDst = (U32 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iY;
  1958. pDst[0] = (U32)_CLIP2(0, r, 1023) +
  1959. (((U32)_CLIP2(0, g, 1023)) << 10) +
  1960. (((U32)_CLIP2(0, b, 1023)) << 20);
  1961. }
  1962. }
  1963. }
  1964. if(pSC->WMISCP.uAlphaMode > 0)
  1965. if(decodeThumbnailAlpha(pSC, nBits, cMul, rShiftY) != ICERR_OK)
  1966. return ICERR_ERROR;
  1967. #ifdef REENTRANT_MODE
  1968. pSC->WMIBI.cLinesDecoded = ( cHeight - iFirstRow + tScale - 1 ) / tScale;
  1969. if (CF_RGB == pSC->WMII.cfColorFormat && Y_ONLY == pSC->WMISCP.cfColorFormat)
  1970. {
  1971. const CWMImageInfo* pII = &pSC->WMII;
  1972. #define fixupThumb(type, nCh) \
  1973. for(iRow = iFirstRow; iRow < cHeight; iRow += tScale) {\
  1974. size_t iOffsetY;\
  1975. for(iColumn = iFirstColumn, iOffsetY = pOffsetY[iRow >> nBits]; iColumn < cWidth; iColumn += tScale){\
  1976. type *pT = (type*)((U8 *)pSC->WMIBI.pv + pOffsetX[iColumn >> nBits] + iOffsetY);\
  1977. pT[iB] = pT[1] = pT[iR]; \
  1978. } \
  1979. } \
  1980. break
  1981. switch (pII->bdBitDepth)
  1982. {
  1983. case BD_8:
  1984. fixupThumb(U8, (pII->cBitsPerUnit >> 3));
  1985. break;
  1986. case BD_16:
  1987. case BD_16S:
  1988. case BD_16F:
  1989. fixupThumb(U16, (pII->cBitsPerUnit >> 3) / sizeof(U16));
  1990. break;
  1991. case BD_32:
  1992. case BD_32S:
  1993. case BD_32F:
  1994. fixupThumb(U32, (pII->cBitsPerUnit >> 3) / sizeof(float));
  1995. break;
  1996. case BD_5:
  1997. case BD_10:
  1998. case BD_565:
  1999. default:
  2000. break;
  2001. }
  2002. }
  2003. #endif
  2004. return ICERR_OK;
  2005. }
  2006. /*************************************************************************
  2007. Read variable length byte aligned integer
  2008. *************************************************************************/
  2009. static size_t GetVLWordEsc(BitIOInfo* pIO, Int *iEscape)
  2010. {
  2011. size_t s;
  2012. if (iEscape)
  2013. *iEscape = 0;
  2014. s = getBit32(pIO, 8);
  2015. if (s == 0xfd || s == 0xfe || s == 0xff) {
  2016. if (iEscape)
  2017. *iEscape = (Int) s;
  2018. s = 0;
  2019. }
  2020. else if (s < 0xfb) {
  2021. s = (s << 8) | getBit32(pIO, 8);
  2022. }
  2023. else {
  2024. s -= 0xfb;
  2025. if (s) {
  2026. s = getBit32(pIO, 16) << 16;
  2027. s = (s | getBit32(pIO, 16)) << 16;
  2028. s <<= 16;
  2029. }
  2030. s |= (getBit32(pIO, 16) << 16);
  2031. s |= getBit32(pIO, 16);
  2032. }
  2033. return s;
  2034. }
  2035. //================================================================
  2036. Int readIndexTable(CWMImageStrCodec * pSC)
  2037. {
  2038. BitIOInfo* pIO = pSC->pIOHeader;
  2039. readIS_L1(pSC, pIO);
  2040. if(pSC->cNumBitIO > 0){
  2041. size_t *pTable = pSC->pIndexTable;
  2042. U32 iEntry = (U32)pSC->cNumBitIO * (pSC->WMISCP.cNumOfSliceMinus1H + 1), i;
  2043. // read index table header [0x0001] - 2 bytes
  2044. if (getBit32(pIO, 16) != 1)
  2045. return ICERR_ERROR;
  2046. //iBits = getBit16(pIO, 5) + 1; // how many bits per entry
  2047. for(i = 0; i < iEntry; i ++){
  2048. readIS_L1(pSC, pIO);
  2049. pTable[i] = GetVLWordEsc(pIO, NULL); // escape handling is not important since the respective band is not accessed
  2050. }
  2051. }
  2052. pSC->cHeaderSize = GetVLWordEsc(pIO, NULL); // escape handling is not important
  2053. flushToByte(pIO);
  2054. pSC->cHeaderSize += getPosRead(pSC->pIOHeader); // get header length
  2055. return ICERR_OK;
  2056. }
  2057. Int StrIODecInit(CWMImageStrCodec* pSC)
  2058. {
  2059. if(allocateBitIOInfo(pSC) != ICERR_OK){
  2060. return ICERR_ERROR;
  2061. }
  2062. attachISRead(pSC->pIOHeader, pSC->WMISCP.pWStream, pSC);
  2063. readIndexTable(pSC);
  2064. if(pSC->WMISCP.bVerbose){
  2065. U32 i, j;
  2066. printf("\n%d horizontal tiles:\n", pSC->WMISCP.cNumOfSliceMinus1H + 1);
  2067. for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1H; i ++){
  2068. printf(" offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileY[i]);
  2069. }
  2070. printf("\n%d vertical tiles:\n", pSC->WMISCP.cNumOfSliceMinus1V + 1);
  2071. for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){
  2072. printf(" offset of tile %d in MBs: %d\n", i, pSC->WMISCP.uiTileX[i]);
  2073. }
  2074. if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){
  2075. printf("\nSpatial order bitstream\n");
  2076. }
  2077. else{
  2078. printf("\nFrequency order bitstream\n");
  2079. }
  2080. if(!pSC->m_param.bIndexTable){
  2081. printf("\nstreaming mode, no index table.\n");
  2082. }
  2083. else if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){
  2084. for(j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j ++){
  2085. for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){
  2086. size_t * p = &pSC->pIndexTable[j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i];
  2087. if(i + j != pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V){
  2088. printf("bitstream size for tile (%d, %d): %d.\n", j, i, (int) (p[1] - p[0]));
  2089. }
  2090. else{
  2091. printf("bitstream size for tile (%d, %d): unknown.\n", j, i);
  2092. }
  2093. }
  2094. }
  2095. }
  2096. else{
  2097. for(j = 0; j <= pSC->WMISCP.cNumOfSliceMinus1H; j ++){
  2098. for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){
  2099. size_t * p = &pSC->pIndexTable[(j * (pSC->WMISCP.cNumOfSliceMinus1V + 1) + i) * 4];
  2100. if(i + j != pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V){
  2101. printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d %d.\n", j, i,
  2102. (int) (p[1] - p[0]), (int) (p[2] - p[1]), (int) (p[3] - p[2]), (int) (p[4] - p[3]));
  2103. }
  2104. else{
  2105. printf("bitstream size of (DC, LP, AC, FL) for tile (%d, %d): %d %d %d unknown.\n", j, i,
  2106. (int) (p[1] - p[0]), (int) (p[2] - p[1]), (int) (p[3] - p[2]));
  2107. }
  2108. }
  2109. }
  2110. }
  2111. }
  2112. return 0;
  2113. }
  2114. Int StrIODecTerm(CWMImageStrCodec* pSC)
  2115. {
  2116. detachISRead(pSC, pSC->pIOHeader);
  2117. free(pSC->m_ppBitIO);
  2118. free(pSC->pIndexTable);
  2119. return 0;
  2120. }
  2121. Int initLookupTables(CWMImageStrCodec* pSC)
  2122. {
  2123. static const U8 cbChannels[BDB_MAX] = {1, 1, 2, 2, 2, 4, 4, 4, (U8) -1, (U8) -1, (U8) -1 };
  2124. CWMImageInfo * pII = &pSC->WMII;
  2125. size_t cStrideX, cStrideY;
  2126. size_t w, h, i, iFirst = 0;
  2127. Bool bReverse;
  2128. // lookup tables for rotation and flipping
  2129. if(pSC->m_Dparam->cThumbnailScale > 1) // thumbnail
  2130. w = pII->cThumbnailWidth, h = pII->cThumbnailHeight;
  2131. else
  2132. w = pII->cWidth, h = pII->cHeight;
  2133. w += (pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale;
  2134. h += (pSC->m_Dparam->cROITopY + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale;
  2135. switch(pII->bdBitDepth){
  2136. case BD_16:
  2137. case BD_16S:
  2138. case BD_5:
  2139. case BD_565:
  2140. case BD_16F:
  2141. cStrideY = pSC->WMIBI.cbStride / 2;
  2142. break;
  2143. case BD_32:
  2144. case BD_32S:
  2145. case BD_32F:
  2146. case BD_10:
  2147. cStrideY = pSC->WMIBI.cbStride / 4;
  2148. break;
  2149. default: //BD_8, BD_1
  2150. cStrideY = pSC->WMIBI.cbStride;
  2151. break;
  2152. }
  2153. switch(pII->cfColorFormat){
  2154. case YUV_420:
  2155. cStrideX = 6;
  2156. w >>= 1, h >>= 1;
  2157. break;
  2158. case YUV_422:
  2159. cStrideX = 4;
  2160. w >>= 1;
  2161. break;
  2162. default:
  2163. cStrideX = (pII->cBitsPerUnit >> 3) / cbChannels[pII->bdBitDepth];
  2164. break;
  2165. }
  2166. if(pII->bdBitDepth == BD_1 || pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_10 || pII->bdBitDepth == BD_565)
  2167. cStrideX = 1;
  2168. if(pII->oOrientation > O_FLIPVH) // rotated !!
  2169. i =cStrideX, cStrideX = cStrideY, cStrideY = i;
  2170. pSC->m_Dparam->pOffsetX = (size_t *)malloc(w * sizeof(size_t));
  2171. if(pSC->m_Dparam->pOffsetX == NULL || w * sizeof(size_t) < w)
  2172. return ICERR_ERROR;
  2173. /*
  2174. consider a row in the source image. if it becomes a reversed row in the target, or a reversed (upside-down)column
  2175. in the target, we have to reverse the offsets. bReverse here tells us when this happened.
  2176. */
  2177. bReverse = (pII->oOrientation == O_FLIPH || pII->oOrientation == O_FLIPVH ||
  2178. pII->oOrientation == O_RCW_FLIPV || pII->oOrientation == O_RCW_FLIPVH);
  2179. if(!pSC->m_Dparam->bDecodeFullFrame) // take care of region decode here!
  2180. iFirst = (pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale;
  2181. for(i = 0; i + iFirst < w; i ++){
  2182. pSC->m_Dparam->pOffsetX[i + iFirst] = pII->cLeadingPadding + (bReverse ? (pSC->m_Dparam->bDecodeFullFrame ? w :
  2183. (pSC->m_Dparam->cROIRightX - pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cThumbnailScale) / pSC->m_Dparam->cThumbnailScale / ((pII->cfColorFormat == YUV_420 || pII->cfColorFormat == YUV_422) ? 2 : 1)) - 1 - i : i) * cStrideX;
  2184. }
  2185. pSC->m_Dparam->pOffsetY = (size_t *)malloc(h * sizeof(size_t));
  2186. if(pSC->m_Dparam->pOffsetY == NULL || h * sizeof(size_t) < h)
  2187. return ICERR_ERROR;
  2188. /*
  2189. consider a column in the source image. if it becomes an upside-down column in the target, or a reversed row
  2190. in the target, we have to reverse the offsets. bReverse here tells us when this happened.
  2191. */
  2192. bReverse = (pII->oOrientation == O_FLIPV || pII->oOrientation == O_FLIPVH ||
  2193. pII->oOrientation == O_RCW || pII->oOrientation == O_RCW_FLIPV);
  2194. if(!pSC->m_Dparam->bDecodeFullFrame) // take care of region decode here!
  2195. iFirst = (pSC->m_Dparam->cROITopY + pSC->m_Dparam->cThumbnailScale - 1) / pSC->m_Dparam->cThumbnailScale;
  2196. for(i = 0; i + iFirst < h; i ++){
  2197. pSC->m_Dparam->pOffsetY[i + iFirst] = (bReverse ? (pSC->m_Dparam->bDecodeFullFrame ? h :
  2198. (pSC->m_Dparam->cROIBottomY - pSC->m_Dparam->cROITopY + pSC->m_Dparam->cThumbnailScale) / pSC->m_Dparam->cThumbnailScale / (pII->cfColorFormat == YUV_420 ? 2 : 1)) - 1 - i : i) * cStrideY;
  2199. }
  2200. return ICERR_OK;
  2201. }
  2202. Void setROI(CWMImageStrCodec* pSC)
  2203. {
  2204. CWMImageInfo * pWMII = &pSC->WMII;
  2205. CWMIStrCodecParam * pSCP = &pSC->WMISCP;
  2206. // inscribed image size
  2207. pWMII->cWidth -= pSC->m_param.cExtraPixelsLeft + pSC->m_param.cExtraPixelsRight;
  2208. pWMII->cHeight -= pSC->m_param.cExtraPixelsTop + pSC->m_param.cExtraPixelsBottom;
  2209. pSC->m_Dparam->bSkipFlexbits = (pSCP->sbSubband == SB_NO_FLEXBITS);
  2210. pSC->m_Dparam->bDecodeHP = (pSCP->sbSubband == SB_ALL || pSCP->sbSubband == SB_NO_FLEXBITS);
  2211. pSC->m_Dparam->bDecodeLP = (pSCP->sbSubband != SB_DC_ONLY);
  2212. pSC->m_Dparam->cThumbnailScale = 1;
  2213. while(pSC->m_Dparam->cThumbnailScale * pWMII->cThumbnailWidth < pWMII->cWidth)
  2214. pSC->m_Dparam->cThumbnailScale <<= 1;
  2215. if(pSC->WMISCP.bfBitstreamFormat == FREQUENCY){
  2216. if(pSC->m_Dparam->cThumbnailScale >= 4)
  2217. pSC->m_Dparam->bDecodeHP = FALSE; // no need to decode HP
  2218. if(pSC->m_Dparam->cThumbnailScale >= 16)
  2219. pSC->m_Dparam->bDecodeLP = FALSE; // only need to decode DC
  2220. }
  2221. // original image size
  2222. pWMII->cWidth += pSC->m_param.cExtraPixelsLeft + pSC->m_param.cExtraPixelsRight;
  2223. pWMII->cHeight += pSC->m_param.cExtraPixelsTop + pSC->m_param.cExtraPixelsBottom;
  2224. /** region decode stuff */
  2225. pSC->m_Dparam->cROILeftX = pWMII->cROILeftX * pSC->m_Dparam->cThumbnailScale + pSC->m_param.cExtraPixelsLeft;
  2226. pSC->m_Dparam->cROIRightX = pSC->m_Dparam->cROILeftX + pWMII->cROIWidth * pSC->m_Dparam->cThumbnailScale - 1;
  2227. pSC->m_Dparam->cROITopY = pWMII->cROITopY * pSC->m_Dparam->cThumbnailScale + pSC->m_param.cExtraPixelsTop;
  2228. pSC->m_Dparam->cROIBottomY = pSC->m_Dparam->cROITopY + pWMII->cROIHeight * pSC->m_Dparam->cThumbnailScale - 1;
  2229. if(pSC->m_Dparam->cROIRightX >= pWMII->cWidth)
  2230. pSC->m_Dparam->cROIRightX = pWMII->cWidth - 1;
  2231. if(pSC->m_Dparam->cROIBottomY >= pWMII->cHeight)
  2232. pSC->m_Dparam->cROIBottomY = pWMII->cHeight - 1;
  2233. pSC->m_Dparam->bDecodeFullFrame = (pSC->m_Dparam->cROILeftX + pSC->m_Dparam->cROITopY == 0 &&
  2234. ((pSC->m_Dparam->cROIRightX + 15) / 16 >= (pWMII->cWidth + 14) / 16) && ((pSC->m_Dparam->cROIBottomY + 15) / 16 >= (pWMII->cHeight + 14) / 16));
  2235. pSC->m_Dparam->bDecodeFullWidth = (pSC->m_Dparam->cROILeftX == 0 && ((pSC->m_Dparam->cROIRightX + 15) / 16 >= (pWMII->cWidth + 14) / 16));
  2236. // inscribed image size
  2237. pWMII->cWidth -= pSC->m_param.cExtraPixelsLeft + pSC->m_param.cExtraPixelsRight;
  2238. pWMII->cHeight -= pSC->m_param.cExtraPixelsTop + pSC->m_param.cExtraPixelsBottom;
  2239. if(pSC->WMISCP.bfBitstreamFormat == FREQUENCY && pWMII->bSkipFlexbits == TRUE)
  2240. pSC->m_Dparam->bSkipFlexbits = TRUE;
  2241. pSC->cTileColumn = pSC->cTileRow = 0;
  2242. }
  2243. Int StrDecInit(CWMImageStrCodec* pSC)
  2244. {
  2245. // CWMImageInfo * pWMII = &pSC->WMII;
  2246. COLORFORMAT cfInt = pSC->m_param.cfColorFormat;
  2247. COLORFORMAT cfExt = pSC->WMII.cfColorFormat;
  2248. size_t i;
  2249. /** color transcoding with resolution change **/
  2250. pSC->m_bUVResolutionChange = ((cfExt != Y_ONLY) && ((cfInt == YUV_420 && cfExt != YUV_420) ||
  2251. (cfInt == YUV_422 && cfExt != YUV_422))) && !pSC->WMISCP.bYUVData;
  2252. if(pSC->m_bUVResolutionChange){
  2253. pSC->pResU = (PixelI *)malloc((cfExt == YUV_422 ? 128 : 256) * pSC->cmbWidth * sizeof(PixelI));
  2254. pSC->pResV = (PixelI *)malloc((cfExt == YUV_422 ? 128 : 256) * pSC->cmbWidth * sizeof(PixelI));
  2255. if(pSC->pResU == NULL || pSC->pResV == NULL || (cfExt == YUV_422 ? 128 : 256) * pSC->cmbWidth * sizeof(PixelI) < pSC->cmbWidth){
  2256. return ICERR_ERROR;
  2257. }
  2258. }
  2259. if(allocatePredInfo(pSC) != ICERR_OK){
  2260. return ICERR_ERROR;
  2261. }
  2262. if(allocateTileInfo(pSC) != ICERR_OK)
  2263. return ICERR_ERROR;
  2264. if((pSC->m_param.uQPMode & 1) == 0){ // DC frame uniform quantization
  2265. if(allocateQuantizer(pSC->pTile[0].pQuantizerDC, pSC->m_param.cNumChannels, 1) != ICERR_OK)
  2266. return ICERR_ERROR;
  2267. setUniformQuantizer(pSC, 0);
  2268. for(i = 0; i < pSC->m_param.cNumChannels; i ++)
  2269. pSC->pTile[0].pQuantizerDC[i]->iIndex = pSC->m_param.uiQPIndexDC[i];
  2270. formatQuantizer(pSC->pTile[0].pQuantizerDC, (pSC->m_param.uQPMode >> 3) & 3, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith);
  2271. }
  2272. if(pSC->WMISCP.sbSubband != SB_DC_ONLY){
  2273. if((pSC->m_param.uQPMode & 2) == 0){ // LP frame uniform quantization
  2274. if(allocateQuantizer(pSC->pTile[0].pQuantizerLP, pSC->m_param.cNumChannels, 1) != ICERR_OK)
  2275. return ICERR_ERROR;
  2276. setUniformQuantizer(pSC, 1);
  2277. if((pSC->m_param.uQPMode & 0x200) == 0) // use DC quantizer
  2278. useDCQuantizer(pSC, 0);
  2279. else{
  2280. for(i = 0; i < pSC->m_param.cNumChannels; i ++)
  2281. pSC->pTile[0].pQuantizerLP[i]->iIndex = pSC->m_param.uiQPIndexLP[i];
  2282. formatQuantizer(pSC->pTile[0].pQuantizerLP, (pSC->m_param.uQPMode >> 5) & 3, pSC->m_param.cNumChannels, 0, TRUE, pSC->m_param.bScaledArith);
  2283. }
  2284. }
  2285. if(pSC->WMISCP.sbSubband != SB_NO_HIGHPASS){
  2286. if((pSC->m_param.uQPMode & 4) == 0){ // HP frame uniform quantization
  2287. if(allocateQuantizer(pSC->pTile[0].pQuantizerHP, pSC->m_param.cNumChannels, 1) != ICERR_OK)
  2288. return ICERR_ERROR;
  2289. setUniformQuantizer(pSC, 2);
  2290. if((pSC->m_param.uQPMode & 0x400) == 0) // use LP quantizer
  2291. useLPQuantizer(pSC, 1, 0);
  2292. else{
  2293. for(i = 0; i < pSC->m_param.cNumChannels; i ++)
  2294. pSC->pTile[0].pQuantizerHP[i]->iIndex = pSC->m_param.uiQPIndexHP[i];
  2295. formatQuantizer(pSC->pTile[0].pQuantizerHP, (pSC->m_param.uQPMode >> 7) & 3, pSC->m_param.cNumChannels, 0, FALSE, pSC->m_param.bScaledArith);
  2296. }
  2297. }
  2298. }
  2299. }
  2300. if(pSC->WMISCP.cNumOfSliceMinus1V >= MAX_TILES || AllocateCodingContextDec(pSC, pSC->WMISCP.cNumOfSliceMinus1V + 1) != ICERR_OK){
  2301. return ICERR_ERROR;
  2302. }
  2303. if (pSC->m_bSecondary) {
  2304. pSC->pIOHeader = pSC->m_pNextSC->pIOHeader;
  2305. pSC->m_ppBitIO = pSC->m_pNextSC->m_ppBitIO;
  2306. pSC->cNumBitIO = pSC->m_pNextSC->cNumBitIO;
  2307. pSC->cSB = pSC->m_pNextSC->cSB;
  2308. }
  2309. setBitIOPointers(pSC);
  2310. return ICERR_OK;
  2311. }
  2312. Int StrDecTerm(CWMImageStrCodec* pSC)
  2313. {
  2314. size_t j, jend = (pSC->m_pNextSC != NULL);
  2315. for (j = 0; j <= jend; j++) {
  2316. if(pSC->m_bUVResolutionChange){
  2317. if(pSC->pResU != NULL)
  2318. free(pSC->pResU);
  2319. if(pSC->pResV != NULL)
  2320. free(pSC->pResV);
  2321. }
  2322. freePredInfo(pSC);
  2323. freeTileInfo(pSC);
  2324. FreeCodingContextDec(pSC);
  2325. if (j == 0) {
  2326. StrIODecTerm(pSC);
  2327. // free lookup tables for rotation and flipping
  2328. if(pSC->m_Dparam->pOffsetX != NULL)
  2329. free(pSC->m_Dparam->pOffsetX);
  2330. if(pSC->m_Dparam->pOffsetY != NULL)
  2331. free(pSC->m_Dparam->pOffsetY);
  2332. }
  2333. pSC = pSC->m_pNextSC;
  2334. }
  2335. return 0;
  2336. }
  2337. /*************************************************************************
  2338. Read header of image plane
  2339. *************************************************************************/
  2340. Int ReadImagePlaneHeader(CWMImageInfo* pII, CWMIStrCodecParam *pSCP,
  2341. CCoreParameters *pSC, SimpleBitIO* pSB)
  2342. {
  2343. ERR err = WMP_errSuccess;
  2344. pSC->cfColorFormat = getBit32_SB(pSB, 3); // internal color format
  2345. FailIf((pSC->cfColorFormat < Y_ONLY || pSC->cfColorFormat > NCOMPONENT), WMP_errUnsupportedFormat);
  2346. pSCP->cfColorFormat = pSC->cfColorFormat; // this should be removed later
  2347. pSC->bScaledArith = getBit32_SB(pSB, 1); // lossless mode
  2348. // subbands
  2349. pSCP->sbSubband = getBit32_SB(pSB, 4);
  2350. // color parameters
  2351. switch (pSC->cfColorFormat) {
  2352. case Y_ONLY:
  2353. pSC->cNumChannels = 1;
  2354. break;
  2355. case YUV_420:
  2356. pSC->cNumChannels = 3;
  2357. getBit32_SB(pSB, 1);
  2358. pII->cChromaCenteringX = (U8) getBit32_SB(pSB, 3);
  2359. getBit32_SB(pSB, 1);
  2360. pII->cChromaCenteringY = (U8) getBit32_SB(pSB, 3);
  2361. break;
  2362. case YUV_422:
  2363. pSC->cNumChannels = 3;
  2364. getBit32_SB(pSB, 1);
  2365. pII->cChromaCenteringX = (U8) getBit32_SB(pSB, 3);
  2366. getBit32_SB(pSB, 4);
  2367. break;
  2368. case YUV_444:
  2369. pSC->cNumChannels = 3;
  2370. getBit32_SB(pSB, 4);
  2371. getBit32_SB(pSB, 4);
  2372. break;
  2373. case NCOMPONENT:
  2374. pSC->cNumChannels = (Int) getBit32_SB(pSB, 4) + 1;
  2375. getBit32_SB(pSB, 4);
  2376. break;
  2377. case CMYK:
  2378. pSC->cNumChannels = 4;
  2379. break;
  2380. default:
  2381. break;
  2382. }
  2383. // float and 32s additional parameters
  2384. switch (pII->bdBitDepth) {
  2385. case BD_16:
  2386. case BD_16S:
  2387. case BD_32:
  2388. case BD_32S:
  2389. pSCP->nLenMantissaOrShift = (U8) getBit32_SB(pSB, 8);
  2390. break;
  2391. case BD_32F:
  2392. pSCP->nLenMantissaOrShift = (U8) getBit32_SB(pSB, 8);//float conversion parameters
  2393. pSCP->nExpBias = (I8) getBit32_SB(pSB, 8);
  2394. break;
  2395. default:
  2396. break;
  2397. }
  2398. // quantization
  2399. pSC->uQPMode = 0;
  2400. if(getBit32_SB(pSB, 1) == 1) // DC uniform
  2401. pSC->uQPMode += (readQuantizerSB(pSC->uiQPIndexDC, pSB, pSC->cNumChannels) << 3);
  2402. else
  2403. pSC->uQPMode ++;
  2404. if(pSCP->sbSubband != SB_DC_ONLY){
  2405. if(getBit32_SB(pSB, 1) == 0){ // don't use DC QP
  2406. pSC->uQPMode += 0x200;
  2407. if(getBit32_SB(pSB, 1) == 1) // LP uniform
  2408. pSC->uQPMode += (readQuantizerSB(pSC->uiQPIndexLP, pSB, pSC->cNumChannels) << 5);
  2409. else
  2410. pSC->uQPMode += 2;
  2411. }
  2412. else
  2413. pSC->uQPMode += ((pSC->uQPMode & 1) << 1) + ((pSC->uQPMode & 0x18) << 2);
  2414. if(pSCP->sbSubband != SB_NO_HIGHPASS){
  2415. if(getBit32_SB(pSB, 1) == 0){ // don't use LP QP
  2416. pSC->uQPMode += 0x400;
  2417. if(getBit32_SB(pSB, 1) == 1) // HP uniform
  2418. pSC->uQPMode += (readQuantizerSB(pSC->uiQPIndexHP, pSB, pSC->cNumChannels) << 7);
  2419. else
  2420. pSC->uQPMode += 4;
  2421. }
  2422. else
  2423. pSC->uQPMode += ((pSC->uQPMode & 2) << 1) + ((pSC->uQPMode & 0x60) << 2);
  2424. }
  2425. }
  2426. if(pSCP->sbSubband == SB_DC_ONLY)
  2427. pSC->uQPMode |= 0x200;
  2428. else if(pSCP->sbSubband == SB_NO_HIGHPASS)
  2429. pSC->uQPMode |= 0x400;
  2430. FailIf((pSC->uQPMode & 0x600) == 0, WMP_errInvalidParameter); // frame level QPs must be specified independently!
  2431. flushToByte_SB(pSB); // remove this later
  2432. Cleanup:
  2433. return WMP_errSuccess == err ? ICERR_OK : ICERR_ERROR;
  2434. }
  2435. /*************************************************************************
  2436. Read header of image, and header of FIRST PLANE only
  2437. *************************************************************************/
  2438. Int ReadWMIHeader(
  2439. CWMImageInfo* pII,
  2440. CWMIStrCodecParam *pSCP,
  2441. CCoreParameters *pSC)
  2442. {
  2443. U32 i;
  2444. ERR err = WMP_errSuccess;
  2445. Bool bTilingPresent, bInscribed, bTileStretch, bAbbreviatedHeader;
  2446. struct WMPStream* pWS = pSCP->pWStream;
  2447. SimpleBitIO SB = {0};
  2448. SimpleBitIO* pSB = &SB;
  2449. U8 szMS[8] = {0};
  2450. U32 cbStream = 0;
  2451. // U32 bits = 0;
  2452. // Int HEADERSIZE = 0;
  2453. assert(pSC != NULL);
  2454. //================================
  2455. // 0
  2456. /** signature **/
  2457. Call(pWS->Read(pWS, szMS, sizeof(szMS)));
  2458. FailIf(szMS != (U8 *) strstr((char *) szMS, "WMPHOTO"), WMP_errUnsupportedFormat);
  2459. //================================
  2460. Call(attach_SB(pSB, pWS));
  2461. // 8
  2462. /** codec version and subversion **/
  2463. i = getBit32_SB(pSB, 4);
  2464. FailIf((i != CODEC_VERSION), WMP_errIncorrectCodecVersion);
  2465. pSC->cVersion = i;
  2466. i = getBit32_SB(pSB, 4); // subversion
  2467. FailIf((i != CODEC_SUBVERSION &&
  2468. i != CODEC_SUBVERSION_NEWSCALING_SOFT_TILES && i != CODEC_SUBVERSION_NEWSCALING_HARD_TILES),
  2469. WMP_errIncorrectCodecSubVersion);
  2470. pSC->cSubVersion = i;
  2471. pSC->bUseHardTileBoundaries = FALSE;
  2472. if (pSC->cSubVersion == CODEC_SUBVERSION_NEWSCALING_HARD_TILES)
  2473. pSC->bUseHardTileBoundaries = TRUE;
  2474. pSCP->bUseHardTileBoundaries = pSC->bUseHardTileBoundaries;
  2475. // 9 primary parameters
  2476. bTilingPresent = (Bool) getBit32_SB(pSB, 1); // tiling present
  2477. pSCP->bfBitstreamFormat = getBit32_SB(pSB, 1); // bitstream layout
  2478. pII->oOrientation = (ORIENTATION)getBit32_SB(pSB, 3); // presentation orientation
  2479. pSC->bIndexTable = getBit32_SB(pSB, 1);
  2480. i = getBit32_SB(pSB, 2); // overlap
  2481. FailIf((i == 3), WMP_errInvalidParameter);
  2482. pSCP->olOverlap = i;
  2483. // 11 some other parameters
  2484. bAbbreviatedHeader = (Bool) getBit32_SB(pSB, 1); // short words for size and tiles
  2485. pSCP->bdBitDepth = (BITDEPTH) getBit32_SB(pSB, 1); // long word
  2486. pSCP->bdBitDepth = BD_LONG; // remove when optimization is done
  2487. bInscribed = (Bool) getBit32_SB(pSB, 1); // windowing
  2488. pSC->bTrimFlexbitsFlag = (Bool) getBit32_SB(pSB, 1); // trim flexbits flag
  2489. bTileStretch = (Bool) getBit32_SB(pSB, 1); // tile stretching flag
  2490. pSC->bRBSwapped = (Bool) getBit32_SB(pSB, 1); // red-blue swap flag
  2491. getBit32_SB(pSB, 1); // padding / reserved bit
  2492. pSC->bAlphaChannel = (Bool) getBit32_SB(pSB, 1); // alpha channel present
  2493. // 10 - informational
  2494. pII->cfColorFormat = getBit32_SB(pSB, 4); // source color format
  2495. pII->bdBitDepth = getBit32_SB(pSB, 4); // source bit depth
  2496. if(BD_1alt == pII->bdBitDepth)
  2497. {
  2498. pII->bdBitDepth = BD_1;
  2499. pSCP->bBlackWhite = 1;
  2500. }
  2501. // 12 - Variable length fields
  2502. // size
  2503. pII->cWidth = getBit32_SB(pSB, bAbbreviatedHeader ? 16 : 32) + 1;
  2504. pII->cHeight = getBit32_SB(pSB, bAbbreviatedHeader ? 16 : 32) + 1;
  2505. pSC->cExtraPixelsTop = pSC->cExtraPixelsLeft = pSC->cExtraPixelsBottom = pSC->cExtraPixelsRight = 0;
  2506. if (bInscribed == FALSE && (pII->cWidth & 0xf) != 0)
  2507. pSC->cExtraPixelsRight = 0x10 - (pII->cWidth & 0xF);
  2508. if (bInscribed == FALSE && (pII->cHeight & 0xf) != 0)
  2509. pSC->cExtraPixelsBottom = 0x10 - (pII->cHeight & 0xF);
  2510. // tiling
  2511. pSCP->cNumOfSliceMinus1V = pSCP->cNumOfSliceMinus1H = 0;
  2512. if (bTilingPresent) {
  2513. pSCP->cNumOfSliceMinus1V = getBit32_SB(pSB, LOG_MAX_TILES); // # of vertical slices along X axis
  2514. pSCP->cNumOfSliceMinus1H = getBit32_SB(pSB, LOG_MAX_TILES); // # of horizontal slices along Y axis
  2515. }
  2516. FailIf((pSC->bIndexTable == FALSE) && (pSCP->bfBitstreamFormat == FREQUENCY || pSCP->cNumOfSliceMinus1V + pSCP->cNumOfSliceMinus1H > 0),
  2517. WMP_errUnsupportedFormat);
  2518. // tile sizes
  2519. pSCP->uiTileX[0] = pSCP->uiTileY[0] = 0;
  2520. for(i = 0; i < pSCP->cNumOfSliceMinus1V; i ++){ // width in MB of vertical slices, not needed for last slice!
  2521. pSCP->uiTileX[i + 1] = (U32) getBit32_SB(pSB, bAbbreviatedHeader ? 8 : 16) + pSCP->uiTileX[i];
  2522. }
  2523. for(i = 0; i < pSCP->cNumOfSliceMinus1H; i ++){ // width in MB of vertical slices, not needed for last slice!
  2524. pSCP->uiTileY[i + 1] = (U32) getBit32_SB(pSB, bAbbreviatedHeader ? 8 : 16) + pSCP->uiTileY[i];
  2525. }
  2526. if (bTileStretch) { // no handling of tile stretching enabled as of now
  2527. for (i = 0; i < (pSCP->cNumOfSliceMinus1V + 1) * (pSCP->cNumOfSliceMinus1H + 1); i++)
  2528. getBit32_SB(pSB, 8);
  2529. }
  2530. // window due to compressed domain processing
  2531. if (bInscribed) {
  2532. pSC->cExtraPixelsTop = (U8)getBit32_SB(pSB, 6);
  2533. pSC->cExtraPixelsLeft = (U8)getBit32_SB(pSB, 6);
  2534. pSC->cExtraPixelsBottom = (U8)getBit32_SB(pSB, 6);
  2535. pSC->cExtraPixelsRight = (U8)getBit32_SB(pSB, 6);
  2536. }
  2537. if(((pII->cWidth + pSC->cExtraPixelsLeft + pSC->cExtraPixelsRight) & 0xf) + ((pII->cHeight + pSC->cExtraPixelsTop + pSC->cExtraPixelsBottom) & 0xf) != 0){
  2538. FailIf((pII->cWidth & 0xf) + (pII->cHeight & 0xf) + pSC->cExtraPixelsLeft + pSC->cExtraPixelsTop != 0, WMP_errInvalidParameter);
  2539. FailIf(pII->cWidth <= pSC->cExtraPixelsRight || pII->cHeight <= pSC->cExtraPixelsBottom, WMP_errInvalidParameter);
  2540. pII->cWidth -= pSC->cExtraPixelsRight, pII->cHeight -= pSC->cExtraPixelsBottom;
  2541. }
  2542. flushToByte_SB(pSB); // redundant
  2543. // read header of first image plane
  2544. FailIf(ReadImagePlaneHeader(pII, pSCP, pSC, pSB), WMP_errUnsupportedFormat);
  2545. // maybe UNALIGNED!!!
  2546. //================================
  2547. detach_SB(pSB);
  2548. pSCP->cbStream = cbStream - getByteRead_SB(pSB);
  2549. pSCP->uAlphaMode = (pSC->bAlphaChannel ? pSCP->uAlphaMode : 0);
  2550. pSCP->cChannel = pSC->cNumChannels;
  2551. if((pII->bdBitDepth == BD_5 || pII->bdBitDepth == BD_10 || pII->bdBitDepth == BD_565) &&
  2552. (pSCP->cfColorFormat != YUV_444 && pSCP->cfColorFormat != YUV_422 && pSCP->cfColorFormat != YUV_420 && pSCP->cfColorFormat != Y_ONLY))
  2553. return ICERR_ERROR;
  2554. Cleanup:
  2555. return WMP_errSuccess == err ? ICERR_OK : ICERR_ERROR;
  2556. }
  2557. //----------------------------------------------------------------
  2558. // streaming api init/decode/term
  2559. EXTERN_C Int ImageStrDecGetInfo(
  2560. CWMImageInfo* pII,
  2561. CWMIStrCodecParam *pSCP)
  2562. {
  2563. ERR err = WMP_errSuccess;
  2564. size_t cMarker;
  2565. CCoreParameters aDummy;
  2566. // mark position of start of data
  2567. Call(pSCP->pWStream->GetPos(pSCP->pWStream, &cMarker));
  2568. Call(ReadWMIHeader(pII, pSCP, &aDummy));
  2569. // rewind to start of data
  2570. Call(pSCP->pWStream->SetPos(pSCP->pWStream, cMarker));
  2571. return ICERR_OK;
  2572. Cleanup:
  2573. return ICERR_ERROR;
  2574. }
  2575. EXTERN_C Int WMPhotoValidate(
  2576. CWMImageInfo * pII,
  2577. CWMIStrCodecParam * pSCP)
  2578. {
  2579. CWMImageInfo cII;
  2580. CWMIStrCodecParam cSCP = *pSCP;
  2581. size_t cScale = 1;
  2582. if(ImageStrDecGetInfo(&cII, pSCP) != ICERR_OK)
  2583. return ICERR_ERROR;
  2584. // copy over un-overwritable ImageInfo parameters
  2585. pII->bdBitDepth = cII.bdBitDepth;
  2586. pII->cWidth = cII.cWidth;
  2587. pII->cHeight = cII.cHeight;
  2588. if(pII->cWidth == 0 || pII->cHeight == 0)
  2589. return ICERR_ERROR;
  2590. // copy over overwritable CodecParam parameters
  2591. pSCP->bVerbose = cSCP.bVerbose;
  2592. pSCP->cbStream = cSCP.cbStream;
  2593. pSCP->pWStream = cSCP.pWStream;
  2594. if(pSCP->uAlphaMode > 1) // something + alpha
  2595. pSCP->uAlphaMode = cSCP.uAlphaMode; // something + alpha to alpha or something transcoding!
  2596. // validate color transcoding
  2597. if(pSCP->cfColorFormat == NCOMPONENT)
  2598. pII->cfColorFormat = NCOMPONENT;
  2599. if(pSCP->cfColorFormat == CMYK && pII->cfColorFormat != Y_ONLY && pII->cfColorFormat != CF_RGB)
  2600. pII->cfColorFormat = CMYK;
  2601. if(pSCP->cfColorFormat == YUV_422 && pII->cfColorFormat == YUV_420)
  2602. pII->cfColorFormat = YUV_422;
  2603. if(pSCP->cfColorFormat == YUV_444 && (pII->cfColorFormat == YUV_422 || pII->cfColorFormat == YUV_420))
  2604. pII->cfColorFormat = YUV_444;
  2605. if(cII.cfColorFormat == CF_RGB && pII->cfColorFormat != Y_ONLY &&
  2606. pII->cfColorFormat != NCOMPONENT) // no guarantee that number of channels will be >= 3
  2607. pII->cfColorFormat = cII.cfColorFormat;
  2608. if(cII.cfColorFormat == CF_RGBE)
  2609. pII->cfColorFormat = CF_RGBE;
  2610. // validate thumbnail parameters
  2611. if(pII->cThumbnailWidth == 0 || pII->cThumbnailWidth > pII->cWidth)
  2612. pII->cThumbnailWidth = pII->cWidth;
  2613. if(pII->cThumbnailHeight == 0 || pII->cThumbnailHeight > pII->cHeight)
  2614. pII->cThumbnailHeight = pII->cHeight;
  2615. if((pII->cWidth + pII->cThumbnailWidth - 1) / pII->cThumbnailWidth != (pII->cHeight + pII->cThumbnailHeight - 1) / pII->cThumbnailHeight) {
  2616. while((pII->cWidth + cScale - 1) / cScale > pII->cThumbnailWidth &&
  2617. (pII->cHeight + cScale - 1) / cScale > pII->cThumbnailHeight && (cScale << 1))
  2618. cScale <<= 1;
  2619. }
  2620. else {
  2621. cScale = (pII->cWidth + pII->cThumbnailWidth - 1) / pII->cThumbnailWidth;
  2622. if (cScale == 0)
  2623. cScale = 1;
  2624. }
  2625. pII->cThumbnailWidth = (pII->cWidth + cScale - 1) / cScale;
  2626. pII->cThumbnailHeight = (pII->cHeight + cScale - 1) / cScale;
  2627. // validate region decode parameters
  2628. if(pII->cROIHeight == 0 || pII->cROIWidth == 0){
  2629. pII->cROILeftX = pII->cROITopY = 0;
  2630. pII->cROIWidth = pII->cThumbnailWidth;
  2631. pII->cROIHeight = pII->cThumbnailHeight;
  2632. }
  2633. if(pII->cROILeftX >= pII->cThumbnailWidth)
  2634. pII->cROILeftX = 0;
  2635. if(pII->cROITopY >= pII->cThumbnailHeight)
  2636. pII->cROITopY = 0;
  2637. if(pII->cROILeftX + pII->cROIWidth > pII->cThumbnailWidth)
  2638. pII->cROIWidth = pII->cThumbnailWidth - pII->cROILeftX;
  2639. if(pII->cROITopY + pII->cROIHeight > pII->cThumbnailHeight)
  2640. pII->cROIHeight = pII->cThumbnailHeight - pII->cROITopY;
  2641. return ICERR_OK;
  2642. }
  2643. /*************************************************************************
  2644. Initialization of CWMImageStrCodec struct
  2645. *************************************************************************/
  2646. static Void InitializeStrDec(CWMImageStrCodec *pSC,
  2647. const CCoreParameters *pParams, const CWMImageStrCodec *pSCIn)
  2648. {
  2649. // copy core parameters
  2650. memcpy (&(pSC->m_param), pParams, sizeof (CCoreParameters));
  2651. pSC->cbStruct = sizeof(*pSC);
  2652. pSC->WMII = pSCIn->WMII;
  2653. pSC->WMISCP = pSCIn->WMISCP;
  2654. pSC->cRow = 0;
  2655. pSC->cColumn = 0;
  2656. pSC->cmbWidth = (pSC->WMII.cWidth + 15) / 16;
  2657. pSC->cmbHeight = (pSC->WMII.cHeight + 15) / 16;
  2658. pSC->Load = outputMBRow; // output decoding result (ICC, etc)
  2659. pSC->Transform = pParams->cSubVersion == CODEC_SUBVERSION ?
  2660. invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
  2661. pSC->TransformCenter = pSC->Transform;
  2662. pSC->ProcessTopLeft = processMacroblockDec;
  2663. pSC->ProcessTop = processMacroblockDec;
  2664. pSC->ProcessTopRight = processMacroblockDec;
  2665. pSC->ProcessLeft = processMacroblockDec;
  2666. pSC->ProcessCenter = processMacroblockDec;
  2667. pSC->ProcessRight = processMacroblockDec;
  2668. pSC->ProcessBottomLeft = processMacroblockDec;
  2669. pSC->ProcessBottom = processMacroblockDec;
  2670. pSC->ProcessBottomRight = processMacroblockDec;
  2671. pSC->m_pNextSC = NULL;
  2672. pSC->m_bSecondary = FALSE;
  2673. }
  2674. /*************************************************************************
  2675. ImageStrDecInit
  2676. *************************************************************************/
  2677. Int ImageStrDecInit(
  2678. CWMImageInfo* pII,
  2679. CWMIStrCodecParam *pSCP,
  2680. CTXSTRCODEC* pctxSC)
  2681. {
  2682. static size_t cbChannels[BD_MAX] = {2, 4};
  2683. ERR err = WMP_errSuccess;
  2684. size_t cbChannel = 0, cblkChroma = 0;
  2685. size_t cbMacBlockStride = 0, cbMacBlockChroma = 0, cMacBlock = 0;
  2686. CWMImageStrCodec SC = {0};
  2687. CWMImageStrCodec *pSC = NULL, *pNextSC = NULL;
  2688. char* pb = NULL;
  2689. size_t cb = 0, i;
  2690. Bool bLossyTranscoding = FALSE;
  2691. Bool bUseHardTileBoundaries = FALSE; //default is soft tile boundaries
  2692. Bool bLessThan64Bit = sizeof(void *) < 8;
  2693. *pctxSC = NULL;
  2694. if(WMPhotoValidate(pII, pSCP) != ICERR_OK)
  2695. return ICERR_ERROR;
  2696. if(pSCP->sbSubband == SB_ISOLATED) // can not do anything with isolated bitstream
  2697. return ICERR_ERROR;
  2698. //================================================
  2699. SC.WMISCP.pWStream = pSCP->pWStream;
  2700. if (ReadWMIHeader(&SC.WMII, &SC.WMISCP, &SC.m_param) != ICERR_OK) {
  2701. return ICERR_ERROR;
  2702. }
  2703. bUseHardTileBoundaries = SC.WMISCP.bUseHardTileBoundaries;
  2704. if(SC.WMII.cfColorFormat == CMYK && pII->cfColorFormat == CF_RGB)
  2705. bLossyTranscoding = TRUE;
  2706. if(pSCP->cfColorFormat != CMYK && (pII->cfColorFormat == CMYK))
  2707. return ICERR_ERROR;
  2708. //================================================
  2709. SC.WMISCP = *pSCP;
  2710. SC.WMII = *pII;
  2711. // original image size
  2712. SC.WMII.cWidth += SC.m_param.cExtraPixelsLeft + SC.m_param.cExtraPixelsRight;
  2713. SC.WMII.cHeight += SC.m_param.cExtraPixelsTop + SC.m_param.cExtraPixelsBottom;
  2714. pII->cROILeftX += SC.m_param.cExtraPixelsLeft;
  2715. pII->cROITopY += SC.m_param.cExtraPixelsTop;
  2716. //================================================
  2717. cbChannel = cbChannels[SC.WMISCP.bdBitDepth];
  2718. cblkChroma = cblkChromas[SC.m_param.cfColorFormat];
  2719. cbMacBlockStride = cbChannel * 16 * 16;
  2720. cbMacBlockChroma = cbChannel * 16 * cblkChroma;
  2721. cMacBlock = (SC.WMII.cWidth + 15) / 16;
  2722. //================================================
  2723. cb = sizeof(*pSC) + (128 - 1) + sizeof(CWMDecoderParameters);
  2724. cb += (PACKETLENGTH * 4 - 1) + (PACKETLENGTH * 2 ) + sizeof(*pSC->pIOHeader);
  2725. i = (cbMacBlockStride + cbMacBlockChroma * (SC.m_param.cNumChannels - 1)) * 2; // i <= 2^15
  2726. if (bLessThan64Bit && ((i * (cMacBlock >> 16)) & 0xffffc000)) {
  2727. /** potential overflow - 32 bit pointers insufficient to address cache **/
  2728. return ICERR_ERROR;
  2729. }
  2730. cb += i * cMacBlock;
  2731. pb = malloc(cb);
  2732. if(pb == NULL)
  2733. return WMP_errOutOfMemory;
  2734. memset(pb, 0, cb);
  2735. //================================================
  2736. pSC = (CWMImageStrCodec*)pb; pb += sizeof(*pSC);
  2737. if(pSC == NULL)
  2738. return ICERR_ERROR;
  2739. // Set up perf timers
  2740. PERFTIMER_ONLY(pSC->m_fMeasurePerf = pSCP->fMeasurePerf);
  2741. PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEndToEndPerf);
  2742. PERFTIMER_NEW(pSC->m_fMeasurePerf, &pSC->m_ptEncDecPerf);
  2743. PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf);
  2744. PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  2745. PERFTIMER_COPYSTARTTIME(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf, pSC->m_ptEndToEndPerf);
  2746. pSC->m_Dparam = (CWMDecoderParameters*)pb; pb += sizeof(CWMDecoderParameters);
  2747. pSC->cbChannel = cbChannel;
  2748. //pSC->cNumChannels = SC.WMISCP.cChannel;
  2749. pSC->bUseHardTileBoundaries = bUseHardTileBoundaries;
  2750. //================================================
  2751. InitializeStrDec(pSC, &SC.m_param, &SC);
  2752. //================================================
  2753. // 2 Macro Row buffers for each channel
  2754. pb = ALIGNUP(pb, 128);
  2755. for (i = 0; i < pSC->m_param.cNumChannels; i++) {
  2756. pSC->a0MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth;
  2757. pSC->a1MBbuffer[i] = (PixelI*)pb; pb += cbMacBlockStride * pSC->cmbWidth;
  2758. cbMacBlockStride = cbMacBlockChroma;
  2759. }
  2760. //================================================
  2761. // lay 2 aligned IO buffers just below pIO struct
  2762. pb = (char*)ALIGNUP(pb, PACKETLENGTH * 4) + PACKETLENGTH * 2;
  2763. pSC->pIOHeader = (BitIOInfo*)pb; pb += sizeof(*pSC->pIOHeader);
  2764. // if interleaved alpha is needed
  2765. if (pSC->m_param.bAlphaChannel) {
  2766. SimpleBitIO SB = {0};
  2767. cbMacBlockStride = cbChannel * 16 * 16;
  2768. // 1. allocate new pNextSC info
  2769. //================================================
  2770. cb = sizeof(*pNextSC) + (128 - 1) + cbMacBlockStride * cMacBlock * 2;
  2771. // if primary image is safe to allocate, alpha channel is certainly safe
  2772. pb = malloc(cb);
  2773. if(pb == NULL)
  2774. return WMP_errOutOfMemory;
  2775. memset(pb, 0, cb);
  2776. //================================================
  2777. pNextSC = (CWMImageStrCodec*)pb; pb += sizeof(*pNextSC);
  2778. // read plane header of second image plane
  2779. Call(attach_SB(&SB, pSCP->pWStream));
  2780. InitializeStrDec(pNextSC, &SC.m_param, &SC);
  2781. ReadImagePlaneHeader(&pNextSC->WMII, &pNextSC->WMISCP, &pNextSC->m_param, &SB);
  2782. detach_SB(&SB);
  2783. // 2. initialize pNextSC
  2784. if(pNextSC == NULL)
  2785. return ICERR_ERROR;
  2786. pNextSC->m_Dparam = pSC->m_Dparam;
  2787. pNextSC->cbChannel = cbChannel;
  2788. //================================================
  2789. // 3. initialize arrays
  2790. // InitializeStrDec(pNextSC, &SC.m_param, &SC);
  2791. pNextSC->m_param.cfColorFormat = Y_ONLY;
  2792. pNextSC->m_param.cNumChannels = 1;
  2793. pNextSC->m_param.bAlphaChannel = TRUE;
  2794. //================================================
  2795. // 2 Macro Row buffers for each channel
  2796. pb = ALIGNUP(pb, 128);
  2797. pNextSC->a0MBbuffer[0] = (PixelI*)pb; pb += cbMacBlockStride * pNextSC->cmbWidth;
  2798. pNextSC->a1MBbuffer[0] = (PixelI*)pb;
  2799. //================================================
  2800. pNextSC->pIOHeader = pSC->pIOHeader;
  2801. //================================================
  2802. // 4. link pSC->pNextSC = pNextSC
  2803. pNextSC->m_pNextSC = pSC;
  2804. pNextSC->m_bSecondary = TRUE;
  2805. }
  2806. else
  2807. pSC->WMISCP.uAlphaMode = 0;
  2808. //================================================
  2809. FailIf((StrIODecInit(pSC) != ICERR_OK), WMP_errOutOfMemory);
  2810. FailIf((StrDecInit(pSC) != ICERR_OK), WMP_errOutOfMemory);
  2811. if (pNextSC) {
  2812. // 5. StrEncInit
  2813. FailIf((StrDecInit(pNextSC) != ICERR_OK), WMP_errOutOfMemory);
  2814. }
  2815. pSC->m_pNextSC = pNextSC;
  2816. //================================================
  2817. *pII = pSC->WMII;
  2818. *pSCP = pSC->WMISCP;
  2819. *pctxSC = (CTXSTRCODEC)pSC;
  2820. if(pSC->WMII.cPostProcStrength){
  2821. initPostProc(pSC->pPostProcInfo, pSC->cmbWidth, pSC->m_param.cNumChannels);
  2822. if (pSC->m_param.bAlphaChannel)
  2823. initPostProc(pNextSC->pPostProcInfo, pNextSC->cmbWidth, pNextSC->m_param.cNumChannels);
  2824. }
  2825. PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  2826. Cleanup:
  2827. return WMP_errSuccess == err ? ICERR_OK : ICERR_ERROR;
  2828. }
  2829. Int ImageStrDecDecode(
  2830. CTXSTRCODEC ctxSC,
  2831. const CWMImageBufferInfo* pBI
  2832. #ifdef REENTRANT_MODE
  2833. , size_t *pcDecodedLines
  2834. #endif
  2835. )
  2836. {
  2837. CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC;
  2838. CWMImageStrCodec* pNextSC = pSC->m_pNextSC;
  2839. size_t cMBRow, k;
  2840. ImageDataProc ProcessLeft, ProcessCenter, ProcessRight;
  2841. ImageDataProc Transform = NULL;
  2842. const size_t iChromaElements = (pSC->m_param.cfColorFormat == YUV_420) ? 8 * 8
  2843. : ((pSC->m_param.cfColorFormat == YUV_422) ? 8 * 16 : 16 * 16);
  2844. if (sizeof(*pSC) != pSC->cbStruct)
  2845. {
  2846. return ICERR_ERROR;
  2847. }
  2848. //================================
  2849. PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  2850. pSC->WMIBI = *pBI;
  2851. #ifdef REENTRANT_MODE
  2852. if (0 == pSC->WMIBI.uiFirstMBRow)
  2853. {
  2854. setROI(pSC);
  2855. if (pNextSC) {
  2856. pNextSC->WMIBI = pSC->WMIBI;
  2857. setROI(pNextSC);
  2858. }
  2859. }
  2860. #else
  2861. setROI(pSC);
  2862. if (pNextSC) {
  2863. pNextSC->WMIBI = pSC->WMIBI;
  2864. setROI(pNextSC);
  2865. }
  2866. #endif // REENTRANT_MODE
  2867. // optimization flags can be defined only after ROI is set!
  2868. #if defined(WMP_OPT_SSE2) || defined(WMP_OPT_CC_DEC) || defined(WMP_OPT_TRFM_DEC)
  2869. StrDecOpt(pSC);
  2870. #endif // OPT defined
  2871. cMBRow = (pSC->m_Dparam->bDecodeFullFrame ? pSC->cmbHeight : ((pSC->m_Dparam->cROIBottomY + 16) >> 4));
  2872. #ifdef REENTRANT_MODE
  2873. if (0 == pSC->WMIBI.uiFirstMBRow)
  2874. {
  2875. if(initLookupTables(pSC) != ICERR_OK)
  2876. return ICERR_ERROR;
  2877. if (pNextSC && initLookupTables(pNextSC) != ICERR_OK)
  2878. return ICERR_ERROR;
  2879. }
  2880. #else
  2881. if(initLookupTables(pSC) != ICERR_OK)
  2882. return ICERR_ERROR;
  2883. if (pNextSC && initLookupTables(pNextSC) != ICERR_OK)
  2884. return ICERR_ERROR;
  2885. #endif // REENTRANT_MODE
  2886. #ifndef REENTRANT_MODE
  2887. if(pSC->WMII.bdBitDepth == BD_1){
  2888. size_t i;
  2889. for(i = 0; i < pSC->WMIBI.cLine; i ++)
  2890. memset(pSC->WMIBI.pv, 0, pSC->WMIBI.cbStride);
  2891. }
  2892. #endif
  2893. //================================
  2894. // top row
  2895. #ifdef REENTRANT_MODE
  2896. #else
  2897. pSC->cRow = 0;
  2898. ProcessLeft = pSC->ProcessTopLeft;
  2899. ProcessCenter = pSC->ProcessTop;
  2900. ProcessRight = pSC->ProcessTopRight;
  2901. Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
  2902. invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
  2903. #endif // REENTRANT_MODE
  2904. #ifdef REENTRANT_MODE
  2905. for (pSC->cRow = pSC->WMIBI.uiFirstMBRow; pSC->cRow <= pSC->WMIBI.uiLastMBRow; pSC->cRow++)
  2906. {
  2907. // const COLORFORMAT cfExt = (pSC->m_param.cfColorFormat == Y_ONLY ? Y_ONLY : pSC->WMII.cfColorFormat);
  2908. if (0 == pSC->cRow)
  2909. {
  2910. ProcessLeft = pSC->ProcessTopLeft;
  2911. ProcessCenter = pSC->ProcessTop;
  2912. ProcessRight = pSC->ProcessTopRight;
  2913. Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
  2914. invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
  2915. }
  2916. else if (cMBRow == pSC->cRow)
  2917. {
  2918. //================================
  2919. // bottom row
  2920. ProcessLeft = pSC->ProcessBottomLeft;
  2921. ProcessCenter = pSC->ProcessBottom;
  2922. ProcessRight = pSC->ProcessBottomRight;
  2923. Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
  2924. invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
  2925. }
  2926. else { // middle rows
  2927. ProcessLeft = pSC->ProcessLeft;
  2928. ProcessCenter = pSC->ProcessCenter;
  2929. ProcessRight = pSC->ProcessRight;
  2930. Transform = pSC->TransformCenter;
  2931. }
  2932. #else
  2933. //================================
  2934. // central rows
  2935. for(pSC->cRow = 0; pSC->cRow <= cMBRow; pSC->cRow++)
  2936. {
  2937. #endif // REENTRANT_MODE
  2938. pSC->cColumn = 0;
  2939. initMRPtr(pSC);
  2940. /** zero out the transform coefficients (pull this out to once per MB row) **/
  2941. memset(pSC->p1MBbuffer[0], 0, sizeof(PixelI) * 16 * 16 * pSC->cmbWidth);
  2942. for (k = 1; k < pSC->m_param.cNumChannels; k++) {
  2943. memset(pSC->p1MBbuffer[k], 0, sizeof(PixelI) * iChromaElements * pSC->cmbWidth);
  2944. }
  2945. if (pSC->m_pNextSC != NULL) { // alpha channel
  2946. memset(pSC->m_pNextSC->p1MBbuffer[0], 0, sizeof(PixelI) * 16 * 16 * pSC->m_pNextSC->cmbWidth);
  2947. }
  2948. if(ProcessLeft(pSC) != ICERR_OK)
  2949. return ICERR_ERROR;
  2950. advanceMRPtr(pSC);
  2951. pSC->Transform = Transform;
  2952. for (pSC->cColumn = 1; pSC->cColumn < pSC->cmbWidth; ++pSC->cColumn)
  2953. {
  2954. if(ProcessCenter(pSC) != ICERR_OK)
  2955. return ICERR_ERROR;
  2956. advanceMRPtr(pSC);
  2957. }
  2958. pSC->Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
  2959. invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
  2960. if(ProcessRight(pSC) != ICERR_OK)
  2961. return ICERR_ERROR;
  2962. if (pSC->cRow) {
  2963. if(pSC->m_Dparam->cThumbnailScale < 2 && (pSC->m_Dparam->bDecodeFullFrame ||
  2964. ((pSC->cRow * 16 > pSC->m_Dparam->cROITopY) && (pSC->cRow * 16 <= pSC->m_Dparam->cROIBottomY + 16)))) {
  2965. if( pSC->Load(pSC) != ICERR_OK ) // bypass CC for thumbnail decode
  2966. return ICERR_ERROR;
  2967. }
  2968. if(pSC->m_Dparam->cThumbnailScale >= 2) // decode thumbnail
  2969. decodeThumbnail(pSC);
  2970. }
  2971. advanceOneMBRow(pSC);
  2972. swapMRPtr(pSC);
  2973. #ifdef REENTRANT_MODE
  2974. *pcDecodedLines = pSC->WMIBI.cLinesDecoded;
  2975. #else
  2976. if (pSC->cRow == cMBRow - 1) {
  2977. //================================
  2978. // bottom row
  2979. ProcessLeft = pSC->ProcessBottomLeft;
  2980. ProcessCenter = pSC->ProcessBottom;
  2981. ProcessRight = pSC->ProcessBottomRight;
  2982. Transform = pSC->m_param.cSubVersion == CODEC_SUBVERSION ?
  2983. invTransformMacroblock : invTransformMacroblock_alteredOperators_hard;
  2984. }
  2985. else {
  2986. ProcessLeft = pSC->ProcessLeft;
  2987. ProcessCenter = pSC->ProcessCenter;
  2988. ProcessRight = pSC->ProcessRight;
  2989. Transform = pSC->TransformCenter;
  2990. }
  2991. #endif // REENTRANT_MODE
  2992. }
  2993. #ifndef REENTRANT_MODE
  2994. fixup_Y_ONLY_to_Others(pSC, pBI);
  2995. #endif // REENTRANT_MODE
  2996. PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  2997. return ICERR_OK;
  2998. }
  2999. Int ImageStrDecTerm(
  3000. CTXSTRCODEC ctxSC)
  3001. {
  3002. CWMImageStrCodec* pSC = (CWMImageStrCodec*)ctxSC;
  3003. if (NULL == pSC)
  3004. {
  3005. return ICERR_OK;
  3006. }
  3007. if (sizeof(*pSC) != pSC->cbStruct)
  3008. {
  3009. return ICERR_ERROR;
  3010. }
  3011. PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  3012. StrDecTerm(pSC);
  3013. PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  3014. PERFTIMER_REPORT(pSC->m_fMeasurePerf, pSC);
  3015. PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  3016. PERFTIMER_DELETE(pSC->m_fMeasurePerf, pSC->m_ptEndToEndPerf);
  3017. free(pSC);
  3018. return ICERR_OK;
  3019. }