Coverage Report

Created: 2026-04-09 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/jpegxr/r_tile_frequency.c
Line
Count
Source
1
/*************************************************************************
2
*
3
* This software module was originally contributed by Microsoft
4
* Corporation in the course of development of the
5
* ITU-T T.832 | ISO/IEC 29199-2 ("JPEG XR") format standard for
6
* reference purposes and its performance may not have been optimized.
7
*
8
* This software module is an implementation of one or more
9
* tools as specified by the JPEG XR standard.
10
*
11
* ITU/ISO/IEC give You a royalty-free, worldwide, non-exclusive
12
* copyright license to copy, distribute, and make derivative works
13
* of this software module or modifications thereof for use in
14
* products claiming conformance to the JPEG XR standard as
15
* specified by ITU-T T.832 | ISO/IEC 29199-2.
16
*
17
* ITU/ISO/IEC give users the same free license to this software
18
* module or modifications thereof for research purposes and further
19
* ITU/ISO/IEC standardization.
20
*
21
* Those intending to use this software module in products are advised
22
* that its use may infringe existing patents. ITU/ISO/IEC have no
23
* liability for use of this software module or modifications thereof.
24
*
25
* Copyright is not released for products that do not conform to
26
* to the JPEG XR standard as specified by ITU-T T.832 |
27
* ISO/IEC 29199-2.
28
*
29
******** Section to be removed when the standard is published ************
30
*
31
* Assurance that the contributed software module can be used
32
* (1) in the ITU-T "T.JXR" | ISO/IEC 29199 ("JPEG XR") standard once the
33
* standard has been adopted; and
34
* (2) to develop the JPEG XR standard:
35
*
36
* Microsoft Corporation and any subsequent contributors to the development
37
* of this software grant ITU/ISO/IEC all rights necessary to include
38
* the originally developed software module or modifications thereof in the
39
* JPEG XR standard and to permit ITU/ISO/IEC to offer such a royalty-free,
40
* worldwide, non-exclusive copyright license to copy, distribute, and make
41
* derivative works of this software module or modifications thereof for
42
* use in products claiming conformance to the JPEG XR standard as
43
* specified by ITU-T T.832 | ISO/IEC 29199-2, and to the extent that
44
* such originally developed software module or portions of it are included
45
* in an ITU/ISO/IEC standard. To the extent that the original contributors
46
* may own patent rights that would be required to make, use, or sell the
47
* originally developed software module or portions thereof included in the
48
* ITU/ISO/IEC standard in a conforming product, the contributors will
49
* assure ITU/ISO/IEC that they are willing to negotiate licenses under
50
* reasonable and non-discriminatory terms and conditions with
51
* applicants throughout the world and in accordance with their patent
52
* rights declarations made to ITU/ISO/IEC (if any).
53
*
54
* Microsoft, any subsequent contributors, and ITU/ISO/IEC additionally
55
* gives You a free license to this software module or modifications
56
* thereof for the sole purpose of developing the JPEG XR standard.
57
*
58
******** end of section to be removed when the standard is published *****
59
*
60
* Microsoft Corporation retains full right to modify and use the code
61
* for its own purpose, to assign or donate the code to a third party,
62
* and to inhibit third parties from using the code for products that
63
* do not conform to the JPEG XR standard as specified by ITU-T T.832 |
64
* ISO/IEC 29199-2.
65
*
66
* This copyright notice must be included in all copies or derivative
67
* works.
68
*
69
* Copyright (c) ITU-T/ISO/IEC 2008, 2009.
70
***********************************************************************/
71
72
#ifdef _MSC_VER
73
#pragma comment (user,"$Id: r_tile_frequency.c,v 1.9 2011-11-08 20:17:29 thor Exp $")
74
#endif
75
76
# include "jxr_priv.h"
77
# include <assert.h>
78
79
static void backup_dc_strip(jxr_image_t image, int tx, int ty, int my);
80
static void backup_dclp_strip(jxr_image_t image, int tx, int ty, int my);
81
static void backup_hp_strip(jxr_image_t image, int tx, int ty, int my);
82
static void recover_dc_strip(jxr_image_t image, int tx, int ty, int my);
83
static void recover_dclp_strip(jxr_image_t image, int tx, int ty, int my);
84
static void recover_dclphp_strip(jxr_image_t image, int tx, int ty, int my);
85
86
int _jxr_r_TILE_DC(jxr_image_t image, struct rbitstream*str,
87
                   unsigned tx, unsigned ty)
