lossless_enc.c 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439
  1. // Copyright 2015 Google Inc. All Rights Reserved.
  2. //
  3. // Use of this source code is governed by a BSD-style license
  4. // that can be found in the COPYING file in the root of the source
  5. // tree. An additional intellectual property rights grant can be found
  6. // in the file PATENTS. All contributing project authors may
  7. // be found in the AUTHORS file in the root of the source tree.
  8. // -----------------------------------------------------------------------------
  9. //
  10. // Image transform methods for lossless encoder.
  11. //
  12. // Authors: Vikas Arora ([email protected])
  13. // Jyrki Alakuijala ([email protected])
  14. // Urvang Joshi ([email protected])
  15. #include "./dsp.h"
  16. #include <math.h>
  17. #include <stdlib.h>
  18. #include "../dec/vp8li.h"
  19. #include "../utils/endian_inl.h"
  20. #include "./lossless.h"
  21. #include "./yuv.h"
  22. #define MAX_DIFF_COST (1e30f)
  23. static const int kPredLowEffort = 11;
  24. static const uint32_t kMaskAlpha = 0xff000000;
  25. // lookup table for small values of log2(int)
  26. const float kLog2Table[LOG_LOOKUP_IDX_MAX] = {
  27. 0.0000000000000000f, 0.0000000000000000f,
  28. 1.0000000000000000f, 1.5849625007211560f,
  29. 2.0000000000000000f, 2.3219280948873621f,
  30. 2.5849625007211560f, 2.8073549220576041f,
  31. 3.0000000000000000f, 3.1699250014423121f,
  32. 3.3219280948873621f, 3.4594316186372973f,
  33. 3.5849625007211560f, 3.7004397181410921f,
  34. 3.8073549220576041f, 3.9068905956085187f,
  35. 4.0000000000000000f, 4.0874628412503390f,
  36. 4.1699250014423121f, 4.2479275134435852f,
  37. 4.3219280948873626f, 4.3923174227787606f,
  38. 4.4594316186372973f, 4.5235619560570130f,
  39. 4.5849625007211560f, 4.6438561897747243f,
  40. 4.7004397181410917f, 4.7548875021634682f,
  41. 4.8073549220576037f, 4.8579809951275718f,
  42. 4.9068905956085187f, 4.9541963103868749f,
  43. 5.0000000000000000f, 5.0443941193584533f,
  44. 5.0874628412503390f, 5.1292830169449663f,
  45. 5.1699250014423121f, 5.2094533656289501f,
  46. 5.2479275134435852f, 5.2854022188622487f,
  47. 5.3219280948873626f, 5.3575520046180837f,
  48. 5.3923174227787606f, 5.4262647547020979f,
  49. 5.4594316186372973f, 5.4918530963296747f,
  50. 5.5235619560570130f, 5.5545888516776376f,
  51. 5.5849625007211560f, 5.6147098441152083f,
  52. 5.6438561897747243f, 5.6724253419714951f,
  53. 5.7004397181410917f, 5.7279204545631987f,
  54. 5.7548875021634682f, 5.7813597135246599f,
  55. 5.8073549220576037f, 5.8328900141647412f,
  56. 5.8579809951275718f, 5.8826430493618415f,
  57. 5.9068905956085187f, 5.9307373375628866f,
  58. 5.9541963103868749f, 5.9772799234999167f,
  59. 6.0000000000000000f, 6.0223678130284543f,
  60. 6.0443941193584533f, 6.0660891904577720f,
  61. 6.0874628412503390f, 6.1085244567781691f,
  62. 6.1292830169449663f, 6.1497471195046822f,
  63. 6.1699250014423121f, 6.1898245588800175f,
  64. 6.2094533656289501f, 6.2288186904958804f,
  65. 6.2479275134435852f, 6.2667865406949010f,
  66. 6.2854022188622487f, 6.3037807481771030f,
  67. 6.3219280948873626f, 6.3398500028846243f,
  68. 6.3575520046180837f, 6.3750394313469245f,
  69. 6.3923174227787606f, 6.4093909361377017f,
  70. 6.4262647547020979f, 6.4429434958487279f,
  71. 6.4594316186372973f, 6.4757334309663976f,
  72. 6.4918530963296747f, 6.5077946401986963f,
  73. 6.5235619560570130f, 6.5391588111080309f,
  74. 6.5545888516776376f, 6.5698556083309478f,
  75. 6.5849625007211560f, 6.5999128421871278f,
  76. 6.6147098441152083f, 6.6293566200796094f,
  77. 6.6438561897747243f, 6.6582114827517946f,
  78. 6.6724253419714951f, 6.6865005271832185f,
  79. 6.7004397181410917f, 6.7142455176661224f,
  80. 6.7279204545631987f, 6.7414669864011464f,
  81. 6.7548875021634682f, 6.7681843247769259f,
  82. 6.7813597135246599f, 6.7944158663501061f,
  83. 6.8073549220576037f, 6.8201789624151878f,
  84. 6.8328900141647412f, 6.8454900509443747f,
  85. 6.8579809951275718f, 6.8703647195834047f,
  86. 6.8826430493618415f, 6.8948177633079437f,
  87. 6.9068905956085187f, 6.9188632372745946f,
  88. 6.9307373375628866f, 6.9425145053392398f,
  89. 6.9541963103868749f, 6.9657842846620869f,
  90. 6.9772799234999167f, 6.9886846867721654f,
  91. 7.0000000000000000f, 7.0112272554232539f,
  92. 7.0223678130284543f, 7.0334230015374501f,
  93. 7.0443941193584533f, 7.0552824355011898f,
  94. 7.0660891904577720f, 7.0768155970508308f,
  95. 7.0874628412503390f, 7.0980320829605263f,
  96. 7.1085244567781691f, 7.1189410727235076f,
  97. 7.1292830169449663f, 7.1395513523987936f,
  98. 7.1497471195046822f, 7.1598713367783890f,
  99. 7.1699250014423121f, 7.1799090900149344f,
  100. 7.1898245588800175f, 7.1996723448363644f,
  101. 7.2094533656289501f, 7.2191685204621611f,
  102. 7.2288186904958804f, 7.2384047393250785f,
  103. 7.2479275134435852f, 7.2573878426926521f,
  104. 7.2667865406949010f, 7.2761244052742375f,
  105. 7.2854022188622487f, 7.2946207488916270f,
  106. 7.3037807481771030f, 7.3128829552843557f,
  107. 7.3219280948873626f, 7.3309168781146167f,
  108. 7.3398500028846243f, 7.3487281542310771f,
  109. 7.3575520046180837f, 7.3663222142458160f,
  110. 7.3750394313469245f, 7.3837042924740519f,
  111. 7.3923174227787606f, 7.4008794362821843f,
  112. 7.4093909361377017f, 7.4178525148858982f,
  113. 7.4262647547020979f, 7.4346282276367245f,
  114. 7.4429434958487279f, 7.4512111118323289f,
  115. 7.4594316186372973f, 7.4676055500829976f,
  116. 7.4757334309663976f, 7.4838157772642563f,
  117. 7.4918530963296747f, 7.4998458870832056f,
  118. 7.5077946401986963f, 7.5156998382840427f,
  119. 7.5235619560570130f, 7.5313814605163118f,
  120. 7.5391588111080309f, 7.5468944598876364f,
  121. 7.5545888516776376f, 7.5622424242210728f,
  122. 7.5698556083309478f, 7.5774288280357486f,
  123. 7.5849625007211560f, 7.5924570372680806f,
  124. 7.5999128421871278f, 7.6073303137496104f,
  125. 7.6147098441152083f, 7.6220518194563764f,
  126. 7.6293566200796094f, 7.6366246205436487f,
  127. 7.6438561897747243f, 7.6510516911789281f,
  128. 7.6582114827517946f, 7.6653359171851764f,
  129. 7.6724253419714951f, 7.6794800995054464f,
  130. 7.6865005271832185f, 7.6934869574993252f,
  131. 7.7004397181410917f, 7.7073591320808825f,
  132. 7.7142455176661224f, 7.7210991887071855f,
  133. 7.7279204545631987f, 7.7347096202258383f,
  134. 7.7414669864011464f, 7.7481928495894605f,
  135. 7.7548875021634682f, 7.7615512324444795f,
  136. 7.7681843247769259f, 7.7747870596011736f,
  137. 7.7813597135246599f, 7.7879025593914317f,
  138. 7.7944158663501061f, 7.8008998999203047f,
  139. 7.8073549220576037f, 7.8137811912170374f,
  140. 7.8201789624151878f, 7.8265484872909150f,
  141. 7.8328900141647412f, 7.8392037880969436f,
  142. 7.8454900509443747f, 7.8517490414160571f,
  143. 7.8579809951275718f, 7.8641861446542797f,
  144. 7.8703647195834047f, 7.8765169465649993f,
  145. 7.8826430493618415f, 7.8887432488982591f,
  146. 7.8948177633079437f, 7.9008668079807486f,
  147. 7.9068905956085187f, 7.9128893362299619f,
  148. 7.9188632372745946f, 7.9248125036057812f,
  149. 7.9307373375628866f, 7.9366379390025709f,
  150. 7.9425145053392398f, 7.9483672315846778f,
  151. 7.9541963103868749f, 7.9600019320680805f,
  152. 7.9657842846620869f, 7.9715435539507719f,
  153. 7.9772799234999167f, 7.9829935746943103f,
  154. 7.9886846867721654f, 7.9943534368588577f
  155. };
  156. const float kSLog2Table[LOG_LOOKUP_IDX_MAX] = {
  157. 0.00000000f, 0.00000000f, 2.00000000f, 4.75488750f,
  158. 8.00000000f, 11.60964047f, 15.50977500f, 19.65148445f,
  159. 24.00000000f, 28.52932501f, 33.21928095f, 38.05374781f,
  160. 43.01955001f, 48.10571634f, 53.30296891f, 58.60335893f,
  161. 64.00000000f, 69.48686830f, 75.05865003f, 80.71062276f,
  162. 86.43856190f, 92.23866588f, 98.10749561f, 104.04192499f,
  163. 110.03910002f, 116.09640474f, 122.21143267f, 128.38196256f,
  164. 134.60593782f, 140.88144886f, 147.20671787f, 153.58008562f,
  165. 160.00000000f, 166.46500594f, 172.97373660f, 179.52490559f,
  166. 186.11730005f, 192.74977453f, 199.42124551f, 206.13068654f,
  167. 212.87712380f, 219.65963219f, 226.47733176f, 233.32938445f,
  168. 240.21499122f, 247.13338933f, 254.08384998f, 261.06567603f,
  169. 268.07820003f, 275.12078236f, 282.19280949f, 289.29369244f,
  170. 296.42286534f, 303.57978409f, 310.76392512f, 317.97478424f,
  171. 325.21187564f, 332.47473081f, 339.76289772f, 347.07593991f,
  172. 354.41343574f, 361.77497759f, 369.16017124f, 376.56863518f,
  173. 384.00000000f, 391.45390785f, 398.93001188f, 406.42797576f,
  174. 413.94747321f, 421.48818752f, 429.04981119f, 436.63204548f,
  175. 444.23460010f, 451.85719280f, 459.49954906f, 467.16140179f,
  176. 474.84249102f, 482.54256363f, 490.26137307f, 497.99867911f,
  177. 505.75424759f, 513.52785023f, 521.31926438f, 529.12827280f,
  178. 536.95466351f, 544.79822957f, 552.65876890f, 560.53608414f,
  179. 568.42998244f, 576.34027536f, 584.26677867f, 592.20931226f,
  180. 600.16769996f, 608.14176943f, 616.13135206f, 624.13628279f,
  181. 632.15640007f, 640.19154569f, 648.24156472f, 656.30630539f,
  182. 664.38561898f, 672.47935976f, 680.58738488f, 688.70955430f,
  183. 696.84573069f, 704.99577935f, 713.15956818f, 721.33696754f,
  184. 729.52785023f, 737.73209140f, 745.94956849f, 754.18016116f,
  185. 762.42375127f, 770.68022275f, 778.94946161f, 787.23135586f,
  186. 795.52579543f, 803.83267219f, 812.15187982f, 820.48331383f,
  187. 828.82687147f, 837.18245171f, 845.54995518f, 853.92928416f,
  188. 862.32034249f, 870.72303558f, 879.13727036f, 887.56295522f,
  189. 896.00000000f, 904.44831595f, 912.90781569f, 921.37841320f,
  190. 929.86002376f, 938.35256392f, 946.85595152f, 955.37010560f,
  191. 963.89494641f, 972.43039537f, 980.97637504f, 989.53280911f,
  192. 998.09962237f, 1006.67674069f, 1015.26409097f, 1023.86160116f,
  193. 1032.46920021f, 1041.08681805f, 1049.71438560f, 1058.35183469f,
  194. 1066.99909811f, 1075.65610955f, 1084.32280357f, 1092.99911564f,
  195. 1101.68498204f, 1110.38033993f, 1119.08512727f, 1127.79928282f,
  196. 1136.52274614f, 1145.25545758f, 1153.99735821f, 1162.74838989f,
  197. 1171.50849518f, 1180.27761738f, 1189.05570047f, 1197.84268914f,
  198. 1206.63852876f, 1215.44316535f, 1224.25654560f, 1233.07861684f,
  199. 1241.90932703f, 1250.74862473f, 1259.59645914f, 1268.45278005f,
  200. 1277.31753781f, 1286.19068338f, 1295.07216828f, 1303.96194457f,
  201. 1312.85996488f, 1321.76618236f, 1330.68055071f, 1339.60302413f,
  202. 1348.53355734f, 1357.47210556f, 1366.41862452f, 1375.37307041f,
  203. 1384.33539991f, 1393.30557020f, 1402.28353887f, 1411.26926400f,
  204. 1420.26270412f, 1429.26381818f, 1438.27256558f, 1447.28890615f,
  205. 1456.31280014f, 1465.34420819f, 1474.38309138f, 1483.42941118f,
  206. 1492.48312945f, 1501.54420843f, 1510.61261078f, 1519.68829949f,
  207. 1528.77123795f, 1537.86138993f, 1546.95871952f, 1556.06319119f,
  208. 1565.17476976f, 1574.29342040f, 1583.41910860f, 1592.55180020f,
  209. 1601.69146137f, 1610.83805860f, 1619.99155871f, 1629.15192882f,
  210. 1638.31913637f, 1647.49314911f, 1656.67393509f, 1665.86146266f,
  211. 1675.05570047f, 1684.25661744f, 1693.46418280f, 1702.67836605f,
  212. 1711.89913698f, 1721.12646563f, 1730.36032233f, 1739.60067768f,
  213. 1748.84750254f, 1758.10076802f, 1767.36044551f, 1776.62650662f,
  214. 1785.89892323f, 1795.17766747f, 1804.46271172f, 1813.75402857f,
  215. 1823.05159087f, 1832.35537170f, 1841.66534438f, 1850.98148244f,
  216. 1860.30375965f, 1869.63214999f, 1878.96662767f, 1888.30716711f,
  217. 1897.65374295f, 1907.00633003f, 1916.36490342f, 1925.72943838f,
  218. 1935.09991037f, 1944.47629506f, 1953.85856831f, 1963.24670620f,
  219. 1972.64068498f, 1982.04048108f, 1991.44607117f, 2000.85743204f,
  220. 2010.27454072f, 2019.69737440f, 2029.12591044f, 2038.56012640f
  221. };
  222. const VP8LPrefixCode kPrefixEncodeCode[PREFIX_LOOKUP_IDX_MAX] = {
  223. { 0, 0}, { 0, 0}, { 1, 0}, { 2, 0}, { 3, 0}, { 4, 1}, { 4, 1}, { 5, 1},
  224. { 5, 1}, { 6, 2}, { 6, 2}, { 6, 2}, { 6, 2}, { 7, 2}, { 7, 2}, { 7, 2},
  225. { 7, 2}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3},
  226. { 8, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3},
  227. { 9, 3}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4},
  228. {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4},
  229. {10, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4},
  230. {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4},
  231. {11, 4}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
  232. {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
  233. {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
  234. {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},
  235. {12, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
  236. {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
  237. {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
  238. {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},
  239. {13, 5}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
  240. {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
  241. {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
  242. {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
  243. {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
  244. {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
  245. {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
  246. {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},
  247. {14, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
  248. {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
  249. {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
  250. {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
  251. {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
  252. {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
  253. {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
  254. {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},
  255. {15, 6}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  256. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  257. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  258. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  259. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  260. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  261. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  262. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  263. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  264. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  265. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  266. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  267. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  268. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  269. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  270. {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},
  271. {16, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  272. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  273. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  274. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  275. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  276. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  277. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  278. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  279. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  280. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  281. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  282. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  283. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  284. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  285. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  286. {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},
  287. };
  288. const uint8_t kPrefixEncodeExtraBitsValue[PREFIX_LOOKUP_IDX_MAX] = {
  289. 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 2, 3, 0, 1, 2, 3,
  290. 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,
  291. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  292. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  293. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  294. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  295. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  296. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  297. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  298. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  299. 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  300. 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  301. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  302. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  303. 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  304. 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  305. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  306. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  307. 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  308. 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  309. 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  310. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  311. 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
  312. 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
  313. 127,
  314. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  315. 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  316. 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
  317. 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
  318. 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
  319. 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
  320. 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
  321. 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126
  322. };
  323. static float FastSLog2Slow(uint32_t v) {
  324. assert(v >= LOG_LOOKUP_IDX_MAX);
  325. if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
  326. int log_cnt = 0;
  327. uint32_t y = 1;
  328. int correction = 0;
  329. const float v_f = (float)v;
  330. const uint32_t orig_v = v;
  331. do {
  332. ++log_cnt;
  333. v = v >> 1;
  334. y = y << 1;
  335. } while (v >= LOG_LOOKUP_IDX_MAX);
  336. // vf = (2^log_cnt) * Xf; where y = 2^log_cnt and Xf < 256
  337. // Xf = floor(Xf) * (1 + (v % y) / v)
  338. // log2(Xf) = log2(floor(Xf)) + log2(1 + (v % y) / v)
  339. // The correction factor: log(1 + d) ~ d; for very small d values, so
  340. // log2(1 + (v % y) / v) ~ LOG_2_RECIPROCAL * (v % y)/v
  341. // LOG_2_RECIPROCAL ~ 23/16
  342. correction = (23 * (orig_v & (y - 1))) >> 4;
  343. return v_f * (kLog2Table[v] + log_cnt) + correction;
  344. } else {
  345. return (float)(LOG_2_RECIPROCAL * v * log((double)v));
  346. }
  347. }
  348. static float FastLog2Slow(uint32_t v) {
  349. assert(v >= LOG_LOOKUP_IDX_MAX);
  350. if (v < APPROX_LOG_WITH_CORRECTION_MAX) {
  351. int log_cnt = 0;
  352. uint32_t y = 1;
  353. const uint32_t orig_v = v;
  354. double log_2;
  355. do {
  356. ++log_cnt;
  357. v = v >> 1;
  358. y = y << 1;
  359. } while (v >= LOG_LOOKUP_IDX_MAX);
  360. log_2 = kLog2Table[v] + log_cnt;
  361. if (orig_v >= APPROX_LOG_MAX) {
  362. // Since the division is still expensive, add this correction factor only
  363. // for large values of 'v'.
  364. const int correction = (23 * (orig_v & (y - 1))) >> 4;
  365. log_2 += (double)correction / orig_v;
  366. }
  367. return (float)log_2;
  368. } else {
  369. return (float)(LOG_2_RECIPROCAL * log((double)v));
  370. }
  371. }
  372. // Mostly used to reduce code size + readability
  373. static WEBP_INLINE int GetMin(int a, int b) { return (a > b) ? b : a; }
  374. static WEBP_INLINE int GetMax(int a, int b) { return (a < b) ? b : a; }
  375. //------------------------------------------------------------------------------
  376. // Methods to calculate Entropy (Shannon).
  377. static float PredictionCostSpatial(const int counts[256], int weight_0,
  378. double exp_val) {
  379. const int significant_symbols = 256 >> 4;
  380. const double exp_decay_factor = 0.6;
  381. double bits = weight_0 * counts[0];
  382. int i;
  383. for (i = 1; i < significant_symbols; ++i) {
  384. bits += exp_val * (counts[i] + counts[256 - i]);
  385. exp_val *= exp_decay_factor;
  386. }
  387. return (float)(-0.1 * bits);
  388. }
  389. // Compute the combined Shanon's entropy for distribution {X} and {X+Y}
  390. static float CombinedShannonEntropy(const int X[256], const int Y[256]) {
  391. int i;
  392. double retval = 0.;
  393. int sumX = 0, sumXY = 0;
  394. for (i = 0; i < 256; ++i) {
  395. const int x = X[i];
  396. if (x != 0) {
  397. const int xy = x + Y[i];
  398. sumX += x;
  399. retval -= VP8LFastSLog2(x);
  400. sumXY += xy;
  401. retval -= VP8LFastSLog2(xy);
  402. } else if (Y[i] != 0) {
  403. sumXY += Y[i];
  404. retval -= VP8LFastSLog2(Y[i]);
  405. }
  406. }
  407. retval += VP8LFastSLog2(sumX) + VP8LFastSLog2(sumXY);
  408. return (float)retval;
  409. }
  410. static float PredictionCostSpatialHistogram(const int accumulated[4][256],
  411. const int tile[4][256]) {
  412. int i;
  413. double retval = 0;
  414. for (i = 0; i < 4; ++i) {
  415. const double kExpValue = 0.94;
  416. retval += PredictionCostSpatial(tile[i], 1, kExpValue);
  417. retval += VP8LCombinedShannonEntropy(tile[i], accumulated[i]);
  418. }
  419. return (float)retval;
  420. }
  421. void VP8LBitEntropyInit(VP8LBitEntropy* const entropy) {
  422. entropy->entropy = 0.;
  423. entropy->sum = 0;
  424. entropy->nonzeros = 0;
  425. entropy->max_val = 0;
  426. entropy->nonzero_code = VP8L_NON_TRIVIAL_SYM;
  427. }
  428. void VP8LBitsEntropyUnrefined(const uint32_t* const array, int n,
  429. VP8LBitEntropy* const entropy) {
  430. int i;
  431. VP8LBitEntropyInit(entropy);
  432. for (i = 0; i < n; ++i) {
  433. if (array[i] != 0) {
  434. entropy->sum += array[i];
  435. entropy->nonzero_code = i;
  436. ++entropy->nonzeros;
  437. entropy->entropy -= VP8LFastSLog2(array[i]);
  438. if (entropy->max_val < array[i]) {
  439. entropy->max_val = array[i];
  440. }
  441. }
  442. }
  443. entropy->entropy += VP8LFastSLog2(entropy->sum);
  444. }
  445. static WEBP_INLINE void GetEntropyUnrefinedHelper(
  446. uint32_t val, int i, uint32_t* const val_prev, int* const i_prev,
  447. VP8LBitEntropy* const bit_entropy, VP8LStreaks* const stats) {
  448. const int streak = i - *i_prev;
  449. // Gather info for the bit entropy.
  450. if (*val_prev != 0) {
  451. bit_entropy->sum += (*val_prev) * streak;
  452. bit_entropy->nonzeros += streak;
  453. bit_entropy->nonzero_code = *i_prev;
  454. bit_entropy->entropy -= VP8LFastSLog2(*val_prev) * streak;
  455. if (bit_entropy->max_val < *val_prev) {
  456. bit_entropy->max_val = *val_prev;
  457. }
  458. }
  459. // Gather info for the Huffman cost.
  460. stats->counts[*val_prev != 0] += (streak > 3);
  461. stats->streaks[*val_prev != 0][(streak > 3)] += streak;
  462. *val_prev = val;
  463. *i_prev = i;
  464. }
  465. void VP8LGetEntropyUnrefined(const uint32_t* const X, int length,
  466. VP8LBitEntropy* const bit_entropy,
  467. VP8LStreaks* const stats) {
  468. int i;
  469. int i_prev = 0;
  470. uint32_t x_prev = X[0];
  471. memset(stats, 0, sizeof(*stats));
  472. VP8LBitEntropyInit(bit_entropy);
  473. for (i = 1; i < length; ++i) {
  474. const uint32_t x = X[i];
  475. if (x != x_prev) {
  476. VP8LGetEntropyUnrefinedHelper(x, i, &x_prev, &i_prev, bit_entropy, stats);
  477. }
  478. }
  479. VP8LGetEntropyUnrefinedHelper(0, i, &x_prev, &i_prev, bit_entropy, stats);
  480. bit_entropy->entropy += VP8LFastSLog2(bit_entropy->sum);
  481. }
  482. void VP8LGetCombinedEntropyUnrefined(const uint32_t* const X,
  483. const uint32_t* const Y, int length,
  484. VP8LBitEntropy* const bit_entropy,
  485. VP8LStreaks* const stats) {
  486. int i = 1;
  487. int i_prev = 0;
  488. uint32_t xy_prev = X[0] + Y[0];
  489. memset(stats, 0, sizeof(*stats));
  490. VP8LBitEntropyInit(bit_entropy);
  491. for (i = 1; i < length; ++i) {
  492. const uint32_t xy = X[i] + Y[i];
  493. if (xy != xy_prev) {
  494. VP8LGetEntropyUnrefinedHelper(xy, i, &xy_prev, &i_prev, bit_entropy,
  495. stats);
  496. }
  497. }
  498. VP8LGetEntropyUnrefinedHelper(0, i, &xy_prev, &i_prev, bit_entropy, stats);
  499. bit_entropy->entropy += VP8LFastSLog2(bit_entropy->sum);
  500. }
  501. static WEBP_INLINE void UpdateHisto(int histo_argb[4][256], uint32_t argb) {
  502. ++histo_argb[0][argb >> 24];
  503. ++histo_argb[1][(argb >> 16) & 0xff];
  504. ++histo_argb[2][(argb >> 8) & 0xff];
  505. ++histo_argb[3][argb & 0xff];
  506. }
  507. //------------------------------------------------------------------------------
  508. static WEBP_INLINE uint32_t Predict(VP8LPredictorFunc pred_func,
  509. int x, int y,
  510. const uint32_t* current_row,
  511. const uint32_t* upper_row) {
  512. if (y == 0) {
  513. return (x == 0) ? ARGB_BLACK : current_row[x - 1]; // Left.
  514. } else if (x == 0) {
  515. return upper_row[x]; // Top.
  516. } else {
  517. return pred_func(current_row[x - 1], upper_row + x);
  518. }
  519. }
  520. static int MaxDiffBetweenPixels(uint32_t p1, uint32_t p2) {
  521. const int diff_a = abs((int)(p1 >> 24) - (int)(p2 >> 24));
  522. const int diff_r = abs((int)((p1 >> 16) & 0xff) - (int)((p2 >> 16) & 0xff));
  523. const int diff_g = abs((int)((p1 >> 8) & 0xff) - (int)((p2 >> 8) & 0xff));
  524. const int diff_b = abs((int)(p1 & 0xff) - (int)(p2 & 0xff));
  525. return GetMax(GetMax(diff_a, diff_r), GetMax(diff_g, diff_b));
  526. }
  527. static int MaxDiffAroundPixel(uint32_t current, uint32_t up, uint32_t down,
  528. uint32_t left, uint32_t right) {
  529. const int diff_up = MaxDiffBetweenPixels(current, up);
  530. const int diff_down = MaxDiffBetweenPixels(current, down);
  531. const int diff_left = MaxDiffBetweenPixels(current, left);
  532. const int diff_right = MaxDiffBetweenPixels(current, right);
  533. return GetMax(GetMax(diff_up, diff_down), GetMax(diff_left, diff_right));
  534. }
  535. static uint32_t AddGreenToBlueAndRed(uint32_t argb) {
  536. const uint32_t green = (argb >> 8) & 0xff;
  537. uint32_t red_blue = argb & 0x00ff00ffu;
  538. red_blue += (green << 16) | green;
  539. red_blue &= 0x00ff00ffu;
  540. return (argb & 0xff00ff00u) | red_blue;
  541. }
  542. static void MaxDiffsForRow(int width, int stride, const uint32_t* const argb,
  543. uint8_t* const max_diffs, int used_subtract_green) {
  544. uint32_t current, up, down, left, right;
  545. int x;
  546. if (width <= 2) return;
  547. current = argb[0];
  548. right = argb[1];
  549. if (used_subtract_green) {
  550. current = AddGreenToBlueAndRed(current);
  551. right = AddGreenToBlueAndRed(right);
  552. }
  553. // max_diffs[0] and max_diffs[width - 1] are never used.
  554. for (x = 1; x < width - 1; ++x) {
  555. up = argb[-stride + x];
  556. down = argb[stride + x];
  557. left = current;
  558. current = right;
  559. right = argb[x + 1];
  560. if (used_subtract_green) {
  561. up = AddGreenToBlueAndRed(up);
  562. down = AddGreenToBlueAndRed(down);
  563. right = AddGreenToBlueAndRed(right);
  564. }
  565. max_diffs[x] = MaxDiffAroundPixel(current, up, down, left, right);
  566. }
  567. }
  568. // Quantize the difference between the actual component value and its prediction
  569. // to a multiple of quantization, working modulo 256, taking care not to cross
  570. // a boundary (inclusive upper limit).
  571. static uint8_t NearLosslessComponent(uint8_t value, uint8_t predict,
  572. uint8_t boundary, int quantization) {
  573. const int residual = (value - predict) & 0xff;
  574. const int boundary_residual = (boundary - predict) & 0xff;
  575. const int lower = residual & ~(quantization - 1);
  576. const int upper = lower + quantization;
  577. // Resolve ties towards a value closer to the prediction (i.e. towards lower
  578. // if value comes after prediction and towards upper otherwise).
  579. const int bias = ((boundary - value) & 0xff) < boundary_residual;
  580. if (residual - lower < upper - residual + bias) {
  581. // lower is closer to residual than upper.
  582. if (residual > boundary_residual && lower <= boundary_residual) {
  583. // Halve quantization step to avoid crossing boundary. This midpoint is
  584. // on the same side of boundary as residual because midpoint >= residual
  585. // (since lower is closer than upper) and residual is above the boundary.
  586. return lower + (quantization >> 1);
  587. }
  588. return lower;
  589. } else {
  590. // upper is closer to residual than lower.
  591. if (residual <= boundary_residual && upper > boundary_residual) {
  592. // Halve quantization step to avoid crossing boundary. This midpoint is
  593. // on the same side of boundary as residual because midpoint <= residual
  594. // (since upper is closer than lower) and residual is below the boundary.
  595. return lower + (quantization >> 1);
  596. }
  597. return upper & 0xff;
  598. }
  599. }
  600. // Quantize every component of the difference between the actual pixel value and
  601. // its prediction to a multiple of a quantization (a power of 2, not larger than
  602. // max_quantization which is a power of 2, smaller than max_diff). Take care if
  603. // value and predict have undergone subtract green, which means that red and
  604. // blue are represented as offsets from green.
  605. static uint32_t NearLossless(uint32_t value, uint32_t predict,
  606. int max_quantization, int max_diff,
  607. int used_subtract_green) {
  608. int quantization;
  609. uint8_t new_green = 0;
  610. uint8_t green_diff = 0;
  611. uint8_t a, r, g, b;
  612. if (max_diff <= 2) {
  613. return VP8LSubPixels(value, predict);
  614. }
  615. quantization = max_quantization;
  616. while (quantization >= max_diff) {
  617. quantization >>= 1;
  618. }
  619. if ((value >> 24) == 0 || (value >> 24) == 0xff) {
  620. // Preserve transparency of fully transparent or fully opaque pixels.
  621. a = ((value >> 24) - (predict >> 24)) & 0xff;
  622. } else {
  623. a = NearLosslessComponent(value >> 24, predict >> 24, 0xff, quantization);
  624. }
  625. g = NearLosslessComponent((value >> 8) & 0xff, (predict >> 8) & 0xff, 0xff,
  626. quantization);
  627. if (used_subtract_green) {
  628. // The green offset will be added to red and blue components during decoding
  629. // to obtain the actual red and blue values.
  630. new_green = ((predict >> 8) + g) & 0xff;
  631. // The amount by which green has been adjusted during quantization. It is
  632. // subtracted from red and blue for compensation, to avoid accumulating two
  633. // quantization errors in them.
  634. green_diff = (new_green - (value >> 8)) & 0xff;
  635. }
  636. r = NearLosslessComponent(((value >> 16) - green_diff) & 0xff,
  637. (predict >> 16) & 0xff, 0xff - new_green,
  638. quantization);
  639. b = NearLosslessComponent((value - green_diff) & 0xff, predict & 0xff,
  640. 0xff - new_green, quantization);
  641. return ((uint32_t)a << 24) | ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
  642. }
  643. // Returns the difference between the pixel and its prediction. In case of a
  644. // lossy encoding, updates the source image to avoid propagating the deviation
  645. // further to pixels which depend on the current pixel for their predictions.
  646. static WEBP_INLINE uint32_t GetResidual(int width, int height,
  647. uint32_t* const upper_row,
  648. uint32_t* const current_row,
  649. const uint8_t* const max_diffs,
  650. int mode, VP8LPredictorFunc pred_func,
  651. int x, int y, int max_quantization,
  652. int exact, int used_subtract_green) {
  653. const uint32_t predict = Predict(pred_func, x, y, current_row, upper_row);
  654. uint32_t residual;
  655. if (max_quantization == 1 || mode == 0 || y == 0 || y == height - 1 ||
  656. x == 0 || x == width - 1) {
  657. residual = VP8LSubPixels(current_row[x], predict);
  658. } else {
  659. residual = NearLossless(current_row[x], predict, max_quantization,
  660. max_diffs[x], used_subtract_green);
  661. // Update the source image.
  662. current_row[x] = VP8LAddPixels(predict, residual);
  663. // x is never 0 here so we do not need to update upper_row like below.
  664. }
  665. if (!exact && (current_row[x] & kMaskAlpha) == 0) {
  666. // If alpha is 0, cleanup RGB. We can choose the RGB values of the residual
  667. // for best compression. The prediction of alpha itself can be non-zero and
  668. // must be kept though. We choose RGB of the residual to be 0.
  669. residual &= kMaskAlpha;
  670. // Update the source image.
  671. current_row[x] = predict & ~kMaskAlpha;
  672. // The prediction for the rightmost pixel in a row uses the leftmost pixel
  673. // in that row as its top-right context pixel. Hence if we change the
  674. // leftmost pixel of current_row, the corresponding change must be applied
  675. // to upper_row as well where top-right context is being read from.
  676. if (x == 0 && y != 0) upper_row[width] = current_row[0];
  677. }
  678. return residual;
  679. }
  680. // Returns best predictor and updates the accumulated histogram.
  681. // If max_quantization > 1, assumes that near lossless processing will be
  682. // applied, quantizing residuals to multiples of quantization levels up to
  683. // max_quantization (the actual quantization level depends on smoothness near
  684. // the given pixel).
  685. static int GetBestPredictorForTile(int width, int height,
  686. int tile_x, int tile_y, int bits,
  687. int accumulated[4][256],
  688. uint32_t* const argb_scratch,
  689. const uint32_t* const argb,
  690. int max_quantization,
  691. int exact, int used_subtract_green) {
  692. const int kNumPredModes = 14;
  693. const int start_x = tile_x << bits;
  694. const int start_y = tile_y << bits;
  695. const int tile_size = 1 << bits;
  696. const int max_y = GetMin(tile_size, height - start_y);
  697. const int max_x = GetMin(tile_size, width - start_x);
  698. // Whether there exist columns just outside the tile.
  699. const int have_left = (start_x > 0);
  700. const int have_right = (max_x < width - start_x);
  701. // Position and size of the strip covering the tile and adjacent columns if
  702. // they exist.
  703. const int context_start_x = start_x - have_left;
  704. const int context_width = max_x + have_left + have_right;
  705. // The width of upper_row and current_row is one pixel larger than image width
  706. // to allow the top right pixel to point to the leftmost pixel of the next row
  707. // when at the right edge.
  708. uint32_t* upper_row = argb_scratch;
  709. uint32_t* current_row = upper_row + width + 1;
  710. uint8_t* const max_diffs = (uint8_t*)(current_row + width + 1);
  711. float best_diff = MAX_DIFF_COST;
  712. int best_mode = 0;
  713. int mode;
  714. int histo_stack_1[4][256];
  715. int histo_stack_2[4][256];
  716. // Need pointers to be able to swap arrays.
  717. int (*histo_argb)[256] = histo_stack_1;
  718. int (*best_histo)[256] = histo_stack_2;
  719. int i, j;
  720. for (mode = 0; mode < kNumPredModes; ++mode) {
  721. const VP8LPredictorFunc pred_func = VP8LPredictors[mode];
  722. float cur_diff;
  723. int relative_y;
  724. memset(histo_argb, 0, sizeof(histo_stack_1));
  725. if (start_y > 0) {
  726. // Read the row above the tile which will become the first upper_row.
  727. // Include a pixel to the left if it exists; include a pixel to the right
  728. // in all cases (wrapping to the leftmost pixel of the next row if it does
  729. // not exist).
  730. memcpy(current_row + context_start_x,
  731. argb + (start_y - 1) * width + context_start_x,
  732. sizeof(*argb) * (max_x + have_left + 1));
  733. }
  734. for (relative_y = 0; relative_y < max_y; ++relative_y) {
  735. const int y = start_y + relative_y;
  736. int relative_x;
  737. uint32_t* tmp = upper_row;
  738. upper_row = current_row;
  739. current_row = tmp;
  740. // Read current_row. Include a pixel to the left if it exists; include a
  741. // pixel to the right in all cases except at the bottom right corner of
  742. // the image (wrapping to the leftmost pixel of the next row if it does
  743. // not exist in the current row).
  744. memcpy(current_row + context_start_x,
  745. argb + y * width + context_start_x,
  746. sizeof(*argb) * (max_x + have_left + (y + 1 < height)));
  747. if (max_quantization > 1 && y >= 1 && y + 1 < height) {
  748. MaxDiffsForRow(context_width, width, argb + y * width + context_start_x,
  749. max_diffs + context_start_x, used_subtract_green);
  750. }
  751. for (relative_x = 0; relative_x < max_x; ++relative_x) {
  752. const int x = start_x + relative_x;
  753. UpdateHisto(histo_argb,
  754. GetResidual(width, height, upper_row, current_row,
  755. max_diffs, mode, pred_func, x, y,
  756. max_quantization, exact, used_subtract_green));
  757. }
  758. }
  759. cur_diff = PredictionCostSpatialHistogram(
  760. (const int (*)[256])accumulated, (const int (*)[256])histo_argb);
  761. if (cur_diff < best_diff) {
  762. int (*tmp)[256] = histo_argb;
  763. histo_argb = best_histo;
  764. best_histo = tmp;
  765. best_diff = cur_diff;
  766. best_mode = mode;
  767. }
  768. }
  769. for (i = 0; i < 4; i++) {
  770. for (j = 0; j < 256; j++) {
  771. accumulated[i][j] += best_histo[i][j];
  772. }
  773. }
  774. return best_mode;
  775. }
  776. // Converts pixels of the image to residuals with respect to predictions.
  777. // If max_quantization > 1, applies near lossless processing, quantizing
  778. // residuals to multiples of quantization levels up to max_quantization
  779. // (the actual quantization level depends on smoothness near the given pixel).
  780. static void CopyImageWithPrediction(int width, int height,
  781. int bits, uint32_t* const modes,
  782. uint32_t* const argb_scratch,
  783. uint32_t* const argb,
  784. int low_effort, int max_quantization,
  785. int exact, int used_subtract_green) {
  786. const int tiles_per_row = VP8LSubSampleSize(width, bits);
  787. const int mask = (1 << bits) - 1;
  788. // The width of upper_row and current_row is one pixel larger than image width
  789. // to allow the top right pixel to point to the leftmost pixel of the next row
  790. // when at the right edge.
  791. uint32_t* upper_row = argb_scratch;
  792. uint32_t* current_row = upper_row + width + 1;
  793. uint8_t* current_max_diffs = (uint8_t*)(current_row + width + 1);
  794. uint8_t* lower_max_diffs = current_max_diffs + width;
  795. int y;
  796. int mode = 0;
  797. VP8LPredictorFunc pred_func = NULL;
  798. for (y = 0; y < height; ++y) {
  799. int x;
  800. uint32_t* const tmp32 = upper_row;
  801. upper_row = current_row;
  802. current_row = tmp32;
  803. memcpy(current_row, argb + y * width,
  804. sizeof(*argb) * (width + (y + 1 < height)));
  805. if (low_effort) {
  806. for (x = 0; x < width; ++x) {
  807. const uint32_t predict = Predict(VP8LPredictors[kPredLowEffort], x, y,
  808. current_row, upper_row);
  809. argb[y * width + x] = VP8LSubPixels(current_row[x], predict);
  810. }
  811. } else {
  812. if (max_quantization > 1) {
  813. // Compute max_diffs for the lower row now, because that needs the
  814. // contents of argb for the current row, which we will overwrite with
  815. // residuals before proceeding with the next row.
  816. uint8_t* const tmp8 = current_max_diffs;
  817. current_max_diffs = lower_max_diffs;
  818. lower_max_diffs = tmp8;
  819. if (y + 2 < height) {
  820. MaxDiffsForRow(width, width, argb + (y + 1) * width, lower_max_diffs,
  821. used_subtract_green);
  822. }
  823. }
  824. for (x = 0; x < width; ++x) {
  825. if ((x & mask) == 0) {
  826. mode = (modes[(y >> bits) * tiles_per_row + (x >> bits)] >> 8) & 0xff;
  827. pred_func = VP8LPredictors[mode];
  828. }
  829. argb[y * width + x] = GetResidual(
  830. width, height, upper_row, current_row, current_max_diffs, mode,
  831. pred_func, x, y, max_quantization, exact, used_subtract_green);
  832. }
  833. }
  834. }
  835. }
  836. // Finds the best predictor for each tile, and converts the image to residuals
  837. // with respect to predictions. If near_lossless_quality < 100, applies
  838. // near lossless processing, shaving off more bits of residuals for lower
  839. // qualities.
  840. void VP8LResidualImage(int width, int height, int bits, int low_effort,
  841. uint32_t* const argb, uint32_t* const argb_scratch,
  842. uint32_t* const image, int near_lossless_quality,
  843. int exact, int used_subtract_green) {
  844. const int tiles_per_row = VP8LSubSampleSize(width, bits);
  845. const int tiles_per_col = VP8LSubSampleSize(height, bits);
  846. int tile_y;
  847. int histo[4][256];
  848. const int max_quantization = 1 << VP8LNearLosslessBits(near_lossless_quality);
  849. if (low_effort) {
  850. int i;
  851. for (i = 0; i < tiles_per_row * tiles_per_col; ++i) {
  852. image[i] = ARGB_BLACK | (kPredLowEffort << 8);
  853. }
  854. } else {
  855. memset(histo, 0, sizeof(histo));
  856. for (tile_y = 0; tile_y < tiles_per_col; ++tile_y) {
  857. int tile_x;
  858. for (tile_x = 0; tile_x < tiles_per_row; ++tile_x) {
  859. const int pred = GetBestPredictorForTile(width, height, tile_x, tile_y,
  860. bits, histo, argb_scratch, argb, max_quantization, exact,
  861. used_subtract_green);
  862. image[tile_y * tiles_per_row + tile_x] = ARGB_BLACK | (pred << 8);
  863. }
  864. }
  865. }
  866. CopyImageWithPrediction(width, height, bits, image, argb_scratch, argb,
  867. low_effort, max_quantization, exact,
  868. used_subtract_green);
  869. }
  870. void VP8LSubtractGreenFromBlueAndRed_C(uint32_t* argb_data, int num_pixels) {
  871. int i;
  872. for (i = 0; i < num_pixels; ++i) {
  873. const uint32_t argb = argb_data[i];
  874. const uint32_t green = (argb >> 8) & 0xff;
  875. const uint32_t new_r = (((argb >> 16) & 0xff) - green) & 0xff;
  876. const uint32_t new_b = ((argb & 0xff) - green) & 0xff;
  877. argb_data[i] = (argb & 0xff00ff00) | (new_r << 16) | new_b;
  878. }
  879. }
  880. static WEBP_INLINE void MultipliersClear(VP8LMultipliers* const m) {
  881. m->green_to_red_ = 0;
  882. m->green_to_blue_ = 0;
  883. m->red_to_blue_ = 0;
  884. }
  885. static WEBP_INLINE uint32_t ColorTransformDelta(int8_t color_pred,
  886. int8_t color) {
  887. return (uint32_t)((int)(color_pred) * color) >> 5;
  888. }
  889. static WEBP_INLINE void ColorCodeToMultipliers(uint32_t color_code,
  890. VP8LMultipliers* const m) {
  891. m->green_to_red_ = (color_code >> 0) & 0xff;
  892. m->green_to_blue_ = (color_code >> 8) & 0xff;
  893. m->red_to_blue_ = (color_code >> 16) & 0xff;
  894. }
  895. static WEBP_INLINE uint32_t MultipliersToColorCode(
  896. const VP8LMultipliers* const m) {
  897. return 0xff000000u |
  898. ((uint32_t)(m->red_to_blue_) << 16) |
  899. ((uint32_t)(m->green_to_blue_) << 8) |
  900. m->green_to_red_;
  901. }
  902. void VP8LTransformColor_C(const VP8LMultipliers* const m, uint32_t* data,
  903. int num_pixels) {
  904. int i;
  905. for (i = 0; i < num_pixels; ++i) {
  906. const uint32_t argb = data[i];
  907. const uint32_t green = argb >> 8;
  908. const uint32_t red = argb >> 16;
  909. uint32_t new_red = red;
  910. uint32_t new_blue = argb;
  911. new_red -= ColorTransformDelta(m->green_to_red_, green);
  912. new_red &= 0xff;
  913. new_blue -= ColorTransformDelta(m->green_to_blue_, green);
  914. new_blue -= ColorTransformDelta(m->red_to_blue_, red);
  915. new_blue &= 0xff;
  916. data[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);
  917. }
  918. }
  919. static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red,
  920. uint32_t argb) {
  921. const uint32_t green = argb >> 8;
  922. uint32_t new_red = argb >> 16;
  923. new_red -= ColorTransformDelta(green_to_red, green);
  924. return (new_red & 0xff);
  925. }
  926. static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue,
  927. uint8_t red_to_blue,
  928. uint32_t argb) {
  929. const uint32_t green = argb >> 8;
  930. const uint32_t red = argb >> 16;
  931. uint8_t new_blue = argb;
  932. new_blue -= ColorTransformDelta(green_to_blue, green);
  933. new_blue -= ColorTransformDelta(red_to_blue, red);
  934. return (new_blue & 0xff);
  935. }
  936. static float PredictionCostCrossColor(const int accumulated[256],
  937. const int counts[256]) {
  938. // Favor low entropy, locally and globally.
  939. // Favor small absolute values for PredictionCostSpatial
  940. static const double kExpValue = 2.4;
  941. return VP8LCombinedShannonEntropy(counts, accumulated) +
  942. PredictionCostSpatial(counts, 3, kExpValue);
  943. }
  944. void VP8LCollectColorRedTransforms_C(const uint32_t* argb, int stride,
  945. int tile_width, int tile_height,
  946. int green_to_red, int histo[]) {
  947. while (tile_height-- > 0) {
  948. int x;
  949. for (x = 0; x < tile_width; ++x) {
  950. ++histo[TransformColorRed(green_to_red, argb[x])];
  951. }
  952. argb += stride;
  953. }
  954. }
  955. static float GetPredictionCostCrossColorRed(
  956. const uint32_t* argb, int stride, int tile_width, int tile_height,
  957. VP8LMultipliers prev_x, VP8LMultipliers prev_y, int green_to_red,
  958. const int accumulated_red_histo[256]) {
  959. int histo[256] = { 0 };
  960. float cur_diff;
  961. VP8LCollectColorRedTransforms(argb, stride, tile_width, tile_height,
  962. green_to_red, histo);
  963. cur_diff = PredictionCostCrossColor(accumulated_red_histo, histo);
  964. if ((uint8_t)green_to_red == prev_x.green_to_red_) {
  965. cur_diff -= 3; // favor keeping the areas locally similar
  966. }
  967. if ((uint8_t)green_to_red == prev_y.green_to_red_) {
  968. cur_diff -= 3; // favor keeping the areas locally similar
  969. }
  970. if (green_to_red == 0) {
  971. cur_diff -= 3;
  972. }
  973. return cur_diff;
  974. }
  975. static void GetBestGreenToRed(
  976. const uint32_t* argb, int stride, int tile_width, int tile_height,
  977. VP8LMultipliers prev_x, VP8LMultipliers prev_y, int quality,
  978. const int accumulated_red_histo[256], VP8LMultipliers* const best_tx) {
  979. const int kMaxIters = 4 + ((7 * quality) >> 8); // in range [4..6]
  980. int green_to_red_best = 0;
  981. int iter, offset;
  982. float best_diff = GetPredictionCostCrossColorRed(
  983. argb, stride, tile_width, tile_height, prev_x, prev_y,
  984. green_to_red_best, accumulated_red_histo);
  985. for (iter = 0; iter < kMaxIters; ++iter) {
  986. // ColorTransformDelta is a 3.5 bit fixed point, so 32 is equal to
  987. // one in color computation. Having initial delta here as 1 is sufficient
  988. // to explore the range of (-2, 2).
  989. const int delta = 32 >> iter;
  990. // Try a negative and a positive delta from the best known value.
  991. for (offset = -delta; offset <= delta; offset += 2 * delta) {
  992. const int green_to_red_cur = offset + green_to_red_best;
  993. const float cur_diff = GetPredictionCostCrossColorRed(
  994. argb, stride, tile_width, tile_height, prev_x, prev_y,
  995. green_to_red_cur, accumulated_red_histo);
  996. if (cur_diff < best_diff) {
  997. best_diff = cur_diff;
  998. green_to_red_best = green_to_red_cur;
  999. }
  1000. }
  1001. }
  1002. best_tx->green_to_red_ = green_to_red_best;
  1003. }
  1004. void VP8LCollectColorBlueTransforms_C(const uint32_t* argb, int stride,
  1005. int tile_width, int tile_height,
  1006. int green_to_blue, int red_to_blue,
  1007. int histo[]) {
  1008. while (tile_height-- > 0) {
  1009. int x;
  1010. for (x = 0; x < tile_width; ++x) {
  1011. ++histo[TransformColorBlue(green_to_blue, red_to_blue, argb[x])];
  1012. }
  1013. argb += stride;
  1014. }
  1015. }
  1016. static float GetPredictionCostCrossColorBlue(
  1017. const uint32_t* argb, int stride, int tile_width, int tile_height,
  1018. VP8LMultipliers prev_x, VP8LMultipliers prev_y,
  1019. int green_to_blue, int red_to_blue, const int accumulated_blue_histo[256]) {
  1020. int histo[256] = { 0 };
  1021. float cur_diff;
  1022. VP8LCollectColorBlueTransforms(argb, stride, tile_width, tile_height,
  1023. green_to_blue, red_to_blue, histo);
  1024. cur_diff = PredictionCostCrossColor(accumulated_blue_histo, histo);
  1025. if ((uint8_t)green_to_blue == prev_x.green_to_blue_) {
  1026. cur_diff -= 3; // favor keeping the areas locally similar
  1027. }
  1028. if ((uint8_t)green_to_blue == prev_y.green_to_blue_) {
  1029. cur_diff -= 3; // favor keeping the areas locally similar
  1030. }
  1031. if ((uint8_t)red_to_blue == prev_x.red_to_blue_) {
  1032. cur_diff -= 3; // favor keeping the areas locally similar
  1033. }
  1034. if ((uint8_t)red_to_blue == prev_y.red_to_blue_) {
  1035. cur_diff -= 3; // favor keeping the areas locally similar
  1036. }
  1037. if (green_to_blue == 0) {
  1038. cur_diff -= 3;
  1039. }
  1040. if (red_to_blue == 0) {
  1041. cur_diff -= 3;
  1042. }
  1043. return cur_diff;
  1044. }
  1045. #define kGreenRedToBlueNumAxis 8
  1046. #define kGreenRedToBlueMaxIters 7
  1047. static void GetBestGreenRedToBlue(
  1048. const uint32_t* argb, int stride, int tile_width, int tile_height,
  1049. VP8LMultipliers prev_x, VP8LMultipliers prev_y, int quality,
  1050. const int accumulated_blue_histo[256],
  1051. VP8LMultipliers* const best_tx) {
  1052. const int8_t offset[kGreenRedToBlueNumAxis][2] =
  1053. {{0, -1}, {0, 1}, {-1, 0}, {1, 0}, {-1, -1}, {-1, 1}, {1, -1}, {1, 1}};
  1054. const int8_t delta_lut[kGreenRedToBlueMaxIters] = { 16, 16, 8, 4, 2, 2, 2 };
  1055. const int iters =
  1056. (quality < 25) ? 1 : (quality > 50) ? kGreenRedToBlueMaxIters : 4;
  1057. int green_to_blue_best = 0;
  1058. int red_to_blue_best = 0;
  1059. int iter;
  1060. // Initial value at origin:
  1061. float best_diff = GetPredictionCostCrossColorBlue(
  1062. argb, stride, tile_width, tile_height, prev_x, prev_y,
  1063. green_to_blue_best, red_to_blue_best, accumulated_blue_histo);
  1064. for (iter = 0; iter < iters; ++iter) {
  1065. const int delta = delta_lut[iter];
  1066. int axis;
  1067. for (axis = 0; axis < kGreenRedToBlueNumAxis; ++axis) {
  1068. const int green_to_blue_cur =
  1069. offset[axis][0] * delta + green_to_blue_best;
  1070. const int red_to_blue_cur = offset[axis][1] * delta + red_to_blue_best;
  1071. const float cur_diff = GetPredictionCostCrossColorBlue(
  1072. argb, stride, tile_width, tile_height, prev_x, prev_y,
  1073. green_to_blue_cur, red_to_blue_cur, accumulated_blue_histo);
  1074. if (cur_diff < best_diff) {
  1075. best_diff = cur_diff;
  1076. green_to_blue_best = green_to_blue_cur;
  1077. red_to_blue_best = red_to_blue_cur;
  1078. }
  1079. if (quality < 25 && iter == 4) {
  1080. // Only axis aligned diffs for lower quality.
  1081. break; // next iter.
  1082. }
  1083. }
  1084. if (delta == 2 && green_to_blue_best == 0 && red_to_blue_best == 0) {
  1085. // Further iterations would not help.
  1086. break; // out of iter-loop.
  1087. }
  1088. }
  1089. best_tx->green_to_blue_ = green_to_blue_best;
  1090. best_tx->red_to_blue_ = red_to_blue_best;
  1091. }
  1092. #undef kGreenRedToBlueMaxIters
  1093. #undef kGreenRedToBlueNumAxis
  1094. static VP8LMultipliers GetBestColorTransformForTile(
  1095. int tile_x, int tile_y, int bits,
  1096. VP8LMultipliers prev_x,
  1097. VP8LMultipliers prev_y,
  1098. int quality, int xsize, int ysize,
  1099. const int accumulated_red_histo[256],
  1100. const int accumulated_blue_histo[256],
  1101. const uint32_t* const argb) {
  1102. const int max_tile_size = 1 << bits;
  1103. const int tile_y_offset = tile_y * max_tile_size;
  1104. const int tile_x_offset = tile_x * max_tile_size;
  1105. const int all_x_max = GetMin(tile_x_offset + max_tile_size, xsize);
  1106. const int all_y_max = GetMin(tile_y_offset + max_tile_size, ysize);
  1107. const int tile_width = all_x_max - tile_x_offset;
  1108. const int tile_height = all_y_max - tile_y_offset;
  1109. const uint32_t* const tile_argb = argb + tile_y_offset * xsize
  1110. + tile_x_offset;
  1111. VP8LMultipliers best_tx;
  1112. MultipliersClear(&best_tx);
  1113. GetBestGreenToRed(tile_argb, xsize, tile_width, tile_height,
  1114. prev_x, prev_y, quality, accumulated_red_histo, &best_tx);
  1115. GetBestGreenRedToBlue(tile_argb, xsize, tile_width, tile_height,
  1116. prev_x, prev_y, quality, accumulated_blue_histo,
  1117. &best_tx);
  1118. return best_tx;
  1119. }
  1120. static void CopyTileWithColorTransform(int xsize, int ysize,
  1121. int tile_x, int tile_y,
  1122. int max_tile_size,
  1123. VP8LMultipliers color_transform,
  1124. uint32_t* argb) {
  1125. const int xscan = GetMin(max_tile_size, xsize - tile_x);
  1126. int yscan = GetMin(max_tile_size, ysize - tile_y);
  1127. argb += tile_y * xsize + tile_x;
  1128. while (yscan-- > 0) {
  1129. VP8LTransformColor(&color_transform, argb, xscan);
  1130. argb += xsize;
  1131. }
  1132. }
  1133. void VP8LColorSpaceTransform(int width, int height, int bits, int quality,
  1134. uint32_t* const argb, uint32_t* image) {
  1135. const int max_tile_size = 1 << bits;
  1136. const int tile_xsize = VP8LSubSampleSize(width, bits);
  1137. const int tile_ysize = VP8LSubSampleSize(height, bits);
  1138. int accumulated_red_histo[256] = { 0 };
  1139. int accumulated_blue_histo[256] = { 0 };
  1140. int tile_x, tile_y;
  1141. VP8LMultipliers prev_x, prev_y;
  1142. MultipliersClear(&prev_y);
  1143. MultipliersClear(&prev_x);
  1144. for (tile_y = 0; tile_y < tile_ysize; ++tile_y) {
  1145. for (tile_x = 0; tile_x < tile_xsize; ++tile_x) {
  1146. int y;
  1147. const int tile_x_offset = tile_x * max_tile_size;
  1148. const int tile_y_offset = tile_y * max_tile_size;
  1149. const int all_x_max = GetMin(tile_x_offset + max_tile_size, width);
  1150. const int all_y_max = GetMin(tile_y_offset + max_tile_size, height);
  1151. const int offset = tile_y * tile_xsize + tile_x;
  1152. if (tile_y != 0) {
  1153. ColorCodeToMultipliers(image[offset - tile_xsize], &prev_y);
  1154. }
  1155. prev_x = GetBestColorTransformForTile(tile_x, tile_y, bits,
  1156. prev_x, prev_y,
  1157. quality, width, height,
  1158. accumulated_red_histo,
  1159. accumulated_blue_histo,
  1160. argb);
  1161. image[offset] = MultipliersToColorCode(&prev_x);
  1162. CopyTileWithColorTransform(width, height, tile_x_offset, tile_y_offset,
  1163. max_tile_size, prev_x, argb);
  1164. // Gather accumulated histogram data.
  1165. for (y = tile_y_offset; y < all_y_max; ++y) {
  1166. int ix = y * width + tile_x_offset;
  1167. const int ix_end = ix + all_x_max - tile_x_offset;
  1168. for (; ix < ix_end; ++ix) {
  1169. const uint32_t pix = argb[ix];
  1170. if (ix >= 2 &&
  1171. pix == argb[ix - 2] &&
  1172. pix == argb[ix - 1]) {
  1173. continue; // repeated pixels are handled by backward references
  1174. }
  1175. if (ix >= width + 2 &&
  1176. argb[ix - 2] == argb[ix - width - 2] &&
  1177. argb[ix - 1] == argb[ix - width - 1] &&
  1178. pix == argb[ix - width]) {
  1179. continue; // repeated pixels are handled by backward references
  1180. }
  1181. ++accumulated_red_histo[(pix >> 16) & 0xff];
  1182. ++accumulated_blue_histo[(pix >> 0) & 0xff];
  1183. }
  1184. }
  1185. }
  1186. }
  1187. }
  1188. //------------------------------------------------------------------------------
  1189. static int VectorMismatch(const uint32_t* const array1,
  1190. const uint32_t* const array2, int length) {
  1191. int match_len = 0;
  1192. while (match_len < length && array1[match_len] == array2[match_len]) {
  1193. ++match_len;
  1194. }
  1195. return match_len;
  1196. }
  1197. // Bundles multiple (1, 2, 4 or 8) pixels into a single pixel.
  1198. void VP8LBundleColorMap(const uint8_t* const row, int width,
  1199. int xbits, uint32_t* const dst) {
  1200. int x;
  1201. if (xbits > 0) {
  1202. const int bit_depth = 1 << (3 - xbits);
  1203. const int mask = (1 << xbits) - 1;
  1204. uint32_t code = 0xff000000;
  1205. for (x = 0; x < width; ++x) {
  1206. const int xsub = x & mask;
  1207. if (xsub == 0) {
  1208. code = 0xff000000;
  1209. }
  1210. code |= row[x] << (8 + bit_depth * xsub);
  1211. dst[x >> xbits] = code;
  1212. }
  1213. } else {
  1214. for (x = 0; x < width; ++x) dst[x] = 0xff000000 | (row[x] << 8);
  1215. }
  1216. }
  1217. //------------------------------------------------------------------------------
  1218. static double ExtraCost(const uint32_t* population, int length) {
  1219. int i;
  1220. double cost = 0.;
  1221. for (i = 2; i < length - 2; ++i) cost += (i >> 1) * population[i + 2];
  1222. return cost;
  1223. }
  1224. static double ExtraCostCombined(const uint32_t* X, const uint32_t* Y,
  1225. int length) {
  1226. int i;
  1227. double cost = 0.;
  1228. for (i = 2; i < length - 2; ++i) {
  1229. const int xy = X[i + 2] + Y[i + 2];
  1230. cost += (i >> 1) * xy;
  1231. }
  1232. return cost;
  1233. }
  1234. //------------------------------------------------------------------------------
  1235. static void HistogramAdd(const VP8LHistogram* const a,
  1236. const VP8LHistogram* const b,
  1237. VP8LHistogram* const out) {
  1238. int i;
  1239. const int literal_size = VP8LHistogramNumCodes(a->palette_code_bits_);
  1240. assert(a->palette_code_bits_ == b->palette_code_bits_);
  1241. if (b != out) {
  1242. for (i = 0; i < literal_size; ++i) {
  1243. out->literal_[i] = a->literal_[i] + b->literal_[i];
  1244. }
  1245. for (i = 0; i < NUM_DISTANCE_CODES; ++i) {
  1246. out->distance_[i] = a->distance_[i] + b->distance_[i];
  1247. }
  1248. for (i = 0; i < NUM_LITERAL_CODES; ++i) {
  1249. out->red_[i] = a->red_[i] + b->red_[i];
  1250. out->blue_[i] = a->blue_[i] + b->blue_[i];
  1251. out->alpha_[i] = a->alpha_[i] + b->alpha_[i];
  1252. }
  1253. } else {
  1254. for (i = 0; i < literal_size; ++i) {
  1255. out->literal_[i] += a->literal_[i];
  1256. }
  1257. for (i = 0; i < NUM_DISTANCE_CODES; ++i) {
  1258. out->distance_[i] += a->distance_[i];
  1259. }
  1260. for (i = 0; i < NUM_LITERAL_CODES; ++i) {
  1261. out->red_[i] += a->red_[i];
  1262. out->blue_[i] += a->blue_[i];
  1263. out->alpha_[i] += a->alpha_[i];
  1264. }
  1265. }
  1266. }
  1267. //------------------------------------------------------------------------------
  1268. VP8LProcessBlueAndRedFunc VP8LSubtractGreenFromBlueAndRed;
  1269. VP8LTransformColorFunc VP8LTransformColor;
  1270. VP8LCollectColorBlueTransformsFunc VP8LCollectColorBlueTransforms;
  1271. VP8LCollectColorRedTransformsFunc VP8LCollectColorRedTransforms;
  1272. VP8LFastLog2SlowFunc VP8LFastLog2Slow;
  1273. VP8LFastLog2SlowFunc VP8LFastSLog2Slow;
  1274. VP8LCostFunc VP8LExtraCost;
  1275. VP8LCostCombinedFunc VP8LExtraCostCombined;
  1276. VP8LCombinedShannonEntropyFunc VP8LCombinedShannonEntropy;
  1277. GetEntropyUnrefinedHelperFunc VP8LGetEntropyUnrefinedHelper;
  1278. VP8LHistogramAddFunc VP8LHistogramAdd;
  1279. VP8LVectorMismatchFunc VP8LVectorMismatch;
  1280. extern void VP8LEncDspInitSSE2(void);
  1281. extern void VP8LEncDspInitSSE41(void);
  1282. extern void VP8LEncDspInitNEON(void);
  1283. extern void VP8LEncDspInitMIPS32(void);
  1284. extern void VP8LEncDspInitMIPSdspR2(void);
  1285. static volatile VP8CPUInfo lossless_enc_last_cpuinfo_used =
  1286. (VP8CPUInfo)&lossless_enc_last_cpuinfo_used;
  1287. WEBP_TSAN_IGNORE_FUNCTION void VP8LEncDspInit(void) {
  1288. if (lossless_enc_last_cpuinfo_used == VP8GetCPUInfo) return;
  1289. VP8LDspInit();
  1290. VP8LSubtractGreenFromBlueAndRed = VP8LSubtractGreenFromBlueAndRed_C;
  1291. VP8LTransformColor = VP8LTransformColor_C;
  1292. VP8LCollectColorBlueTransforms = VP8LCollectColorBlueTransforms_C;
  1293. VP8LCollectColorRedTransforms = VP8LCollectColorRedTransforms_C;
  1294. VP8LFastLog2Slow = FastLog2Slow;
  1295. VP8LFastSLog2Slow = FastSLog2Slow;
  1296. VP8LExtraCost = ExtraCost;
  1297. VP8LExtraCostCombined = ExtraCostCombined;
  1298. VP8LCombinedShannonEntropy = CombinedShannonEntropy;
  1299. VP8LGetEntropyUnrefinedHelper = GetEntropyUnrefinedHelper;
  1300. VP8LHistogramAdd = HistogramAdd;
  1301. VP8LVectorMismatch = VectorMismatch;
  1302. // If defined, use CPUInfo() to overwrite some pointers with faster versions.
  1303. if (VP8GetCPUInfo != NULL) {
  1304. #if defined(WEBP_USE_SSE2)
  1305. if (VP8GetCPUInfo(kSSE2)) {
  1306. VP8LEncDspInitSSE2();
  1307. #if defined(WEBP_USE_SSE41)
  1308. if (VP8GetCPUInfo(kSSE4_1)) {
  1309. VP8LEncDspInitSSE41();
  1310. }
  1311. #endif
  1312. }
  1313. #endif
  1314. #if defined(WEBP_USE_NEON)
  1315. if (VP8GetCPUInfo(kNEON)) {
  1316. VP8LEncDspInitNEON();
  1317. }
  1318. #endif
  1319. #if defined(WEBP_USE_MIPS32)
  1320. if (VP8GetCPUInfo(kMIPS32)) {
  1321. VP8LEncDspInitMIPS32();
  1322. }
  1323. #endif
  1324. #if defined(WEBP_USE_MIPS_DSP_R2)
  1325. if (VP8GetCPUInfo(kMIPSdspR2)) {
  1326. VP8LEncDspInitMIPSdspR2();
  1327. }
  1328. #endif
  1329. }
  1330. lossless_enc_last_cpuinfo_used = VP8GetCPUInfo;
  1331. }
  1332. //------------------------------------------------------------------------------