Path: blob/master/thirdparty/libwebp/src/dsp/lossless_enc.c
9913 views
// Copyright 2015 Google Inc. All Rights Reserved.1//2// Use of this source code is governed by a BSD-style license3// that can be found in the COPYING file in the root of the source4// tree. An additional intellectual property rights grant can be found5// in the file PATENTS. All contributing project authors may6// be found in the AUTHORS file in the root of the source tree.7// -----------------------------------------------------------------------------8//9// Image transform methods for lossless encoder.10//11// Authors: Vikas Arora ([email protected])12// Jyrki Alakuijala ([email protected])13// Urvang Joshi ([email protected])1415#include "src/dsp/dsp.h"1617#include <assert.h>18#include <math.h>19#include <stdlib.h>20#include "src/dec/vp8li_dec.h"21#include "src/utils/endian_inl_utils.h"22#include "src/dsp/lossless.h"23#include "src/dsp/lossless_common.h"24#include "src/dsp/yuv.h"2526// lookup table for small values of log2(int) * (1 << LOG_2_PRECISION_BITS).27// Obtained in Python with:28// a = [ str(round((1<<23)*math.log2(i))) if i else "0" for i in range(256)]29// print(',\n'.join([' '+','.join(v)30// for v in batched([i.rjust(9) for i in a],7)]))31const uint32_t kLog2Table[LOG_LOOKUP_IDX_MAX] = {320, 0, 8388608, 13295629, 16777216, 19477745, 21684237,3323549800, 25165824, 26591258, 27866353, 29019816, 30072845, 31041538,3431938408, 32773374, 33554432, 34288123, 34979866, 35634199, 36254961,3536845429, 37408424, 37946388, 38461453, 38955489, 39430146, 39886887,3640327016, 40751698, 41161982, 41558811, 41943040, 42315445, 42676731,3743027545, 43368474, 43700062, 44022807, 44337167, 44643569, 44942404,3845234037, 45518808, 45797032, 46069003, 46334996, 46595268, 46850061,3947099600, 47344097, 47583753, 47818754, 48049279, 48275495, 48497560,4048715624, 48929828, 49140306, 49347187, 49550590, 49750631, 49947419,4150141058, 50331648, 50519283, 50704053, 50886044, 51065339, 51242017,4251416153, 51587818, 51757082, 51924012, 52088670, 52251118, 52411415,4352569616, 52725775, 52879946, 53032177, 53182516, 53331012, 53477707,4453622645, 53765868, 53907416, 54047327, 54185640, 54322389, 54457611,4554591338, 54723604, 54854440, 54983876, 55111943, 55238669, 55364082,4655488208, 55611074, 55732705, 55853126, 55972361, 56090432, 56207362,4756323174, 56437887, 56551524, 56664103, 56775645, 56886168, 56995691,4857104232, 57211808, 57318436, 57424133, 57528914, 57632796, 57735795,4957837923, 57939198, 58039632, 58139239, 58238033, 58336027, 58433234,5058529666, 58625336, 58720256, 58814437, 58907891, 59000628, 59092661,5159183999, 59274652, 59364632, 59453947, 59542609, 59630625, 59718006,5259804761, 59890898, 59976426, 60061354, 60145690, 60229443, 60312620,5360395229, 60477278, 60558775, 60639726, 60720140, 60800023, 60879382,5460958224, 61036555, 61114383, 61191714, 61268554, 61344908, 61420785,5561496188, 61571124, 61645600, 61719620, 61793189, 61866315, 61939001,5662011253, 62083076, 62154476, 62225457, 62296024, 62366182, 62435935,5762505289, 62574248, 62642816, 62710997, 62778797, 62846219, 62913267,5862979946, 63046260, 63112212, 63177807, 63243048, 63307939, 63372484,5963436687, 63500551, 63564080, 63627277, 63690146, 63752690, 63814912,6063876816, 63938405, 63999682, 64060650, 64121313, 64181673, 64241734,6164301498, 64360969, 64420148, 64479040, 64537646, 64595970, 64654014,6264711782, 64769274, 64826495, 64883447, 64940132, 64996553, 65052711,6365108611, 65164253, 65219641, 65274776, 65329662, 65384299, 65438691,6465492840, 65546747, 65600416, 65653847, 65707044, 65760008, 65812741,6565865245, 65917522, 65969575, 66021404, 66073013, 66124403, 66175575,6666226531, 66277275, 66327806, 66378127, 66428240, 66478146, 66527847,6766577345, 66626641, 66675737, 66724635, 66773336, 66821842, 66870154,6866918274, 66966204, 67013944, 6706149769};7071// lookup table for small values of int*log2(int) * (1 << LOG_2_PRECISION_BITS).72// Obtained in Python with:73// a=[ "%d"%i if i<(1<<32) else "%dull"%i74// for i in [ round((1<<LOG_2_PRECISION_BITS)*math.log2(i)*i) if i75// else 0 for i in range(256)]]76// print(',\n '.join([','.join(v) for v in batched([i.rjust(15)77// for i in a],4)]))78const uint64_t kSLog2Table[LOG_LOOKUP_IDX_MAX] = {790, 0, 16777216, 39886887,8067108864, 97388723, 130105423, 164848600,81201326592, 239321324, 278663526, 319217973,82360874141, 403539997, 447137711, 491600606,83536870912, 582898099, 629637592, 677049776,84725099212, 773754010, 822985323, 872766924,85923074875, 973887230, 1025183802, 1076945958,861129156447, 1181799249, 1234859451, 1288323135,871342177280, 1396409681, 1451008871, 1505964059,881561265072, 1616902301, 1672866655, 1729149526,891785742744, 1842638548, 1899829557, 1957308741,902015069397, 2073105127, 2131409817, 2189977618ull,912248802933ull, 2307880396ull, 2367204859ull, 2426771383ull,922486575220ull, 2546611805ull, 2606876748ull, 2667365819ull,932728074942ull, 2789000187ull, 2850137762ull, 2911484006ull,942973035382ull, 3034788471ull, 3096739966ull, 3158886666ull,953221225472ull, 3283753383ull, 3346467489ull, 3409364969ull,963472443085ull, 3535699182ull, 3599130679ull, 3662735070ull,973726509920ull, 3790452862ull, 3854561593ull, 3918833872ull,983983267519ull, 4047860410ull, 4112610476ull, 4177515704ull,994242574127ull, 4307783833ull, 4373142952ull, 4438649662ull,1004504302186ull, 4570098787ull, 4636037770ull, 4702117480ull,1014768336298ull, 4834692645ull, 4901184974ull, 4967811774ull,1025034571569ull, 5101462912ull, 5168484389ull, 5235634615ull,1035302912235ull, 5370315922ull, 5437844376ull, 5505496324ull,1045573270518ull, 5641165737ull, 5709180782ull, 5777314477ull,1055845565671ull, 5913933235ull, 5982416059ull, 6051013057ull,1066119723161ull, 6188545324ull, 6257478518ull, 6326521733ull,1076395673979ull, 6464934282ull, 6534301685ull, 6603775250ull,1086673354052ull, 6743037185ull, 6812823756ull, 6882712890ull,1096952703725ull, 7022795412ull, 7092987118ull, 7163278025ull,1107233667324ull, 7304154222ull, 7374737939ull, 7445417707ull,1117516192768ull, 7587062379ull, 7658025806ull, 7729082328ull,1127800231234ull, 7871471825ull, 7942803410ull, 8014225311ull,1138085736859ull, 8157337394ull, 8229026267ull, 8300802839ull,1148372666477ull, 8444616560ull, 8516652476ull, 8588773618ull,1158660979393ull, 8733269211ull, 8805642493ull, 8878098667ull,1168950637170ull, 9023257446ull, 9095958945ull, 9168741125ull,1179241603454ull, 9314545403ull, 9387566451ull, 9460666086ull,1189533843800ull, 9607099093ull, 9680431471ull, 9753840445ull,1199827325535ull, 9900886263ull, 9974522161ull, 10048232765ull,12010122017615ull, 10195876260ull, 10269808253ull, 10343813150ull,12110417890516ull, 10492039919ull, 10566260934ull, 10640553138ull,12210714916116ull, 10789349456ull, 10863852751ull, 10938425600ull,12311013067604ull, 11087778372ull, 11162557513ull, 11237404645ull,12411312319387ull, 11387301364ull, 11462350205ull, 11537465541ull,12511612647010ull, 11687894253ull, 11763206912ull, 11838584638ull,12611914027082ull, 11989533899ull, 12065104750ull, 12140739296ull,12712216437206ull, 12292198148ull, 12368021795ull, 12443907826ull,12812519855920ull, 12595865759ull, 12671937032ull, 12748069427ull,12912824262637ull, 12900516358ull, 12976830290ull, 13053204134ull,13013129637595ull, 13206130381ull, 13282682202ull, 13359292772ull,13113435961806ull, 13512689025ull, 13589474149ull, 13666316903ull,13213743217014ull, 13820174211ull, 13897188225ull, 13974258793ull,13314051385649ull, 14128568535ull, 14205807192ull, 14283101363ull,13414360450796ull, 14437855239ull, 14515314443ull, 14592828162ull,13514670396151ull, 14748018167ull, 14825693972ull, 14903423326ull,13614981205995ull, 15059041743ull, 15136930339ull, 15214871554ull,13715292865160ull, 15370910930ull, 15449008641ull, 15527158071ull,13815605359001ull, 15683611210ull, 15761914485ull, 15840268608ull,13915918673369ull, 15997128556ull, 16075633960ull, 16154189373ull,14016232794589ull, 16311449405ull, 16390153617ull, 16468907026ull,14116547709431ull, 16626560636ull, 16705460444ull, 16784408661ull,14216863405094ull, 16942449552ull, 17021541845ull, 17100681785ull143};144145const VP8LPrefixCode kPrefixEncodeCode[PREFIX_LOOKUP_IDX_MAX] = {146{ 0, 0}, { 0, 0}, { 1, 0}, { 2, 0}, { 3, 0}, { 4, 1}, { 4, 1}, { 5, 1},147{ 5, 1}, { 6, 2}, { 6, 2}, { 6, 2}, { 6, 2}, { 7, 2}, { 7, 2}, { 7, 2},148{ 7, 2}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3}, { 8, 3},149{ 8, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3}, { 9, 3},150{ 9, 3}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4},151{10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4}, {10, 4},152{10, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4},153{11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4}, {11, 4},154{11, 4}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},155{12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},156{12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},157{12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5}, {12, 5},158{12, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},159{13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},160{13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},161{13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5}, {13, 5},162{13, 5}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},163{14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},164{14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},165{14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},166{14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},167{14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},168{14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},169{14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6}, {14, 6},170{14, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},171{15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},172{15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},173{15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},174{15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},175{15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},176{15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},177{15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6}, {15, 6},178{15, 6}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},179{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},180{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},181{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},182{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},183{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},184{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},185{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},186{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},187{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},188{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},189{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},190{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},191{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},192{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},193{16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7}, {16, 7},194{16, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},195{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},196{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},197{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},198{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},199{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},200{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},201{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},202{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},203{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},204{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},205{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},206{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},207{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},208{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},209{17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7}, {17, 7},210};211212const uint8_t kPrefixEncodeExtraBitsValue[PREFIX_LOOKUP_IDX_MAX] = {2130, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 2, 3, 0, 1, 2, 3,2140, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7,2150, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,2160, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,2170, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,21816, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,2190, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,22016, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,2210, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,22216, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,22332, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,22448, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,2250, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,22616, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,22732, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,22848, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,2290, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,23016, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,23132, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,23248, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,23364, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,23480, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,23596, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,236112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,237127,2380, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,23916, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,24032, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,24148, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,24264, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,24380, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,24496, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,245112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126246};247248static uint64_t FastSLog2Slow_C(uint32_t v) {249assert(v >= LOG_LOOKUP_IDX_MAX);250if (v < APPROX_LOG_WITH_CORRECTION_MAX) {251const uint64_t orig_v = v;252uint64_t correction;253#if !defined(WEBP_HAVE_SLOW_CLZ_CTZ)254// use clz if available255const uint64_t log_cnt = BitsLog2Floor(v) - 7;256const uint32_t y = 1 << log_cnt;257v >>= log_cnt;258#else259uint64_t log_cnt = 0;260uint32_t y = 1;261do {262++log_cnt;263v = v >> 1;264y = y << 1;265} while (v >= LOG_LOOKUP_IDX_MAX);266#endif267// vf = (2^log_cnt) * Xf; where y = 2^log_cnt and Xf < 256268// Xf = floor(Xf) * (1 + (v % y) / v)269// log2(Xf) = log2(floor(Xf)) + log2(1 + (v % y) / v)270// The correction factor: log(1 + d) ~ d; for very small d values, so271// log2(1 + (v % y) / v) ~ LOG_2_RECIPROCAL * (v % y)/v272correction = LOG_2_RECIPROCAL_FIXED * (orig_v & (y - 1));273return orig_v * (kLog2Table[v] + (log_cnt << LOG_2_PRECISION_BITS)) +274correction;275} else {276return (uint64_t)(LOG_2_RECIPROCAL_FIXED_DOUBLE * v * log((double)v) + .5);277}278}279280static uint32_t FastLog2Slow_C(uint32_t v) {281assert(v >= LOG_LOOKUP_IDX_MAX);282if (v < APPROX_LOG_WITH_CORRECTION_MAX) {283const uint32_t orig_v = v;284uint32_t log_2;285#if !defined(WEBP_HAVE_SLOW_CLZ_CTZ)286// use clz if available287const uint32_t log_cnt = BitsLog2Floor(v) - 7;288const uint32_t y = 1 << log_cnt;289v >>= log_cnt;290#else291uint32_t log_cnt = 0;292uint32_t y = 1;293do {294++log_cnt;295v = v >> 1;296y = y << 1;297} while (v >= LOG_LOOKUP_IDX_MAX);298#endif299log_2 = kLog2Table[v] + (log_cnt << LOG_2_PRECISION_BITS);300if (orig_v >= APPROX_LOG_MAX) {301// Since the division is still expensive, add this correction factor only302// for large values of 'v'.303const uint64_t correction = LOG_2_RECIPROCAL_FIXED * (orig_v & (y - 1));304log_2 += (uint32_t)DivRound(correction, orig_v);305}306return log_2;307} else {308return (uint32_t)(LOG_2_RECIPROCAL_FIXED_DOUBLE * log((double)v) + .5);309}310}311312//------------------------------------------------------------------------------313// Methods to calculate Entropy (Shannon).314315// Compute the combined Shanon's entropy for distribution {X} and {X+Y}316static uint64_t CombinedShannonEntropy_C(const uint32_t X[256],317const uint32_t Y[256]) {318int i;319uint64_t retval = 0;320uint32_t sumX = 0, sumXY = 0;321for (i = 0; i < 256; ++i) {322const uint32_t x = X[i];323if (x != 0) {324const uint32_t xy = x + Y[i];325sumX += x;326retval += VP8LFastSLog2(x);327sumXY += xy;328retval += VP8LFastSLog2(xy);329} else if (Y[i] != 0) {330sumXY += Y[i];331retval += VP8LFastSLog2(Y[i]);332}333}334retval = VP8LFastSLog2(sumX) + VP8LFastSLog2(sumXY) - retval;335return retval;336}337338static uint64_t ShannonEntropy_C(const uint32_t* X, int n) {339int i;340uint64_t retval = 0;341uint32_t sumX = 0;342for (i = 0; i < n; ++i) {343const int x = X[i];344if (x != 0) {345sumX += x;346retval += VP8LFastSLog2(x);347}348}349retval = VP8LFastSLog2(sumX) - retval;350return retval;351}352353void VP8LBitEntropyInit(VP8LBitEntropy* const entropy) {354entropy->entropy = 0;355entropy->sum = 0;356entropy->nonzeros = 0;357entropy->max_val = 0;358entropy->nonzero_code = VP8L_NON_TRIVIAL_SYM;359}360361void VP8LBitsEntropyUnrefined(const uint32_t* WEBP_RESTRICT const array, int n,362VP8LBitEntropy* WEBP_RESTRICT const entropy) {363int i;364365VP8LBitEntropyInit(entropy);366367for (i = 0; i < n; ++i) {368if (array[i] != 0) {369entropy->sum += array[i];370entropy->nonzero_code = i;371++entropy->nonzeros;372entropy->entropy += VP8LFastSLog2(array[i]);373if (entropy->max_val < array[i]) {374entropy->max_val = array[i];375}376}377}378entropy->entropy = VP8LFastSLog2(entropy->sum) - entropy->entropy;379}380381static WEBP_INLINE void GetEntropyUnrefinedHelper(382uint32_t val, int i, uint32_t* WEBP_RESTRICT const val_prev,383int* WEBP_RESTRICT const i_prev,384VP8LBitEntropy* WEBP_RESTRICT const bit_entropy,385VP8LStreaks* WEBP_RESTRICT const stats) {386const int streak = i - *i_prev;387388// Gather info for the bit entropy.389if (*val_prev != 0) {390bit_entropy->sum += (*val_prev) * streak;391bit_entropy->nonzeros += streak;392bit_entropy->nonzero_code = *i_prev;393bit_entropy->entropy += VP8LFastSLog2(*val_prev) * streak;394if (bit_entropy->max_val < *val_prev) {395bit_entropy->max_val = *val_prev;396}397}398399// Gather info for the Huffman cost.400stats->counts[*val_prev != 0] += (streak > 3);401stats->streaks[*val_prev != 0][(streak > 3)] += streak;402403*val_prev = val;404*i_prev = i;405}406407static void GetEntropyUnrefined_C(408const uint32_t X[], int length,409VP8LBitEntropy* WEBP_RESTRICT const bit_entropy,410VP8LStreaks* WEBP_RESTRICT const stats) {411int i;412int i_prev = 0;413uint32_t x_prev = X[0];414415memset(stats, 0, sizeof(*stats));416VP8LBitEntropyInit(bit_entropy);417418for (i = 1; i < length; ++i) {419const uint32_t x = X[i];420if (x != x_prev) {421GetEntropyUnrefinedHelper(x, i, &x_prev, &i_prev, bit_entropy, stats);422}423}424GetEntropyUnrefinedHelper(0, i, &x_prev, &i_prev, bit_entropy, stats);425426bit_entropy->entropy = VP8LFastSLog2(bit_entropy->sum) - bit_entropy->entropy;427}428429static void GetCombinedEntropyUnrefined_C(430const uint32_t X[], const uint32_t Y[], int length,431VP8LBitEntropy* WEBP_RESTRICT const bit_entropy,432VP8LStreaks* WEBP_RESTRICT const stats) {433int i = 1;434int i_prev = 0;435uint32_t xy_prev = X[0] + Y[0];436437memset(stats, 0, sizeof(*stats));438VP8LBitEntropyInit(bit_entropy);439440for (i = 1; i < length; ++i) {441const uint32_t xy = X[i] + Y[i];442if (xy != xy_prev) {443GetEntropyUnrefinedHelper(xy, i, &xy_prev, &i_prev, bit_entropy, stats);444}445}446GetEntropyUnrefinedHelper(0, i, &xy_prev, &i_prev, bit_entropy, stats);447448bit_entropy->entropy = VP8LFastSLog2(bit_entropy->sum) - bit_entropy->entropy;449}450451//------------------------------------------------------------------------------452453void VP8LSubtractGreenFromBlueAndRed_C(uint32_t* argb_data, int num_pixels) {454int i;455for (i = 0; i < num_pixels; ++i) {456const int argb = (int)argb_data[i];457const int green = (argb >> 8) & 0xff;458const uint32_t new_r = (((argb >> 16) & 0xff) - green) & 0xff;459const uint32_t new_b = (((argb >> 0) & 0xff) - green) & 0xff;460argb_data[i] = ((uint32_t)argb & 0xff00ff00u) | (new_r << 16) | new_b;461}462}463464static WEBP_INLINE int ColorTransformDelta(int8_t color_pred, int8_t color) {465return ((int)color_pred * color) >> 5;466}467468static WEBP_INLINE int8_t U32ToS8(uint32_t v) {469return (int8_t)(v & 0xff);470}471472void VP8LTransformColor_C(const VP8LMultipliers* WEBP_RESTRICT const m,473uint32_t* WEBP_RESTRICT data, int num_pixels) {474int i;475for (i = 0; i < num_pixels; ++i) {476const uint32_t argb = data[i];477const int8_t green = U32ToS8(argb >> 8);478const int8_t red = U32ToS8(argb >> 16);479int new_red = red & 0xff;480int new_blue = argb & 0xff;481new_red -= ColorTransformDelta((int8_t)m->green_to_red_, green);482new_red &= 0xff;483new_blue -= ColorTransformDelta((int8_t)m->green_to_blue_, green);484new_blue -= ColorTransformDelta((int8_t)m->red_to_blue_, red);485new_blue &= 0xff;486data[i] = (argb & 0xff00ff00u) | (new_red << 16) | (new_blue);487}488}489490static WEBP_INLINE uint8_t TransformColorRed(uint8_t green_to_red,491uint32_t argb) {492const int8_t green = U32ToS8(argb >> 8);493int new_red = argb >> 16;494new_red -= ColorTransformDelta((int8_t)green_to_red, green);495return (new_red & 0xff);496}497498static WEBP_INLINE uint8_t TransformColorBlue(uint8_t green_to_blue,499uint8_t red_to_blue,500uint32_t argb) {501const int8_t green = U32ToS8(argb >> 8);502const int8_t red = U32ToS8(argb >> 16);503int new_blue = argb & 0xff;504new_blue -= ColorTransformDelta((int8_t)green_to_blue, green);505new_blue -= ColorTransformDelta((int8_t)red_to_blue, red);506return (new_blue & 0xff);507}508509void VP8LCollectColorRedTransforms_C(const uint32_t* WEBP_RESTRICT argb,510int stride,511int tile_width, int tile_height,512int green_to_red, uint32_t histo[]) {513while (tile_height-- > 0) {514int x;515for (x = 0; x < tile_width; ++x) {516++histo[TransformColorRed((uint8_t)green_to_red, argb[x])];517}518argb += stride;519}520}521522void VP8LCollectColorBlueTransforms_C(const uint32_t* WEBP_RESTRICT argb,523int stride,524int tile_width, int tile_height,525int green_to_blue, int red_to_blue,526uint32_t histo[]) {527while (tile_height-- > 0) {528int x;529for (x = 0; x < tile_width; ++x) {530++histo[TransformColorBlue((uint8_t)green_to_blue, (uint8_t)red_to_blue,531argb[x])];532}533argb += stride;534}535}536537//------------------------------------------------------------------------------538539static int VectorMismatch_C(const uint32_t* const array1,540const uint32_t* const array2, int length) {541int match_len = 0;542543while (match_len < length && array1[match_len] == array2[match_len]) {544++match_len;545}546return match_len;547}548549// Bundles multiple (1, 2, 4 or 8) pixels into a single pixel.550void VP8LBundleColorMap_C(const uint8_t* WEBP_RESTRICT const row,551int width, int xbits, uint32_t* WEBP_RESTRICT dst) {552int x;553if (xbits > 0) {554const int bit_depth = 1 << (3 - xbits);555const int mask = (1 << xbits) - 1;556uint32_t code = 0xff000000;557for (x = 0; x < width; ++x) {558const int xsub = x & mask;559if (xsub == 0) {560code = 0xff000000;561}562code |= row[x] << (8 + bit_depth * xsub);563dst[x >> xbits] = code;564}565} else {566for (x = 0; x < width; ++x) dst[x] = 0xff000000 | (row[x] << 8);567}568}569570//------------------------------------------------------------------------------571572static uint32_t ExtraCost_C(const uint32_t* population, int length) {573int i;574uint32_t cost = population[4] + population[5];575assert(length % 2 == 0);576for (i = 2; i < length / 2 - 1; ++i) {577cost += i * (population[2 * i + 2] + population[2 * i + 3]);578}579return cost;580}581582static uint32_t ExtraCostCombined_C(const uint32_t* WEBP_RESTRICT X,583const uint32_t* WEBP_RESTRICT Y,584int length) {585int i;586uint32_t cost = X[4] + Y[4] + X[5] + Y[5];587assert(length % 2 == 0);588for (i = 2; i < length / 2 - 1; ++i) {589const int xy0 = X[2 * i + 2] + Y[2 * i + 2];590const int xy1 = X[2 * i + 3] + Y[2 * i + 3];591cost += i * (xy0 + xy1);592}593return cost;594}595596//------------------------------------------------------------------------------597598static void AddVector_C(const uint32_t* WEBP_RESTRICT a,599const uint32_t* WEBP_RESTRICT b,600uint32_t* WEBP_RESTRICT out, int size) {601int i;602for (i = 0; i < size; ++i) out[i] = a[i] + b[i];603}604605static void AddVectorEq_C(const uint32_t* WEBP_RESTRICT a,606uint32_t* WEBP_RESTRICT out, int size) {607int i;608for (i = 0; i < size; ++i) out[i] += a[i];609}610611#define ADD(X, ARG, LEN) do { \612if (a->is_used_[X]) { \613if (b->is_used_[X]) { \614VP8LAddVector(a->ARG, b->ARG, out->ARG, (LEN)); \615} else { \616memcpy(&out->ARG[0], &a->ARG[0], (LEN) * sizeof(out->ARG[0])); \617} \618} else if (b->is_used_[X]) { \619memcpy(&out->ARG[0], &b->ARG[0], (LEN) * sizeof(out->ARG[0])); \620} else { \621memset(&out->ARG[0], 0, (LEN) * sizeof(out->ARG[0])); \622} \623} while (0)624625#define ADD_EQ(X, ARG, LEN) do { \626if (a->is_used_[X]) { \627if (out->is_used_[X]) { \628VP8LAddVectorEq(a->ARG, out->ARG, (LEN)); \629} else { \630memcpy(&out->ARG[0], &a->ARG[0], (LEN) * sizeof(out->ARG[0])); \631} \632} \633} while (0)634635void VP8LHistogramAdd(const VP8LHistogram* WEBP_RESTRICT const a,636const VP8LHistogram* WEBP_RESTRICT const b,637VP8LHistogram* WEBP_RESTRICT const out) {638int i;639const int literal_size = VP8LHistogramNumCodes(a->palette_code_bits_);640assert(a->palette_code_bits_ == b->palette_code_bits_);641642if (b != out) {643ADD(0, literal_, literal_size);644ADD(1, red_, NUM_LITERAL_CODES);645ADD(2, blue_, NUM_LITERAL_CODES);646ADD(3, alpha_, NUM_LITERAL_CODES);647ADD(4, distance_, NUM_DISTANCE_CODES);648for (i = 0; i < 5; ++i) {649out->is_used_[i] = (a->is_used_[i] | b->is_used_[i]);650}651} else {652ADD_EQ(0, literal_, literal_size);653ADD_EQ(1, red_, NUM_LITERAL_CODES);654ADD_EQ(2, blue_, NUM_LITERAL_CODES);655ADD_EQ(3, alpha_, NUM_LITERAL_CODES);656ADD_EQ(4, distance_, NUM_DISTANCE_CODES);657for (i = 0; i < 5; ++i) out->is_used_[i] |= a->is_used_[i];658}659}660#undef ADD661#undef ADD_EQ662663//------------------------------------------------------------------------------664// Image transforms.665666static void PredictorSub0_C(const uint32_t* in, const uint32_t* upper,667int num_pixels, uint32_t* WEBP_RESTRICT out) {668int i;669for (i = 0; i < num_pixels; ++i) out[i] = VP8LSubPixels(in[i], ARGB_BLACK);670(void)upper;671}672673static void PredictorSub1_C(const uint32_t* in, const uint32_t* upper,674int num_pixels, uint32_t* WEBP_RESTRICT out) {675int i;676for (i = 0; i < num_pixels; ++i) out[i] = VP8LSubPixels(in[i], in[i - 1]);677(void)upper;678}679680// It subtracts the prediction from the input pixel and stores the residual681// in the output pixel.682#define GENERATE_PREDICTOR_SUB(PREDICTOR_I) \683static void PredictorSub##PREDICTOR_I##_C(const uint32_t* in, \684const uint32_t* upper, \685int num_pixels, \686uint32_t* WEBP_RESTRICT out) { \687int x; \688assert(upper != NULL); \689for (x = 0; x < num_pixels; ++x) { \690const uint32_t pred = \691VP8LPredictor##PREDICTOR_I##_C(&in[x - 1], upper + x); \692out[x] = VP8LSubPixels(in[x], pred); \693} \694}695696GENERATE_PREDICTOR_SUB(2)697GENERATE_PREDICTOR_SUB(3)698GENERATE_PREDICTOR_SUB(4)699GENERATE_PREDICTOR_SUB(5)700GENERATE_PREDICTOR_SUB(6)701GENERATE_PREDICTOR_SUB(7)702GENERATE_PREDICTOR_SUB(8)703GENERATE_PREDICTOR_SUB(9)704GENERATE_PREDICTOR_SUB(10)705GENERATE_PREDICTOR_SUB(11)706GENERATE_PREDICTOR_SUB(12)707GENERATE_PREDICTOR_SUB(13)708709//------------------------------------------------------------------------------710711VP8LProcessEncBlueAndRedFunc VP8LSubtractGreenFromBlueAndRed;712713VP8LTransformColorFunc VP8LTransformColor;714715VP8LCollectColorBlueTransformsFunc VP8LCollectColorBlueTransforms;716VP8LCollectColorRedTransformsFunc VP8LCollectColorRedTransforms;717718VP8LFastLog2SlowFunc VP8LFastLog2Slow;719VP8LFastSLog2SlowFunc VP8LFastSLog2Slow;720721VP8LCostFunc VP8LExtraCost;722VP8LCostCombinedFunc VP8LExtraCostCombined;723VP8LCombinedShannonEntropyFunc VP8LCombinedShannonEntropy;724VP8LShannonEntropyFunc VP8LShannonEntropy;725726VP8LGetEntropyUnrefinedFunc VP8LGetEntropyUnrefined;727VP8LGetCombinedEntropyUnrefinedFunc VP8LGetCombinedEntropyUnrefined;728729VP8LAddVectorFunc VP8LAddVector;730VP8LAddVectorEqFunc VP8LAddVectorEq;731732VP8LVectorMismatchFunc VP8LVectorMismatch;733VP8LBundleColorMapFunc VP8LBundleColorMap;734735VP8LPredictorAddSubFunc VP8LPredictorsSub[16];736VP8LPredictorAddSubFunc VP8LPredictorsSub_C[16];737738extern VP8CPUInfo VP8GetCPUInfo;739extern void VP8LEncDspInitSSE2(void);740extern void VP8LEncDspInitSSE41(void);741extern void VP8LEncDspInitNEON(void);742extern void VP8LEncDspInitMIPS32(void);743extern void VP8LEncDspInitMIPSdspR2(void);744extern void VP8LEncDspInitMSA(void);745746WEBP_DSP_INIT_FUNC(VP8LEncDspInit) {747VP8LDspInit();748749#if !WEBP_NEON_OMIT_C_CODE750VP8LSubtractGreenFromBlueAndRed = VP8LSubtractGreenFromBlueAndRed_C;751752VP8LTransformColor = VP8LTransformColor_C;753#endif754755VP8LCollectColorBlueTransforms = VP8LCollectColorBlueTransforms_C;756VP8LCollectColorRedTransforms = VP8LCollectColorRedTransforms_C;757758VP8LFastLog2Slow = FastLog2Slow_C;759VP8LFastSLog2Slow = FastSLog2Slow_C;760761VP8LExtraCost = ExtraCost_C;762VP8LExtraCostCombined = ExtraCostCombined_C;763VP8LCombinedShannonEntropy = CombinedShannonEntropy_C;764VP8LShannonEntropy = ShannonEntropy_C;765766VP8LGetEntropyUnrefined = GetEntropyUnrefined_C;767VP8LGetCombinedEntropyUnrefined = GetCombinedEntropyUnrefined_C;768769VP8LAddVector = AddVector_C;770VP8LAddVectorEq = AddVectorEq_C;771772VP8LVectorMismatch = VectorMismatch_C;773VP8LBundleColorMap = VP8LBundleColorMap_C;774775VP8LPredictorsSub[0] = PredictorSub0_C;776VP8LPredictorsSub[1] = PredictorSub1_C;777VP8LPredictorsSub[2] = PredictorSub2_C;778VP8LPredictorsSub[3] = PredictorSub3_C;779VP8LPredictorsSub[4] = PredictorSub4_C;780VP8LPredictorsSub[5] = PredictorSub5_C;781VP8LPredictorsSub[6] = PredictorSub6_C;782VP8LPredictorsSub[7] = PredictorSub7_C;783VP8LPredictorsSub[8] = PredictorSub8_C;784VP8LPredictorsSub[9] = PredictorSub9_C;785VP8LPredictorsSub[10] = PredictorSub10_C;786VP8LPredictorsSub[11] = PredictorSub11_C;787VP8LPredictorsSub[12] = PredictorSub12_C;788VP8LPredictorsSub[13] = PredictorSub13_C;789VP8LPredictorsSub[14] = PredictorSub0_C; // <- padding security sentinels790VP8LPredictorsSub[15] = PredictorSub0_C;791792VP8LPredictorsSub_C[0] = PredictorSub0_C;793VP8LPredictorsSub_C[1] = PredictorSub1_C;794VP8LPredictorsSub_C[2] = PredictorSub2_C;795VP8LPredictorsSub_C[3] = PredictorSub3_C;796VP8LPredictorsSub_C[4] = PredictorSub4_C;797VP8LPredictorsSub_C[5] = PredictorSub5_C;798VP8LPredictorsSub_C[6] = PredictorSub6_C;799VP8LPredictorsSub_C[7] = PredictorSub7_C;800VP8LPredictorsSub_C[8] = PredictorSub8_C;801VP8LPredictorsSub_C[9] = PredictorSub9_C;802VP8LPredictorsSub_C[10] = PredictorSub10_C;803VP8LPredictorsSub_C[11] = PredictorSub11_C;804VP8LPredictorsSub_C[12] = PredictorSub12_C;805VP8LPredictorsSub_C[13] = PredictorSub13_C;806VP8LPredictorsSub_C[14] = PredictorSub0_C; // <- padding security sentinels807VP8LPredictorsSub_C[15] = PredictorSub0_C;808809// If defined, use CPUInfo() to overwrite some pointers with faster versions.810if (VP8GetCPUInfo != NULL) {811#if defined(WEBP_HAVE_SSE2)812if (VP8GetCPUInfo(kSSE2)) {813VP8LEncDspInitSSE2();814#if defined(WEBP_HAVE_SSE41)815if (VP8GetCPUInfo(kSSE4_1)) {816VP8LEncDspInitSSE41();817}818#endif819}820#endif821#if defined(WEBP_USE_MIPS32)822if (VP8GetCPUInfo(kMIPS32)) {823VP8LEncDspInitMIPS32();824}825#endif826#if defined(WEBP_USE_MIPS_DSP_R2)827if (VP8GetCPUInfo(kMIPSdspR2)) {828VP8LEncDspInitMIPSdspR2();829}830#endif831#if defined(WEBP_USE_MSA)832if (VP8GetCPUInfo(kMSA)) {833VP8LEncDspInitMSA();834}835#endif836}837838#if defined(WEBP_HAVE_NEON)839if (WEBP_NEON_OMIT_C_CODE ||840(VP8GetCPUInfo != NULL && VP8GetCPUInfo(kNEON))) {841VP8LEncDspInitNEON();842}843#endif844845assert(VP8LSubtractGreenFromBlueAndRed != NULL);846assert(VP8LTransformColor != NULL);847assert(VP8LCollectColorBlueTransforms != NULL);848assert(VP8LCollectColorRedTransforms != NULL);849assert(VP8LFastLog2Slow != NULL);850assert(VP8LFastSLog2Slow != NULL);851assert(VP8LExtraCost != NULL);852assert(VP8LExtraCostCombined != NULL);853assert(VP8LCombinedShannonEntropy != NULL);854assert(VP8LShannonEntropy != NULL);855assert(VP8LGetEntropyUnrefined != NULL);856assert(VP8LGetCombinedEntropyUnrefined != NULL);857assert(VP8LAddVector != NULL);858assert(VP8LAddVectorEq != NULL);859assert(VP8LVectorMismatch != NULL);860assert(VP8LBundleColorMap != NULL);861assert(VP8LPredictorsSub[0] != NULL);862assert(VP8LPredictorsSub[1] != NULL);863assert(VP8LPredictorsSub[2] != NULL);864assert(VP8LPredictorsSub[3] != NULL);865assert(VP8LPredictorsSub[4] != NULL);866assert(VP8LPredictorsSub[5] != NULL);867assert(VP8LPredictorsSub[6] != NULL);868assert(VP8LPredictorsSub[7] != NULL);869assert(VP8LPredictorsSub[8] != NULL);870assert(VP8LPredictorsSub[9] != NULL);871assert(VP8LPredictorsSub[10] != NULL);872assert(VP8LPredictorsSub[11] != NULL);873assert(VP8LPredictorsSub[12] != NULL);874assert(VP8LPredictorsSub[13] != NULL);875assert(VP8LPredictorsSub[14] != NULL);876assert(VP8LPredictorsSub[15] != NULL);877assert(VP8LPredictorsSub_C[0] != NULL);878assert(VP8LPredictorsSub_C[1] != NULL);879assert(VP8LPredictorsSub_C[2] != NULL);880assert(VP8LPredictorsSub_C[3] != NULL);881assert(VP8LPredictorsSub_C[4] != NULL);882assert(VP8LPredictorsSub_C[5] != NULL);883assert(VP8LPredictorsSub_C[6] != NULL);884assert(VP8LPredictorsSub_C[7] != NULL);885assert(VP8LPredictorsSub_C[8] != NULL);886assert(VP8LPredictorsSub_C[9] != NULL);887assert(VP8LPredictorsSub_C[10] != NULL);888assert(VP8LPredictorsSub_C[11] != NULL);889assert(VP8LPredictorsSub_C[12] != NULL);890assert(VP8LPredictorsSub_C[13] != NULL);891assert(VP8LPredictorsSub_C[14] != NULL);892assert(VP8LPredictorsSub_C[15] != NULL);893}894895//------------------------------------------------------------------------------896897898