88
0
{
89
0
    unsigned mx, my;
90
0
    unsigned mb_height;
91
0
    unsigned mb_width;
92
0
    unsigned char s0, s1, s2, s3;
93
0
    DEBUG("START TILE_DC at tile=[%u %u] bitpos=%zu\n", tx, ty, _jxr_rbitstream_bitpos(str));
94
95
    /* TILE_STARTCODE == 1 */
96
0
    s0 = _jxr_rbitstream_uint8(str); /* 0x00 */
97
0
    s1 = _jxr_rbitstream_uint8(str); /* 0x00 */
98
0
    s2 = _jxr_rbitstream_uint8(str); /* 0x01 */
99
0
    s3 = _jxr_rbitstream_uint8(str); /* reserved */
100
0
    DEBUG(" TILE_STARTCODE == %02x %02x %02x (reserved: %02x)\n", s0, s1, s2, s3);
101
102
0
    if (s0 != 0x00 || s1 != 0x00 || s2 != 0x01) {
103
0
      DEBUG(" TILE_LOWPASS ERROR: Invalid marker.\n");
104
0
      return JXR_EC_ERROR;
105
      /* FIX THOR: Invalid TILE_STARTCODE detected */
106
0
    }
107
108
0
    _jxr_r_TILE_HEADER_DC(image, str, 0 /* alpha */, tx, ty);
109
0
    if (ALPHACHANNEL_FLAG(image))
110
0
        _jxr_r_TILE_HEADER_DC(image->alpha, str, 1, tx, ty);
111
112
113
    /* Now form and write out all the compressed data for the
114
    tile. This involves scanning the macroblocks, and the
115
    blocks within the macroblocks, generating bits as we go. */
116
117
0
    mb_height = EXTENDED_HEIGHT_BLOCKS(image);
118
0
    mb_width = EXTENDED_WIDTH_BLOCKS(image);
119
120
0
    if (TILING_FLAG(image)) {
121
0
        mb_height = image->tile_row_height[ty];
122
0
        mb_width = image->tile_column_width[tx];
123
0
    }
124
125
0
    for (my = 0 ; my < mb_height ; my += 1) {
126
0
        _jxr_r_rotate_mb_strip(image);
127
0
        image->cur_my = my;
128
0
        for (mx = 0 ; mx < mb_width ; mx += 1) {
129
0
            _jxr_r_MB_DC(image, str, 0, tx, ty, mx, my);
130
0
            if (image->bands_present == 3 /* DCONLY */)
131
0
                _jxr_complete_cur_dclp(image, tx, mx, my);
132
0
            if (ALPHACHANNEL_FLAG(image)) {
133
0
                _jxr_r_MB_DC(image->alpha, str, 1, tx, ty, mx, my);
134
0
                if (image->alpha->bands_present == 3 /* DCONLY */)
135
0
                    _jxr_complete_cur_dclp(image->alpha, tx, mx, my);
136
0
            }
137
0
        }
138
139
0
        if (ALPHACHANNEL_FLAG(image))
140
0
            backup_dc_strip(image->alpha, tx, ty, my);
141
142
0
        backup_dc_strip(image, tx, ty, my);
143
0
    }
144
145
0
    _jxr_rbitstream_syncbyte(str);
146
0
    DEBUG("END TILE_DC\n");
147
148
0
    return 0;
149
0
}
150
151
int _jxr_r_TILE_LP(jxr_image_t image, struct rbitstream*str,
152
                   unsigned tx, unsigned ty)
153
0
{
154
0
    unsigned mx, my;
155
0
    unsigned plane_idx, num_planes;
156
0
    unsigned mb_height;
157
0
    unsigned mb_width;
158
0
    unsigned char s0, s1, s2, s3;
159
0
    DEBUG("START TILE_LOWPASS at tile=[%u %u] bitpos=%zu\n", tx, ty, _jxr_rbitstream_bitpos(str));
160
161
    /* TILE_STARTCODE == 1 */
162
0
    s0 = _jxr_rbitstream_uint8(str); /* 0x00 */
163
0
    s1 = _jxr_rbitstream_uint8(str); /* 0x00 */
164
0
    s2 = _jxr_rbitstream_uint8(str); /* 0x01 */
165
0
    s3 = _jxr_rbitstream_uint8(str); /* reserved */
166
0
    DEBUG(" TILE_STARTCODE == %02x %02x %02x (reserved: %02x)\n", s0, s1, s2, s3);
167
0
    if (s0 != 0x00 || s1 != 0x00 || s2 != 0x01) {
168
0
        DEBUG(" TILE_LOWPASS ERROR: Invalid marker.\n");
169
0
        return JXR_EC_ERROR;
170
0
    }
171
172
0
    _jxr_r_TILE_HEADER_LOWPASS(image, str, 0 /* alpha */, tx, ty);
173
0
    if (ALPHACHANNEL_FLAG(image))
174
0
        _jxr_r_TILE_HEADER_LOWPASS(image->alpha, str, 1, tx, ty);
175
176
    /* Now form and write out all the compressed data for the
177
    tile. This involves scanning the macroblocks, and the
178
    blocks within the macroblocks, generating bits as we go. */
179
180
0
    mb_height = EXTENDED_HEIGHT_BLOCKS(image);
181
0
    mb_width = EXTENDED_WIDTH_BLOCKS(image);
182
183
0
    if (TILING_FLAG(image)) {
184
0
        mb_height = image->tile_row_height[ty];
185
0
        mb_width = image->tile_column_width[tx];
186
0
    }
187
188
0
    num_planes = ((ALPHACHANNEL_FLAG(image)) ? 2 : 1);
189
0
    for (my = 0 ; my < mb_height ; my += 1) {
190
0
        _jxr_r_rotate_mb_strip(image);
191
0
        if (ALPHACHANNEL_FLAG(image)) {
192
0
            image->alpha->cur_my = my;
193
0
            recover_dc_strip(image->alpha, tx, ty, my);
194
0
        }
195
0
        image->cur_my = my;
196
0
        recover_dc_strip(image, tx, ty, my);
197
198
0
        for (mx = 0 ; mx < mb_width ; mx += 1)
199
0
        for (plane_idx = 0; plane_idx < num_planes; plane_idx ++) {
200
            /* The qp_index_lp table goes only into channel 0 */
201
0
            int qp_index_lp = 0;
202
0
            int ch;
203
0
            jxr_image_t plane = (plane_idx == 0 ? image : image->alpha);
204
205
0
            if (!plane->lp_use_dc_qp && plane->num_lp_qps>1) {
206
0
                qp_index_lp = _jxr_DECODE_QP_INDEX(str, plane->num_lp_qps);
207
0
                DEBUG(" DECODE_QP_INDEX(%d) --> %u\n", plane->num_lp_qps, qp_index_lp);
208
0
            }
209
0
            for (ch = 0 ; ch < plane->num_channels ; ch += 1) {
210
0
                MACROBLK_CUR_LP_QUANT(plane,ch,tx,mx) = qp_index_lp;
211
0
                DEBUG(" LP_QUANT for MBx=%d ch=%d is %d\n", mx, ch, MACROBLK_CUR_LP_QUANT(plane,ch,tx,mx));
212
0
            }
213
0
            _jxr_r_MB_LP(plane, str, 0, tx, ty, mx, my);
214
0
            if (plane->bands_present != 3 /* !DCONLY */)
215
0
                _jxr_complete_cur_dclp(plane, tx, mx, my);
216
217
0
        }
218
0
        if (ALPHACHANNEL_FLAG(image))
219
0
            backup_dclp_strip(image->alpha, tx, ty, my);
220
0
        backup_dclp_strip(image, tx, ty, my);
221
0
    }
222
223
0
    _jxr_rbitstream_syncbyte(str);
224
0
    DEBUG("END TILE_LOWPASS\n");
225
0
    return 0;
226
0
}
227
228
int _jxr_r_TILE_HP(jxr_image_t image, struct rbitstream*str,
229
                   unsigned tx, unsigned ty)
