Coverage Report

Created: 2026-10-28 08:05

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