Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/jxr/image/encode/strPredQuantEnc.c
4393 views
1
//*@@@+++@@@@******************************************************************
2
//
3
// Copyright © Microsoft Corp.
4
// All rights reserved.
5
//
6
// Redistribution and use in source and binary forms, with or without
7
// modification, are permitted provided that the following conditions are met:
8
//
9
// • Redistributions of source code must retain the above copyright notice,
10
// this list of conditions and the following disclaimer.
11
// • Redistributions in binary form must reproduce the above copyright notice,
12
// this list of conditions and the following disclaimer in the documentation
13
// and/or other materials provided with the distribution.
14
//
15
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
// POSSIBILITY OF SUCH DAMAGE.
26
//
27
//*@@@---@@@@******************************************************************
28
29
#include "strcodec.h"
30
#include "encode.h"
31
32
I32 QUANT_Mulless(PixelI v, PixelI o, I32 r)
33
{
34
const I32 m = v >> 31;
35
36
assert(sizeof(PixelI) == sizeof(U32));
37
return ((((v ^ m) - m + o) >> r) ^ m) - m;
38
}
39
40
I32 MUL32HR(U32 a, U32 b, U32 r)
41
{
42
return (I32)((U32)((U64)a * b >> 32) >> r);
43
}
44
45
I32 QUANT(PixelI v, PixelI o, I32 man, I32 exp)
46
{
47
const I32 m = v >> 31;
48
49
assert(sizeof(PixelI) == sizeof(U32));
50
return (MUL32HR((v ^ m) - m + o, man, exp) ^ m) - m;
51
}
52
53
Int quantizeMacroblock(CWMImageStrCodec* pSC)
54
{
55
CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
56
CWMIMBInfo * pMBInfo = &pSC->MBInfo;
57
const COLORFORMAT cf = pSC->m_param.cfColorFormat;
58
int iChannel, i, j;
59
60
if(/*pSC->m_param.bScaledArith && */pSC->m_param.bTranscode == FALSE)
61
for(iChannel = 0; iChannel < (int)pSC->m_param.cNumChannels; iChannel ++){
62
const Bool bUV = (iChannel > 0 && (cf == YUV_444 || cf == YUV_422 || cf == YUV_420));
63
const int iNumBlock = (bUV ? (cf == YUV_422 ? 8 : (cf == YUV_420 ? 4 : 16)) : 16);
64
const int * pOffset = (iNumBlock == 4 ? blkOffsetUV : (iNumBlock == 8 ? blkOffsetUV_422 : blkOffset));
65
CWMIQuantizer * pQPDC = pTile->pQuantizerDC[iChannel];
66
CWMIQuantizer * pQPLP = pTile->pQuantizerLP[iChannel] + pMBInfo->iQIndexLP;
67
CWMIQuantizer * pQPHP = pTile->pQuantizerHP[iChannel] + pMBInfo->iQIndexHP;
68
69
for(j = 0; j < iNumBlock; j ++){
70
PixelI * pData = pSC->pPlane[iChannel] + pOffset[j];
71
72
if(j == 0) // DC
73
pData[0] = (pQPDC->iMan == 0 ? QUANT_Mulless(pData[0], pQPDC->iOffset, pQPDC->iExp) : QUANT(pData[0], pQPDC->iOffset, pQPDC->iMan, pQPDC->iExp));
74
else if(pSC->WMISCP.sbSubband != SB_DC_ONLY) // LP
75
pData[0] = (pQPLP->iMan == 0 ? QUANT_Mulless(pData[0], pQPLP->iOffset, pQPLP->iExp) : QUANT(pData[0], pQPLP->iOffset, pQPLP->iMan, pQPLP->iExp));
76
77
// quantize HP
78
if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS)
79
for(i = 1; i < 16; i ++)
80
pData[i] = (pQPHP->iMan == 0 ? QUANT_Mulless(pData[i], pQPHP->iOffset, pQPHP->iExp) : QUANT(pData[i], pQPHP->iOffset, pQPHP->iMan, pQPHP->iExp));
81
}
82
}
83
84
for(iChannel = 0; iChannel < (int)pSC->m_param.cNumChannels; iChannel ++){
85
I32 * pDC = pSC->MBInfo.iBlockDC[iChannel];
86
PixelI * pData = pSC->pPlane[iChannel];
87
88
if(iChannel > 0 && cf == YUV_422){
89
for(i = 0; i < 8; i ++){
90
pDC[i] = pData[blkOffsetUV_422[i]];
91
}
92
}
93
else if(iChannel > 0 && cf == YUV_420){
94
for(i = 0; i < 4; i ++){
95
pDC[i] = pData[blkOffsetUV[i]];
96
}
97
}
98
else{
99
for(i = 0; i < 16; i ++){
100
pDC[i] = pData[dctIndex[2][i]];
101
}
102
}
103
}
104
105
return 0;
106
}
107
108
/* frequency domain prediction */
109
Void predMacroblockEnc(CWMImageStrCodec * pSC)
110
{
111
const COLORFORMAT cf = pSC->m_param.cfColorFormat;
112
const Int iChannels = (cf == YUV_420 || cf == YUV_422) ? 1 : (Int) pSC->m_param.cNumChannels;
113
size_t mbX = pSC->cColumn - 1;// mbY = pSC->cRow - 1;
114
CWMIMBInfo *pMBInfo = &(pSC->MBInfo);
115
Int iDCACPredMode = getDCACPredMode(pSC, mbX);
116
Int iDCPredMode = (iDCACPredMode & 0x3);
117
Int iADPredMode = (iDCACPredMode & 0xC);
118
Int iACPredMode = getACPredMode(pMBInfo, cf);
119
PixelI * pOrg, * pRef;
120
Int i, j, k;
121
122
pMBInfo->iOrientation = 2 - iACPredMode;
123
124
/* keep necessary info for future prediction */
125
updatePredInfo(pSC, pMBInfo, mbX, cf);
126
127
for(i = 0; i < iChannels; i ++){
128
pOrg = pMBInfo->iBlockDC[i]; // current DC block
129
130
/* DC prediction */
131
if(iDCPredMode == 1){ // predict DC from top
132
pOrg[0] -= (pSC->PredInfoPrevRow[i] + mbX)->iDC;
133
}
134
else if(iDCPredMode == 0){ // predict DC from left
135
pOrg[0] -= (pSC->PredInfo[i] + mbX - 1)->iDC;
136
}
137
else if(iDCPredMode == 2){// predict DC from top&left
138
pOrg[0] -= ((pSC->PredInfo[i] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[i] + mbX)->iDC) >> 1;
139
}
140
141
/* AD prediction */
142
if(iADPredMode == 4){// predict AD from top
143
pRef = (pSC->PredInfoPrevRow[i] + mbX)->piAD;
144
pOrg[4] -= pRef[3], pOrg[8] -= pRef[4], pOrg[12] -= pRef[5];
145
}
146
else if(iADPredMode == 0){// predict AD from left
147
pRef = (pSC->PredInfo[i] + mbX - 1)->piAD;
148
pOrg[1] -= pRef[0], pOrg[2] -= pRef[1], pOrg[3] -= pRef[2];
149
}
150
151
pOrg = pSC->pPlane[i];
152
/* AC prediction */
153
if(iACPredMode == 1){ // predict from top
154
for(k = 0; k <= 192; k += 64){
155
/* inside macroblock, in reverse order */
156
for(j = 48; j > 0; j -= 16){
157
pOrg[k + j + 10] -= pOrg[k + j + 10 - 16];
158
pOrg[k + j + 2] -= pOrg[k + j + 2 - 16];
159
pOrg[k + j + 9] -= pOrg[k + j + 9 - 16];
160
}
161
}
162
}
163
else if(iACPredMode == 0){ // predict from left
164
for(k = 0; k < 64; k += 16){
165
/* inside macroblock, in reverse order */
166
for(j = 192; j > 0; j -= 64){
167
pOrg[k + j + 5] -= pOrg[k + j + 5 - 64];
168
pOrg[k + j + 1] -= pOrg[k + j + 1 - 64];
169
pOrg[k + j + 6] -= pOrg[k + j + 6 - 64];
170
}
171
}
172
}
173
}
174
175
if(cf == YUV_420){
176
for(i = 1; i < 3; i ++){
177
pOrg = pMBInfo->iBlockDC[i]; // current DC block
178
179
/* DC prediciton */
180
if(iDCPredMode == 1){ // predict DC from top
181
pOrg[0] -= (pSC->PredInfoPrevRow[i] + mbX)->iDC;
182
}
183
else if(iDCPredMode == 0){ // predict DC from left
184
pOrg[0] -= (pSC->PredInfo[i] + mbX - 1)->iDC;
185
}
186
else if(iDCPredMode == 2){ // predict DC from top&left
187
pOrg[0] -= (((pSC->PredInfo[i] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[i] + mbX)->iDC + 1) >> 1);
188
}
189
190
/* AD prediction */
191
if(iADPredMode == 4){// predict AD from top
192
pOrg[2] -= (pSC->PredInfoPrevRow[i] + mbX)->piAD[1];
193
}
194
else if(iADPredMode == 0){// predict AD from left
195
pOrg[1] -= (pSC->PredInfo[i] + mbX - 1)->piAD[0];
196
}
197
198
pOrg = pSC->pPlane[i];
199
/* AC prediction */
200
if(iACPredMode == 1){ // predict from top
201
for(j = 16; j <= 48; j += 32){
202
/* inside macroblock */
203
pOrg[j + 10] -= pOrg[j + 10 - 16];
204
pOrg[j + 2] -= pOrg[j + 2 - 16];
205
pOrg[j + 9] -= pOrg[j + 9 - 16];
206
}
207
}
208
else if(iACPredMode == 0){ // predict from left
209
for(j = 32; j <= 48; j += 16){
210
/* inside macroblock */
211
pOrg[j + 5] -= pOrg[j + 5 - 32];
212
pOrg[j + 1] -= pOrg[j + 1 - 32];
213
pOrg[j + 6] -= pOrg[j + 6 - 32];
214
}
215
}
216
}
217
}
218
else if(cf == YUV_422){
219
for(i = 1; i < 3; i ++){
220
pOrg = pMBInfo->iBlockDC[i]; // current DC block
221
222
/* DC prediciton */
223
if(iDCPredMode == 1){ // predict DC from top
224
pOrg[0] -= (pSC->PredInfoPrevRow[i] + mbX)->iDC;
225
}
226
else if(iDCPredMode == 0){ // predict DC from left
227
pOrg[0] -= (pSC->PredInfo[i] + mbX - 1)->iDC;
228
}
229
else if(iDCPredMode == 2){ // predict DC from top&left
230
pOrg[0] -= (((pSC->PredInfo[i] + mbX - 1)->iDC + (pSC->PredInfoPrevRow[i] + mbX)->iDC + 1) >> 1);
231
}
232
233
/* AD prediction */
234
if(iADPredMode == 4){// predict AD from top
235
pOrg[4] -= (pSC->PredInfoPrevRow[i] + mbX)->piAD[4]; // AC of HT !!!
236
pOrg[6] -= pOrg[2];
237
pOrg[2] -= (pSC->PredInfoPrevRow[i] + mbX)->piAD[3];
238
}
239
else if(iADPredMode == 0){// predict AD from left
240
pOrg[4] -= (pSC->PredInfo[i] + mbX - 1)->piAD[4]; // AC of HT !!!
241
pOrg[1] -= (pSC->PredInfo[i] + mbX - 1)->piAD[0];
242
pOrg[5] -= (pSC->PredInfo[i] + mbX - 1)->piAD[2];
243
}
244
else if(iDCPredMode == 1){
245
pOrg[6] -= pOrg[2];
246
}
247
248
pOrg = pSC->pPlane[i]; // current MB
249
/* AC prediction */
250
if(iACPredMode == 1){ // predict from top
251
for(j = 48; j > 0; j -= 16){
252
for(k = 0; k <= 64; k += 64){
253
/* inside macroblock */
254
pOrg[j + k + 10] -= pOrg[j + k + 10 - 16];
255
pOrg[j + k + 2] -= pOrg[j + k + 2 - 16];
256
pOrg[j + k + 9] -= pOrg[j + k + 9 - 16];
257
}
258
}
259
}
260
else if(iACPredMode == 0){ // predict from left
261
for(j = 64; j <= 112; j += 16){
262
/* inside macroblock */
263
pOrg[j + 5] -= pOrg[j + 5 - 64];
264
pOrg[j + 1] -= pOrg[j + 1 - 64];
265
pOrg[j + 6] -= pOrg[j + 6 - 64];
266
}
267
}
268
}
269
}
270
}
271
272
273
/* CBP prediction for 16 x 16 MB */
274
/* block index */
275
/* 0 1 4 5 */
276
/* 2 3 6 7 */
277
/* 8 9 12 13 */
278
/* 10 11 14 15 */
279
280
static int NumOnes(int i)
281
{
282
int retval = 0;
283
static const int g_Count[] = { 0,1,1,2, 1,2,2,3, 1,2,2,3, 2,3,3,4 };
284
i = i & 0xffff;
285
while (i) {
286
retval += g_Count[i & 0xf];
287
i >>= 4;
288
}
289
return retval;
290
}
291
292
#define SATURATE32(x) if((unsigned int)(x + 16) >= 32) { if (x < 0) x = -16; else x = 15; }
293
294
static Int predCBPCEnc(CWMImageStrCodec *pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
295
{
296
Int iPredCBP = 0, iRetval = 0;
297
Int iNOrig = NumOnes(iCBP), iNDiff = AVG_NDIFF;//NumOnes(iPredCBP ^ iCBP);
298
299
UNREFERENCED_PARAMETER( mbY );
300
301
/* only top left block pattern is predicted from neighbour */
302
if(pSC->m_bCtxLeft) {
303
if (pSC->m_bCtxTop) {
304
iPredCBP = 1;
305
}
306
else {
307
Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
308
iPredCBP = (iTopCBP >> 10) & 1; // left: top(10) => 0
309
}
310
}
311
else {
312
Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
313
iPredCBP = ((iLeftCBP >> 5) & 1); // left(5) => 0
314
}
315
316
iPredCBP |= (iCBP & 0x3300) << 2; // [8 9 12 13]->[10 11 14 15]
317
iPredCBP |= (iCBP & 0xcc) << 6; // [2 3 6 7]->[8 9 12 13]
318
iPredCBP |= (iCBP & 0x33) << 2; // [0 1 4 5]->[2 3 6 7]
319
iPredCBP |= (iCBP & 0x11) << 1; // [0 4]->[1 5]
320
iPredCBP |= (iCBP & 0x2) << 3; // [1]->[4]
321
322
if (c) c = 1;
323
if (pModel->m_iState[c] == 0) {
324
iRetval = iPredCBP ^ iCBP;
325
}
326
else if (pModel->m_iState[c] == 1) {
327
iRetval = iCBP;
328
}
329
else {
330
iRetval = iCBP ^ 0xffff;
331
}
332
333
pModel->m_iCount0[c] += iNOrig - iNDiff;
334
SATURATE32(pModel->m_iCount0[c]);
335
336
pModel->m_iCount1[c] += 16 - iNOrig - iNDiff;
337
SATURATE32(pModel->m_iCount1[c]);
338
339
if (pModel->m_iCount0[c] < 0) {
340
if (pModel->m_iCount0[c] < pModel->m_iCount1[c]) {
341
pModel->m_iState[c] = 1;
342
}
343
else {
344
pModel->m_iState[c] = 2;
345
}
346
}
347
else if (pModel->m_iCount1[c] < 0) {
348
pModel->m_iState[c] = 2;
349
}
350
else {
351
pModel->m_iState[c] = 0;
352
}
353
return iRetval;
354
}
355
356
static Int predCBPC420Enc(CWMImageStrCodec *pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
357
{
358
Int iPredCBP = 0, iRetval = 0;
359
Int iNOrig = NumOnes(iCBP) * 4, iNDiff = AVG_NDIFF;//NumOnes(iPredCBP ^ iCBP);
360
361
UNREFERENCED_PARAMETER( mbY );
362
363
/* only top left block pattern is predicted from neighbour */
364
if(pSC->m_bCtxLeft) {
365
if (pSC->m_bCtxTop) {
366
iPredCBP = 1;
367
}
368
else {
369
Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
370
iPredCBP = (iTopCBP >> 2) & 1; // left: top(2) => 0
371
}
372
}
373
else {
374
Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
375
iPredCBP = ((iLeftCBP >> 1) & 1); // left(1) => 0
376
}
377
378
iPredCBP |= (iCBP & 0x1) << 1; // [0]->[1]
379
iPredCBP |= (iCBP & 0x3) << 2; // [0 1]->[2 3]
380
381
if (pModel->m_iState[1] == 0) {
382
iRetval = iPredCBP ^ iCBP;
383
}
384
else if (pModel->m_iState[1] == 1) {
385
iRetval = iCBP;
386
}
387
else {
388
iRetval = iCBP ^ 0xf;
389
}
390
391
pModel->m_iCount0[1] += iNOrig - iNDiff;
392
SATURATE32(pModel->m_iCount0[1]);
393
394
pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;
395
SATURATE32(pModel->m_iCount1[1]);
396
397
if (pModel->m_iCount0[1] < 0) {
398
if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {
399
pModel->m_iState[1] = 1;
400
}
401
else {
402
pModel->m_iState[1] = 2;
403
}
404
}
405
else if (pModel->m_iCount1[1] < 0) {
406
pModel->m_iState[1] = 2;
407
}
408
else {
409
pModel->m_iState[1] = 0;
410
}
411
return iRetval;
412
}
413
414
static Int predCBPC422Enc(CWMImageStrCodec *pSC, Int iCBP, size_t mbX, size_t mbY, size_t c, CCBPModel *pModel)
415
{
416
Int iPredCBP = 0, iRetval = 0;
417
Int iNOrig = NumOnes(iCBP) * 2, iNDiff = AVG_NDIFF;//NumOnes(iPredCBP ^ iCBP);
418
419
UNREFERENCED_PARAMETER( mbY );
420
421
/* only top left block pattern is predicted from neighbour */
422
if(pSC->m_bCtxLeft) {
423
if (pSC->m_bCtxTop) {
424
iPredCBP = 1;
425
}
426
else {
427
Int iTopCBP = (pSC->PredInfoPrevRow[c] + mbX)->iCBP;
428
iPredCBP = (iTopCBP >> 6) & 1; // left: top(6) => 0
429
}
430
}
431
else {
432
Int iLeftCBP = (pSC->PredInfo[c] + mbX - 1)->iCBP;
433
iPredCBP = ((iLeftCBP >> 1) & 1); // left(1) => 0
434
}
435
436
iPredCBP |= (iCBP & 0x1) << 1; // [0]->[1]
437
iPredCBP |= (iCBP & 0x3) << 2; // [0 1]->[2 3]
438
iPredCBP |= (iCBP & 0xc) << 2; // [2 3]->[4 5]
439
iPredCBP |= (iCBP & 0x30) << 2; // [4 5]->[6 7]
440
441
if (pModel->m_iState[1] == 0) {
442
iRetval = iPredCBP ^ iCBP;
443
}
444
else if (pModel->m_iState[1] == 1) {
445
iRetval = iCBP;
446
}
447
else {
448
iRetval = iCBP ^ 0xff;
449
}
450
451
pModel->m_iCount0[1] += iNOrig - iNDiff;
452
SATURATE32(pModel->m_iCount0[1]);
453
454
pModel->m_iCount1[1] += 16 - iNOrig - iNDiff;
455
SATURATE32(pModel->m_iCount1[1]);
456
457
if (pModel->m_iCount0[1] < 0) {
458
if (pModel->m_iCount0[1] < pModel->m_iCount1[1]) {
459
pModel->m_iState[1] = 1;
460
}
461
else {
462
pModel->m_iState[1] = 2;
463
}
464
}
465
else if (pModel->m_iCount1[1] < 0) {
466
pModel->m_iState[1] = 2;
467
}
468
else {
469
pModel->m_iState[1] = 0;
470
}
471
return iRetval;
472
}
473
474
Void predCBPEnc(CWMImageStrCodec* pSC, CCodingContext *pContext)
475
{
476
size_t mbX = pSC->cColumn - 1, mbY = pSC->cRow - 1;
477
CWMIMBInfo * pMBInfo = &(pSC->MBInfo);
478
int iChannel, i, j;
479
480
for(iChannel = 0; iChannel < (int)pSC->m_param.cNumChannels; iChannel ++){
481
const COLORFORMAT cf = pSC->m_param.cfColorFormat;
482
const Bool bUV = (iChannel > 0);
483
const int iNumBlock = (bUV ? (cf == YUV_422 ? 8 : (cf == YUV_420 ? 4 : 16)) : 16);
484
const int * pOffset = (iNumBlock == 4 ? blkOffsetUV : (iNumBlock == 8 ? blkOffsetUV_422 : blkOffset));
485
const Int threshold = (1 << pContext->m_aModelAC.m_iFlcBits[bUV ? 1 : 0]) - 1, threshold2 = threshold * 2 + 1;
486
Int iCBP = 0;
487
488
for(j = 0; j < iNumBlock; j ++){
489
PixelI * pData = pSC->pPlane[iChannel] + pOffset[j];
490
for(i = 1; i < 16; i ++){
491
if((unsigned int)(pData[i] + threshold) >= (unsigned int) threshold2){ // significant coeff
492
iCBP |= (1 << j); // update CBP
493
break;
494
}
495
}
496
}
497
498
pMBInfo->iCBP[iChannel] = (pSC->PredInfo[iChannel] + mbX)->iCBP = iCBP;
499
500
if(iNumBlock == 16){
501
pMBInfo->iDiffCBP[iChannel] = predCBPCEnc(pSC, pMBInfo->iCBP[iChannel], mbX, mbY, iChannel, &pContext->m_aCBPModel);
502
}
503
else if(iNumBlock == 8){
504
pSC->MBInfo.iDiffCBP[iChannel] = predCBPC422Enc(pSC, pMBInfo->iCBP[iChannel], mbX, mbY, iChannel, &pContext->m_aCBPModel);
505
}
506
else{
507
pSC->MBInfo.iDiffCBP[iChannel] = predCBPC420Enc(pSC, pMBInfo->iCBP[iChannel], mbX, mbY, iChannel, &pContext->m_aCBPModel);
508
}
509
}
510
}
511
512
513