230
0
{
231
0
    unsigned mx, my;
232
0
    unsigned plane_idx, num_planes;
233
0
    unsigned mb_height;
234
0
    unsigned mb_width;
235
0
    unsigned char s0, s1, s2, s3;
236
0
    DEBUG("START TILE_HIGHPASS at tile=[%u %u] bitpos=%zu\n", tx, ty, _jxr_rbitstream_bitpos(str));
237
238
    /* TILE_STARTCODE == 1 */
239
0
    s0 = _jxr_rbitstream_uint8(str); /* 0x00 */
240
0
    s1 = _jxr_rbitstream_uint8(str); /* 0x00 */
241
0
    s2 = _jxr_rbitstream_uint8(str); /* 0x01 */
242
0
    s3 = _jxr_rbitstream_uint8(str); /* reserved */
243
0
    DEBUG(" TILE_STARTCODE == %02x %02x %02x (reserved: %02x)\n", s0, s1, s2, s3);
244
0
    if (s0 != 0x00 || s1 != 0x00 || s2 != 0x01) {
245
0
        DEBUG(" TILE_HIGHPASS ERROR: Invalid marker.\n");
246
0
        return JXR_EC_ERROR;
247
0
    }
248
249
0
    _jxr_r_TILE_HEADER_HIGHPASS(image, str, 0 /* alpha */, tx, ty);
250
0
    if (ALPHACHANNEL_FLAG(image))
251
0
        _jxr_r_TILE_HEADER_HIGHPASS(image->alpha, str, 1, tx, ty);
252
253
    /* Now form and write out all the compressed data for the
254
    tile. This involves scanning the macroblocks, and the
255
    blocks within the macroblocks, generating bits as we go. */
256
257
0
    mb_height = EXTENDED_HEIGHT_BLOCKS(image);
258
0
    mb_width = EXTENDED_WIDTH_BLOCKS(image);
259
260
0
    if (TILING_FLAG(image)) {
261
0
        mb_height = image->tile_row_height[ty];
262
0
        mb_width = image->tile_column_width[tx];
263
0
    }
264
265
0
    num_planes = ((ALPHACHANNEL_FLAG(image)) ? 2 : 1);
266
0
    for (my = 0 ; my < mb_height ; my += 1) {
267
0
        _jxr_r_rotate_mb_strip(image);
268
269
0
        if (ALPHACHANNEL_FLAG(image)) {
270
0
            image->alpha->cur_my = my;
271
0
            recover_dclp_strip(image->alpha, tx, ty, my);
272
0
        }
273
0
        image->cur_my = my;
274
0
        recover_dclp_strip(image, tx, ty, my);
275
276
0
        for (mx = 0 ; mx < mb_width ; mx += 1)
277
0
        for (plane_idx = 0; plane_idx < num_planes; plane_idx ++) {
278
            /* The qp_index_hp table goes only into channel 0 */
279
0
            int qp_index_hp = 0;
280
0
            int ch;
281
0
            int rc;
282
0
            jxr_image_t plane = (plane_idx == 0 ? image : image->alpha);
283
0
            if (plane->num_hp_qps>1) {
284
0
                if (!plane->hp_use_lp_qp)
285
0
                    qp_index_hp = _jxr_DECODE_QP_INDEX(str, plane->num_hp_qps);
286
0
                else
287
0
                    qp_index_hp = MACROBLK_CUR_LP_QUANT(plane,0,tx,mx);
288
0
            }
289
0
            DEBUG(" HP_QP_INDEX for MBx=%d is %d\n", mx, qp_index_hp);
290
0
            for (ch = 0 ; ch < plane->num_channels ; ch += 1) {
291
0
                MACROBLK_CUR_HP_QUANT(plane,ch,tx,mx) = plane->hp_quant_ch[ch][qp_index_hp];
292
0
                DEBUG(" HP_QUANT for MBx=%d ch=%d is %d\n", mx, ch, MACROBLK_CUR_HP_QUANT(plane,ch,tx,mx));
293
0
            }
294
295
0
            rc = _jxr_r_MB_CBP(plane, str, 0, tx, ty, mx, my);
296
0
            if (rc < 0) {
297
0
                DEBUG("r_MB_CBP returned ERROR rc=%d\n", rc);
298
0
                return rc;
299
0
            }
300
0
            rc = _jxr_r_MB_HP(plane, str, 0, tx, ty, mx, my);
301
0
            if (rc < 0) {
302
0
                DEBUG("r_MB_HP returned ERROR rc=%d\n", rc);
303
0
                return rc;
304
0
            }
305
0
        }
306
0
        if (ALPHACHANNEL_FLAG(image))
307
0
            backup_hp_strip(image->alpha, tx, ty, my);
308
0
        backup_hp_strip(image, tx, ty, my);
309
0
    }
310
311
0
    _jxr_rbitstream_syncbyte(str);
312
0
    DEBUG("END TILE_HIGHPASS\n");
313
0
    return 0;
314
0
}
315
316
int _jxr_r_TILE_FLEXBITS(jxr_image_t image, struct rbitstream*str,
317
                         unsigned tx, unsigned ty)
318
0
{
319
0
    int mx, my;
320
0
    int plane_idx, num_planes;
321
0
    unsigned mb_height;
322
0
    unsigned mb_width;
323
0
    int use_num_channels;
324
0
    unsigned char s0, s1, s2, s3;
325
326
0
    DEBUG("START TILE_FLEXBITS at tile=[%u %u] bitpos=%zu\n", tx, ty, _jxr_rbitstream_bitpos(str));
327
328
    /* TILE_STARTCODE == 1 */
329
0
    s0 = _jxr_rbitstream_uint8(str); /* 0x00 */
330
0
    s1 = _jxr_rbitstream_uint8(str); /* 0x00 */
331
0
    s2 = _jxr_rbitstream_uint8(str); /* 0x01 */
332
0
    s3 = _jxr_rbitstream_uint8(str); /* reserved */
333
0
    DEBUG(" TILE_STARTCODE == %02x %02x %02x (reserved: %02x)\n", s0, s1, s2, s3);
334
0
    if (s0 != 0x00 || s1 != 0x00 || s2 != 0x01) {
335
0
        DEBUG(" TILE_FLEXBITS ERROR: Invalid marker.\n");
336
0
        return JXR_EC_ERROR; /* THOR: The specs say that this should be decoded nevertheless, though. */
337
0
    }
338
339
0
    image->trim_flexbits = 0;
340
0
    if (TRIM_FLEXBITS_FLAG(image)) {
341
0
        image->trim_flexbits =_jxr_rbitstream_uint4(str);
342
0
        DEBUG(" TRIM_FLEXBITS = %u\n", image->trim_flexbits);
343
0
    }
344
345
0
    use_num_channels = image->num_channels;
346
0
    if (image->use_clr_fmt == 1/*YUV420*/ || image->use_clr_fmt == 2/*YUV422*/)
347
0
        use_num_channels = 1;
348
349
    /* Now form and write out all the compressed data for the
350
    tile. This involves scanning the macroblocks, and the
351
    blocks within the macroblocks, generating bits as we go. */
352
353
0
    mb_height = EXTENDED_HEIGHT_BLOCKS(image);
354
0
    mb_width = EXTENDED_WIDTH_BLOCKS(image);
355
356
0
    if (TILING_FLAG(image)) {
357
0
        mb_height = image->tile_row_height[ty];
358
0
        mb_width = image->tile_column_width[tx];
359
0
    }
360
361
0
    num_planes = ((ALPHACHANNEL_FLAG(image)) ? 2 : 1);
362
0
    for (my = 0 ; my < (int) mb_height ; my += 1) {
363
0
        _jxr_r_rotate_mb_strip(image);
364
0
        if (ALPHACHANNEL_FLAG(image)) {
365
0
            image->alpha->cur_my = my;
366
0
            recover_dclphp_strip(image->alpha, tx, ty, my);
367
0
        }
368
0
        image->cur_my = my;
369
0
        recover_dclphp_strip(image, tx, ty, my);
370
371
0
        for (mx = 0 ; mx < (int) mb_width ; mx += 1)
372
0
        for (plane_idx = 0; plane_idx < num_planes; plane_idx ++) {
373
0
            jxr_image_t plane = (plane_idx == 0 ? image : image->alpha);
374
0
            int channels = (plane_idx == 0 ? use_num_channels : 1);
375
0
            int rc = _jxr_r_MB_FLEXBITS(plane, str, 0, tx, ty, mx, my);
376
0
            int mbhp_pred_mode;
377
0
            int idx;
378
0
            if (rc < 0) {
379
0
                DEBUG("r_MB_FLEXBITS returned ERROR rc=%d\n", rc);
380
0
                return rc;
381
0
            }
382
383
            /* Now the HP values are complete, so run the propagation
384
            process. This involves recovering some bits of data saved
385
            by the HP tile. */
386
0
            mbhp_pred_mode = MACROBLK_CUR(plane,0,tx,mx).mbhp_pred_mode;
387
0
            for (idx = 0 ; idx < channels ; idx += 1) {
388
0
                DEBUG(" MB_FLEXBITS: propagate HP predictions in MB_FLEXBITS\n");
389
0
                _jxr_propagate_hp_predictions(plane, idx, tx, mx, mbhp_pred_mode);
390
0
            }
391
0
        }
392
0
        if (ALPHACHANNEL_FLAG(image))
393
0
            backup_hp_strip(image->alpha, tx, ty, my);
394
0
        backup_hp_strip(image, tx, ty, my);
395
0
    }
396
397
0
    _jxr_rbitstream_syncbyte(str);
398
0
    DEBUG("END TILE_FLEXBITS bitpos=%zu\n", _jxr_rbitstream_bitpos(str));
399
0
    return 0;
400
0
}
401
402
/*
403
* This function handles the special case that the FLEXBITS tile is
404
* escaped away. Do all the soft processing that is otherwise needed.
405
*/
406
int _jxr_r_TILE_FLEXBITS_ESCAPE(jxr_image_t image, unsigned tx, unsigned ty)
407
0
{
408
0
    int use_num_channels = image->num_channels;
409
0
    unsigned mb_height = EXTENDED_HEIGHT_BLOCKS(image);
410
0
    unsigned mb_width = EXTENDED_WIDTH_BLOCKS(image);
411
0
    int mx, my;
412
413
0
    DEBUG("START TILE_FLEXBITS_ESCAPE at tile=[%u %u]\n", tx, ty);
414
415
0
    use_num_channels = image->num_channels;
416
0
    if (image->use_clr_fmt == 1/*YUV420*/ || image->use_clr_fmt == 2/*YUV422*/)
417
0
        use_num_channels = 1;
418
419
0
    mb_height = EXTENDED_HEIGHT_BLOCKS(image);
420
0
    mb_width = EXTENDED_WIDTH_BLOCKS(image);
421
422
0
    if (TILING_FLAG(image)) {
423
0
        mb_height = image->tile_row_height[ty];
424
0
        mb_width = image->tile_column_width[tx];
425
0
    }
426
427
0
    for (my = 0 ; my < (int) mb_height ; my += 1) {
428
0
        _jxr_r_rotate_mb_strip(image);
429
0
        image->cur_my = my;
430
0
        recover_dclphp_strip(image, tx, ty, my);
431
432
0
        for (mx = 0 ; mx < (int) mb_width ; mx += 1) {
433
            /* */
434
0
            int mbhp_pred_mode = MACROBLK_CUR(image,0,tx,mx).mbhp_pred_mode;
435
0
            int idx;
436
0
            for (idx = 0 ; idx < use_num_channels ; idx += 1) {
437
0
                DEBUG(" MB_FLEXBITS_ESCAPE: propagate HP predictions in MB_FLEXBITS\n");
438
0
                _jxr_propagate_hp_predictions(image, idx, tx, mx, mbhp_pred_mode);
439
0
            }
440
0
        }
441
0
        backup_hp_strip(image, tx, ty, my);
442
0
    }
443
444
0
    DEBUG("END TILE_FLEXBIT_ESCAPE\n");
445
0
    return 0;
446
0
}
447
448
static void backup_dc_strip(jxr_image_t image, int tx, int ty, int my)
449
0
{
450
0
    int mx;
451
0
    int use_my = my + image->tile_row_position[ty];
452
0
    int use_mx = image->tile_column_position[tx];
453
0
    int ptr = use_my*EXTENDED_WIDTH_BLOCKS(image) + use_mx;
454
455
0
    int ch;
456
0
    for (ch = 0 ; ch < image->num_channels ; ch += 1) {
457
0
        struct macroblock_s*mb = image->mb_row_buffer[ch] + ptr;
458
459
0
        for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
460
0
            mb[mx].data[0] = MACROBLK_CUR_DC(image,ch,tx,mx);
461
0
            DEBUG(" backup_dc_strip: tx=%d, ty=%d, mx=%d, my=%d, ch=%d, DC=0x%0x8\n",
462
0
                tx, ty, mx, my, ch, mb[mx].data[0]);
463
0
        }
464
0
    }
465
0
}
466
467
static void backup_dclp_strip(jxr_image_t image, int tx, int ty, int my)
468
0
{
469
0
    int mx;
470
0
    int use_my = my + image->tile_row_position[ty];
471
0
    int use_mx = image->tile_column_position[tx];
472
0
    int ptr = use_my*EXTENDED_WIDTH_BLOCKS(image) + use_mx;
473
474
475
0
    int format_scale = 15;
476
0
    int ch;
477
0
    if (image->use_clr_fmt == 2 /* YUV422 */) {
478
0
        format_scale = 7;
479
0
    } else if (image->use_clr_fmt == 1 /* YUV420 */) {
480
0
        format_scale = 3;
481
0
    }
482
483
0
    for (ch = 0 ; ch < image->num_channels ; ch += 1) {
484
0
        struct macroblock_s*mb = image->mb_row_buffer[ch] + ptr;
485
0
        int count = ch==0? 15 : format_scale;
486
487
0
        for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
488
0
            int idx;
489
0
            mb[mx].data[0] = MACROBLK_CUR_DC(image,ch,tx,mx);
490
0
            DEBUG(" backup_dclp_strip: tx=%d, ty=%d, mx=%d, my=%d, ch=%d, DC=0x%x, LP=",
491
0
                tx, ty, mx, my, ch, mb[mx].data[0]);
492
0
            for (idx = 0 ; idx < count ; idx += 1) {
493
0
                mb[mx].data[idx+1] = MACROBLK_CUR_LP(image,ch,tx,mx,idx);
494
0
                DEBUG(" 0x%x", mb[mx].data[idx+1]);
495
0
            }
496
0
            DEBUG("\n");
497
0
            mb[mx].lp_quant = MACROBLK_CUR_LP_QUANT(image,ch,tx,mx);
498
0
        }
499
0
    }
500
0
}
501
502
static void backup_hp_strip(jxr_image_t image, int tx, int ty, int my)
503
0
{
504
0
    int mx;
505
0
    int use_my = my + image->tile_row_position[ty];
506
0
    int use_mx = image->tile_column_position[tx];
507
0
    int ptr = use_my*EXTENDED_WIDTH_BLOCKS(image) + use_mx;
508
509
510
0
    int format_scale = 16;
511
0
    int ch;
512
0
    if (image->use_clr_fmt == 2 /* YUV422 */) {
513
0
        format_scale = 8;
514
0
    } else if (image->use_clr_fmt == 1 /* YUV420 */) {
515
0
        format_scale = 4;
516
0
    }
517
518
0
    for (ch = 0 ; ch < image->num_channels ; ch += 1) {
519
0
        struct macroblock_s*mb = image->mb_row_buffer[ch] + ptr;
520
0
        int count = ch==0? 16 : format_scale;
521
522
0
        if (ch == 0) {
523
            /* Backup also the hp_model_bits, which are
524
            stored only in the channel-0 blocks. */
525
0
            for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
526
0
                mb[mx].hp_model_bits[0] = MACROBLK_CUR(image,0,tx,mx).hp_model_bits[0];
527
0
                mb[mx].hp_model_bits[1] = MACROBLK_CUR(image,0,tx,mx).hp_model_bits[1];
528
0
                mb[mx].mbhp_pred_mode = MACROBLK_CUR(image,0,tx,mx).mbhp_pred_mode;
529
0
            }
530
0
        }
531
0
        for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
532
0
            int blk;
533
0
            mb[mx].data[0] = MACROBLK_CUR_DC(image,ch,tx,mx);
534
0
            DEBUG(" backup_hp_strip: tx=%d, ty=%d, mx=%d, my=%d, ch=%d\n",
535
0
                tx, ty, mx, my, ch);
536
0
            for (blk = 0 ; blk < count ; blk += 1) {
537
0
                int idx;
538
0
                for (idx = 0 ; idx < 15 ; idx += 1)
539
0
                    mb[mx].data[count+15*blk+idx] = MACROBLK_CUR_HP(image,ch,tx,mx,blk,idx);
540
0
            }
541
0
            mb[mx].hp_quant = MACROBLK_CUR_HP_QUANT(image,ch,tx,mx);
542
0
        }
543
0
    }
544
0
}
545
546
static void recover_dc_strip(jxr_image_t image, int tx, int ty, int my)
547
0
{
548
0
    int mx;
549
0
    int use_my = my + image->tile_row_position[ty];
550
0
    int use_mx = image->tile_column_position[tx];
551
0
    int ptr = use_my*EXTENDED_WIDTH_BLOCKS(image) + use_mx;
552
553
0
    int ch;
554
0
    for (ch = 0 ; ch < image->num_channels ; ch += 1) {
555
0
        struct macroblock_s*mb = image->mb_row_buffer[ch] + ptr;
556
557
0
        for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
558
0
            MACROBLK_CUR_DC(image,ch,tx,mx) = mb[mx].data[0];
559
0
            DEBUG(" recover_dc_strip: tx=%d, ty=%d, mx=%d, my=%d, ch=%d, DC=0x%0x8\n",
560
0
                tx, ty, mx, my, ch, mb[mx].data[0]);
561
0
        }
562
0
    }
563
0
}
564
565
static void recover_dclp_strip(jxr_image_t image, int tx, int ty, int my)
566
0
{
567
0
    int mx;
568
0
    int use_my = my + image->tile_row_position[ty];
569
0
    int use_mx = image->tile_column_position[tx];
570
0
    int ptr = use_my*EXTENDED_WIDTH_BLOCKS(image) + use_mx;
571
0
    int ch;
572
573
0
    int format_scale = 15;
574
0
    if (image->use_clr_fmt == 2 /* YUV422 */) {
575
0
        format_scale = 7;
576
0
    } else if (image->use_clr_fmt == 1 /* YUV420 */) {
577
0
        format_scale = 3;
578
0
    }
579
580
0
    for (ch = 0 ; ch < image->num_channels ; ch += 1) {
581
0
        struct macroblock_s*mb = image->mb_row_buffer[ch] + ptr;
582
0
        int count = ch==0? 15 : format_scale;
583
584
0
        for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
585
0
            int idx;
586
0
            MACROBLK_CUR_DC(image,ch,tx,mx) = mb[mx].data[0];
587
0
            DEBUG(" recover_dclp_strip: tx=%d, ty=%d, mx=%d, my=%d, ch=%d, DC=0x%0x8, LP=\n",
588
0
                tx, ty, mx, my, ch, mb[mx].data[0]);
589
0
            for (idx = 0 ; idx < count ; idx += 1) {
590
0
                MACROBLK_CUR_LP(image,ch,tx,mx,idx) = mb[mx].data[idx+1];
591
0
                DEBUG(" 0x%x", mb[mx].data[idx+1]);
592
0
            }
593
0
            DEBUG("\n");
594
0
            MACROBLK_CUR_LP_QUANT(image,ch,tx,mx) = mb[mx].lp_quant;
595
0
        }
596
0
    }
597
0
}
598
599
static void recover_dclphp_strip(jxr_image_t image, int tx, int ty, int my)
600
0
{
601
0
    int mx;
602
0
    int use_my = my + image->tile_row_position[ty];
603
0
    int use_mx = image->tile_column_position[tx];
604
0
    int ptr = use_my*EXTENDED_WIDTH_BLOCKS(image) + use_mx;
605
606
0
    int format_scale = 16;
607
0
    int ch;
608
0
    if (image->use_clr_fmt == 2 /* YUV422 */) {
609
0
        format_scale = 8;
610
0
    } else if (image->use_clr_fmt == 1 /* YUV420 */) {
611
0
        format_scale = 4;
612
0
    }
613
614
0
    for (ch = 0 ; ch < image->num_channels ; ch += 1) {
615
0
        struct macroblock_s*mb = image->mb_row_buffer[ch] + ptr;
616
0
        int count = ch==0? 16 : format_scale;
617
618
0
        if (ch == 0) {
619
            /* Recover also the hp_model_bits, which are
620
            stored only in the channel-0 blocks. */
621
0
            for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
622
0
                MACROBLK_CUR(image,0,tx,mx).hp_model_bits[0] = mb[mx].hp_model_bits[0];
623
0
                MACROBLK_CUR(image,0,tx,mx).hp_model_bits[1] = mb[mx].hp_model_bits[1];
624
0
                MACROBLK_CUR(image,0,tx,mx).mbhp_pred_mode = mb[mx].mbhp_pred_mode;
625
0
            }
626
0
        }
627
0
        for (mx = 0 ; mx < (int) image->tile_column_width[tx] ; mx += 1) {
628
0
            int blk;
629
0
            MACROBLK_CUR_DC(image,ch,tx,mx) = mb[mx].data[0];
630
0
            DEBUG(" recover_dclphp_strip: tx=%d, ty=%d, mx=%d, my=%d, ch=%d, DC=0x%0x8, LP=\n",
631
0
                tx, ty, mx, my, ch, mb[mx].data[0]);
632
0
            for (blk = 1 ; blk < count ; blk += 1) {
633
0
                MACROBLK_CUR_LP(image,ch,tx,mx,blk-1) = mb[mx].data[blk];
634
0
                DEBUG(" 0x%x", mb[mx].data[blk]);
635
0
            }
636
637
0
            for (blk = 0 ; blk < count ; blk += 1) {
638
0
                int idx;
639
0
                for (idx = 0 ; idx < 15 ; idx += 1) {
640
0
                    int data_ptr = count+15*blk+idx;
641
0
                    MACROBLK_CUR_HP(image,ch,tx,mx,blk,idx) = mb[mx].data[data_ptr];
642
0
                }
643
0
            }
644
0
            DEBUG("\n");
645
0
            MACROBLK_CUR_LP_QUANT(image,ch,tx,mx) = mb[mx].lp_quant;
646
0
            MACROBLK_CUR_HP_QUANT(image,ch,tx,mx) = mb[mx].hp_quant;
647
0
        }
648
0
    }
649
0
}
650
651
void _jxr_frequency_mode_render(jxr_image_t image)
652
0
{
653
654
0
    int ty;
655
0
    for (ty = 0 ; ty < (int) image->tile_rows ; ty += 1) {
656
0
        int my;
657
0
        for (my = 0 ; my < (int) image->tile_row_height[ty] ; my += 1) {
658
0
            int tx;
659
0
            if (ALPHACHANNEL_FLAG(image))
660
0
                _jxr_rflush_mb_strip(image->alpha, -1, -1, my + image->alpha->tile_row_position[ty]);
661
0
            _jxr_rflush_mb_strip(image, -1, -1, my + image->tile_row_position[ty]);
662
0
            for (tx = 0 ; tx < (int) image->tile_columns ; tx += 1) {
663
0
                if (ALPHACHANNEL_FLAG(image))
664
0
                    recover_dclphp_strip(image->alpha, tx, ty, my);
665
0
                recover_dclphp_strip(image, tx, ty, my);
666
0
            }
667
0
        }
668
0
    }
669
670
0
    if (ALPHACHANNEL_FLAG(image))
671
0
        _jxr_rflush_mb_strip(image->alpha, -1, -1, EXTENDED_HEIGHT_BLOCKS(image->alpha)+0);
672
0
    _jxr_rflush_mb_strip(image, -1, -1, EXTENDED_HEIGHT_BLOCKS(image)+0);
673
674
0
    if (ALPHACHANNEL_FLAG(image))
675
0
        _jxr_rflush_mb_strip(image->alpha, -1, -1, EXTENDED_HEIGHT_BLOCKS(image->alpha)+1);
676
0
    _jxr_rflush_mb_strip(image, -1, -1, EXTENDED_HEIGHT_BLOCKS(image)+1);
677
678
0
    if (ALPHACHANNEL_FLAG(image))
679
0
        _jxr_rflush_mb_strip(image->alpha, -1, -1, EXTENDED_HEIGHT_BLOCKS(image->alpha)+2);
680
0
    _jxr_rflush_mb_strip(image, -1, -1, EXTENDED_HEIGHT_BLOCKS(image)+2);
681
682
0
    if (ALPHACHANNEL_FLAG(image))
683
0
        _jxr_rflush_mb_strip(image->alpha, -1, -1, EXTENDED_HEIGHT_BLOCKS(image->alpha)+3);
684
0
    _jxr_rflush_mb_strip(image, -1, -1, EXTENDED_HEIGHT_BLOCKS(image)+3);
685
0
}
686
687
/*
688
** thor: Added April 2nd: Render only a single stripe in frequency mode,
689
** then return with an indicator whether this was the last one.
690
*/
691
int _jxr_frequency_mode_render_stripe(jxr_image_t image)
692
0
{
693
0
  int tx;
694
0
  int ty = image->stripe_ty;
695
0
  int my = image->stripe_my;
696
  /*
697
  image->stripe_ty
698
699
  int ty = image->
700
    for (ty = 0 ; ty < (int) image->tile_rows ; ty += 1) {
701
        int my;
702
        for (my = 0 ; my < (int) image->tile_row_height[ty] ; my += 1) {
703
  */
704
705
0
  switch(image->cleanup_state) {
706
0
  case 0:
707
0
    do {
708
0
      if (ALPHACHANNEL_FLAG(image))
709
0
        _jxr_rflush_mb_strip(image->alpha, -1, -1, my + image->alpha->tile_row_position[ty]);
710
0
      _jxr_rflush_mb_strip(image, -1, -1, my + image->tile_row_position[ty]);
711
712
0
      for (tx = 0 ; tx < (int) image->tile_columns ; tx += 1) {
713
0
        if (ALPHACHANNEL_FLAG(image))
714
0
          recover_dclphp_strip(image->alpha, tx, ty, my);
715
0
        recover_dclphp_strip(image, tx, ty, my);
716
0
      }
717
718
0
      my = ++image->stripe_my;
719
0
    } while (image->stripe_my < image->tile_row_height[ty] && image->output_sent == 0);
720
721
0
    if (image->stripe_my < image->tile_row_height[ty]) {
722
      /* Not yet done, continue with this tile. */
723
0
      image->output_sent = 0;
724
0
      return 0;
725
0
    }
726
727
0
    assert(image->stripe_my == image->tile_row_height[ty]);
728
729
0
    image->stripe_my = 0;
730
0
    image->stripe_ty++;
731
0
    if (image->stripe_ty < image->tile_rows && image->output_sent) {
732
      /* Not yet done, continue with the next tile */
733
0
      image->output_sent = 0;
734
0
      return 0;
735
0
    }
736
737
0
    if (image->stripe_ty == image->tile_rows)
738
0
      image->cleanup_state++;
739
740
0
    if (image->output_sent) {
741
0
      image->output_sent = 0;
742
0
      return 0;
743
0
    }
744
    // Runs into the following
745
0
  case 1:
746
0
    if (ALPHACHANNEL_FLAG(image))
747
0
        _jxr_rflush_mb_strip(image->alpha, -1, -1, EXTENDED_HEIGHT_BLOCKS(image->alpha)+0);
748
0
    _jxr_rflush_mb_strip(image, -1, -1, EXTENDED_HEIGHT_BLOCKS(image)+0);
749
0
    image->cleanup_state++;
750
0
    if (image->output_sent) {
751
0
      image->output_sent = 0;
752
0
      return 0;
753
0
    }
754
    // runs into the following
755
0
  case 2:
756
0
    if (ALPHACHANNEL_FLAG(image))
757
0
      _jxr_rflush_mb_strip(image->alpha, -1, -1, EXTENDED_HEIGHT_BLOCKS(image->alpha)+1);
758
0
    _jxr_rflush_mb_strip(image, -1, -1, EXTENDED_HEIGHT_BLOCKS(image)+1);
759
0
    image->cleanup_state++;
760
0
    if (image->output_sent) {
761
0
      image->output_sent = 0;
762
0
      return 0;
763
0
    }
764
    // runs into the following
765
0
  case 3:
766
0
    if (ALPHACHANNEL_FLAG(image))
767
0
      _jxr_rflush_mb_strip(image->alpha, -1, -1, EXTENDED_HEIGHT_BLOCKS(image->alpha)+2);
768
0
    _jxr_rflush_mb_strip(image, -1, -1, EXTENDED_HEIGHT_BLOCKS(image)+2);
769
0
    image->cleanup_state++;
770
0
    if (image->output_sent) {
771
0
      image->output_sent = 0;
772
0
      return 0;
773
0
    }
774
    // runs into the following
775
0
  case 4:
776
0
    if (ALPHACHANNEL_FLAG(image))
777
0
      _jxr_rflush_mb_strip(image->alpha, -1, -1, EXTENDED_HEIGHT_BLOCKS(image->alpha)+3);
778
0
    _jxr_rflush_mb_strip(image, -1, -1, EXTENDED_HEIGHT_BLOCKS(image)+3);
779
0
    image->cleanup_state++;
780
0
    if (image->output_sent) {
781
0
      image->output_sent = 0;
782
0
      return 0;
783
0
    }
784
    // runs into the following
785
0
  default:
786
0
    return JXR_EC_DONE;
787
0
  }
788
0
}
789
790
791
/*
792
* $Log: r_tile_frequency.c,v $
793
* Revision 1.9  2011-11-08 20:17:29  thor
794
* Merged a couple of fixes from the JNB.
795
*
796
* Revision 1.8  2011-04-28 08:45:43  thor
797
* Fixed compiler warnings, ported to gcc 4.4, removed obsolete files.
798
*
799
* Revision 1.7  2010-05-01 11:16:08  thor
800
* Fixed the tiff tag order. Added spatial/line mode.
801
*
802
* Revision 1.6  2010-03-31 07:50:59  thor
803
* Replaced by the latest MS version.
804
*
805
* Revision 1.16 2009/05/29 12:00:00 microsoft
806
* Reference Software v1.6 updates.
807
*
808
* Revision 1.15 2009/04/13 12:00:00 microsoft
809
* Reference Software v1.5 updates.
810
*
811
* Revision 1.14 2008/03/18 21:34:04 steve
812
* Fix distributed color prediction.
813
*
814
* Revision 1.13 2008/03/05 06:58:10 gus
815
* *** empty log message ***
816
*
817
* Revision 1.12 2008/02/26 23:52:44 steve
818
* Remove ident for MS compilers.
819
*
820
* Revision 1.11 2007/11/26 01:47:15 steve
821
* Add copyright notices per MS request.
822
*
823
* Revision 1.10 2007/11/21 00:34:30 steve
824
* Rework spatial mode tile macroblock shuffling.
825
*
826
* Revision 1.9 2007/11/20 00:05:47 steve
827
* Complex handling of mbhp_pred_mode in frequency dmoe.
828
*
829
* Revision 1.8 2007/11/16 21:33:48 steve
830
* Store MB Quant, not qp_index.
831
*
832
* Revision 1.7 2007/11/16 20:03:57 steve
833
* Store MB Quant, not qp_index.
834
*
835
* Revision 1.6 2007/11/16 17:33:24 steve
836
* Do HP prediction after FLEXBITS frequency tiles.
837
*
838
* Revision 1.5 2007/11/16 00:29:06 steve
839
* Support FREQUENCY mode HP and FLEXBITS
840
*
841
* Revision 1.4 2007/11/15 17:44:13 steve
842
* Frequency mode color support.
843
*
844
* Revision 1.3 2007/11/14 23:56:17 steve
845
* Fix TILE ordering, using seeks, for FREQUENCY mode.
846
*
847
* Revision 1.2 2007/11/13 03:27:23 steve
848
* Add Frequency mode LP support.
849
*
850
* Revision 1.1 2007/11/12 23:21:55 steve
851
* Infrastructure for frequency mode ordering.
852
*
853
*/
854