Coverage Report

Created: 2026-04-09 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/jpegxr/api.c
Line
Count
Source
1
2
/*************************************************************************
3
*
4
* This software module was originally contributed by Microsoft
5
* Corporation in the course of development of the
6
* ITU-T T.832 | ISO/IEC 29199-2 ("JPEG XR") format standard for
7
* reference purposes and its performance may not have been optimized.
8
*
9
* This software module is an implementation of one or more
10
* tools as specified by the JPEG XR standard.
11
*
12
* ITU/ISO/IEC give You a royalty-free, worldwide, non-exclusive
13
* copyright license to copy, distribute, and make derivative works
14
* of this software module or modifications thereof for use in
15
* products claiming conformance to the JPEG XR standard as
16
* specified by ITU-T T.832 | ISO/IEC 29199-2.
17
*
18
* ITU/ISO/IEC give users the same free license to this software
19
* module or modifications thereof for research purposes and further
20
* ITU/ISO/IEC standardization.
21
*
22
* Those intending to use this software module in products are advised
23
* that its use may infringe existing patents. ITU/ISO/IEC have no
24
* liability for use of this software module or modifications thereof.
25
*
26
* Copyright is not released for products that do not conform to
27
* to the JPEG XR standard as specified by ITU-T T.832 |
28
* ISO/IEC 29199-2.
29
*
30
******** Section to be removed when the standard is published ************
31
*
32
* Assurance that the contributed software module can be used
33
* (1) in the ITU-T "T.JXR" | ISO/IEC 29199 ("JPEG XR") standard once the
34
* standard has been adopted; and
35
* (2) to develop the JPEG XR standard:
36
*
37
* Microsoft Corporation and any subsequent contributors to the development
38
* of this software grant ITU/ISO/IEC all rights necessary to include
39
* the originally developed software module or modifications thereof in the
40
* JPEG XR standard and to permit ITU/ISO/IEC to offer such a royalty-free,
41
* worldwide, non-exclusive copyright license to copy, distribute, and make
42
* derivative works of this software module or modifications thereof for
43
* use in products claiming conformance to the JPEG XR standard as
44
* specified by ITU-T T.832 | ISO/IEC 29199-2, and to the extent that
45
* such originally developed software module or portions of it are included
46
* in an ITU/ISO/IEC standard. To the extent that the original contributors
47
* may own patent rights that would be required to make, use, or sell the
48
* originally developed software module or portions thereof included in the
49
* ITU/ISO/IEC standard in a conforming product, the contributors will
50
* assure ITU/ISO/IEC that they are willing to negotiate licenses under
51
* reasonable and non-discriminatory terms and conditions with
52
* applicants throughout the world and in accordance with their patent
53
* rights declarations made to ITU/ISO/IEC (if any).
54
*
55
* Microsoft, any subsequent contributors, and ITU/ISO/IEC additionally
56
* gives You a free license to this software module or modifications
57
* thereof for the sole purpose of developing the JPEG XR standard.
58
*
59
******** end of section to be removed when the standard is published *****
60
*
61
* Microsoft Corporation retains full right to modify and use the code
62
* for its own purpose, to assign or donate the code to a third party,
63
* and to inhibit third parties from using the code for products that
64
* do not conform to the JPEG XR standard as specified by ITU-T T.832 |
65
* ISO/IEC 29199-2.
66
*
67
* This copyright notice must be included in all copies or derivative
68
* works.
69
*
70
* Copyright (c) ITU-T/ISO/IEC 2008, 2009.
71
***********************************************************************/
72
73
#ifdef _MSC_VER
74
#pragma comment (user,"$Id: api.c,v 1.19 2012-05-17 12:42:57 thor Exp $")
75
#endif
76
77
# include "jxr_priv.h"
78
# include <assert.h>
79
# include <stdlib.h>
80
# include <string.h>
81
82
void _jxr_send_mb_to_output(jxr_image_t image, int mx, int my, int*data)
83
0
{
84
0
    if (image->out_fun)
85
0
        image->out_fun(image, mx, my, data);
86
0
}
87
88
void jxr_set_block_output(jxr_image_t image, block_fun_t fun)
89
0
{
90
0
    image->out_fun = fun;
91
0
}
92
93
void _jxr_get_mb_from_input(jxr_image_t image, int mx, int my, int*data)
94
0
{
95
0
    if (image->inp_fun)
96
0
        image->inp_fun(image, mx, my, data);
97
0
}
98
99
void jxr_set_block_input(jxr_image_t image, block_fun_t fun)
100
0
{
101
0
    image->inp_fun = fun;
102
0
}
103
104
void jxr_set_user_data(jxr_image_t image, void*data)
105
0
{
106
0
    image->user_data = data;
107
0
}
108
109
void* jxr_get_user_data(jxr_image_t image)
110
0
{
111
0
    return image->user_data;
112
0
}
113
114
/* WARNING: This call returns the number of channels in the codestream,
115
** which is *likely* not the information you care about. Instead, the
116
** number of components is defined through the pixel format in the
117
** container.
118
*/
119
int jxr_get_IMAGE_CHANNELS(jxr_image_t image)
120
0
{
121
0
    return image->num_channels;
122
0
}
123
124
/* While the above returns the number of channels encoded in the codestream,
125
** the following returns the nominal number of channels indicated in the
126
** component. Note that this might be different because Y-Only is enabled
127
** and thus everything but the first channel is missing. Bummer!
128
*/
129
int jxrc_get_CONTAINER_CHANNELS(jxr_container_t container)
130
0
{
131
0
  if (container->table == NULL) {
132
0
    return container->channels;
133
0
  } else {
134
0
    int pxfmt = _jxrc_image_pixelformat(container,0);
135
0
    memcpy(container->pixel_format,jxr_guids[pxfmt],16);
136
0
    return _jxrc_PixelFormatToChannels(container);
137
0
  }
138
0
}
139
140
/*
141
** Check whether the container format includes an alpha channel
142
** flag. This alpha channel can be either realized as separate or as
143
** interleaved alpha channel. This call returns 0 for no alpha channel,
144
** 1 for the regular alpha channel or 2 for the premultiplied case.
145
*/
146
int jxrc_get_CONTAINER_ALPHA_FLAG(jxr_container_t container)
147
0
{
148
0
  if (container->table == NULL) {
149
0
    return container->alpha;
150
0
  } else {
151
0
    int pxfmt = _jxrc_image_pixelformat(container,0);
152
0
    memcpy(container->pixel_format,jxr_guids[pxfmt],16);
153
0
    if (_jxrc_is_alpha_pxfmt(container))
154
0
      return 1;
155
0
    if (_jxrc_is_pre_alpha_pxfmt(container))
156
0
      return 2;
157
0
    return 0;
158
0
  }
159
0
}
160
161
/*
162
** Return 1 if the samples are integers
163
*/
164
int jxrc_integer_samples(jxr_container_t container)
165
0
{
166
0
  if (container->table == NULL) {
167
0
    if ((container->pixeltype >> 12) == 0)
168
0
      return 1;
169
0
    return 0;
170
0
  } else {
171
0
    int pxfmt = _jxrc_image_pixelformat(container,0);
172
0
    memcpy(container->pixel_format,jxr_guids[pxfmt],16);
173
0
    if ((_jxrc_get_boxed_pixel_format(container) >> 12) == 0)
174
0
      return 1;
175
0
    return 0;
176
0
  }
177
0
}
178
179
/*
180
** Return 1 if the samples are fixpoint
181
*/
182
int jxrc_fixpoint_samples(jxr_container_t container)
183
0
{
184
0
  if (container->table == NULL) {
185
0
    if ((container->pixeltype >> 12) == 3)
186
0
      return 1;
187
0
    return 0;
188
0
  } else {
189
0
    int pxfmt = _jxrc_image_pixelformat(container,0);
190
0
    memcpy(container->pixel_format,jxr_guids[pxfmt],16);
191
0
    if ((_jxrc_get_boxed_pixel_format(container) >> 12) == 3)
192
0
      return 1;
193
0
    return 0;
194
0
  }
195
0
}
196
197
/*
198
** Return 1 if the samples are floating point
199
*/
200
int jxrc_float_samples(jxr_container_t container)
201
0
{
202
0
  if (container->table == NULL) {
203
0
    if ((container->pixeltype >> 12) == 3)
204
0
      return 1;
205
0
    return 0;
206
0
  } else {
207
0
    int pxfmt = _jxrc_image_pixelformat(container,0);
208
0
    memcpy(container->pixel_format,jxr_guids[pxfmt],16);
209
0
    if ((_jxrc_get_boxed_pixel_format(container) >> 12) == 3)
210
0
      return 1;
211
0
    return 0;
212
0
  }
213
0
}
214
215
/*
216
** Return 1 if the samples are exponent/mantissa separated, i.e. RGBE
217
*/
218
int jxrc_exponent_mantissa_samples(jxr_container_t container)
219
0
{
220
0
  if (container->table == NULL) {
221
0
    if ((container->pixeltype >> 12) == 1)
222
0
      return 1;
223
0
    return 0;
224
0
  } else {
225
0
    int pxfmt = _jxrc_image_pixelformat(container,0);
226
0
    memcpy(container->pixel_format,jxr_guids[pxfmt],16);
227
0
    if ((_jxrc_get_boxed_pixel_format(container) >> 12) == 1)
228
0
      return 1;
229
0
    return 0;
230
0
  }
231
0
}
232
233
/*
234
** Return the number of bits per channel. Return 6 for the 565 mode.
235
*/
236
int jxrc_bits_per_channel(jxr_container_t container)
237
0
{
238
0
  if (container->table == NULL) {
239
0
    return container->bpp;
240
0
  } else {
241
0
    int pxfmt = _jxrc_image_pixelformat(container,0);
242
0
    memcpy(container->pixel_format,jxr_guids[pxfmt],16);
243
0
    return _jxrc_PixelFormatToBpp(container);
244
0
  }
245
0
}
246
247
/*
248
** Return the number of color channels available in total, not including alpha channels
249
*/
250
int jxrc_color_channels(jxr_container_t container)
251
0
{
252
0
 if (container->table == NULL) {
253
0
   return container->channels - (container->alpha)?(1):(0);
254
0
 } else {
255
0
    int pxfmt = _jxrc_image_pixelformat(container,0);
256
0
    int channels;
257
0
    memcpy(container->pixel_format,jxr_guids[pxfmt],16);
258
0
    channels = _jxrc_PixelFormatToChannels(container);
259
0
    if (_jxrc_is_pre_alpha_pxfmt(container) || _jxrc_is_alpha_pxfmt(container))
260
0
      channels--;
261
0
    return channels;
262
0
 }
263
0
}
264
/*
265
** return a TIFF photometric interpretation indicator:
266
** WhiteIsZero 0
267
** BlackIsZero 1
268
** RGB 2
269
** RGB Palette 3 (not used)
270
** Transparency mask 4
271
** CMYK 5
272
** YCbCr 6
273
** CIELab 8
274
*/
275
int jxrc_photometric_interpretation(jxr_container_t container)
276
0
{
277
0
  int color;
278
279
0
  if (container->table == NULL) {
280
0
    color = container->color;
281
0
  } else {
282
0
    int pxfmt = _jxrc_image_pixelformat(container,0);
283
0
    memcpy(container->pixel_format,jxr_guids[pxfmt],16);
284
0
    color  = _jxrc_enumerated_colorspace(container);
285
0
  }
286
0
  switch(color) {
287
0
  case 25:
288
0
  case 16: /* RGB-type */
289
0
    return 2;
290
0
  case 15:
291
0
  case 17:
292
0
  case 0: /* both bi-level types are mapped into one, the framework must figure this out. Yuck! */
293
0
    return 0;
294
0
  case 3:
295
0
    return 6; /* YCbCr */
296
0
  case 12:
297
0
    return 5; /* CMYK */
298
0
  }
299
0
  return -1; /* Undefined */
300
0
}
301
302
/* Returns true in case it is suggested to place the blue channel at the lower memory location -
303
** note that this is only an output suggestion a decoder might or might not respect. Typically,
304
** a decoder will, of course, place the color channel where the hardware requires it and not
305
** where the file indicates it.
306
*/
307
int jxrc_blue_first(jxr_container_t container)
308
0
{
309
0
  if (container->table == NULL) {
310
0
    return 0; /* is not kept in the file format, and makes actually no sense in first place.... */
311
0
  } else {
312
0
    switch(_jxrc_image_pixelformat(container,0)) {
313
0
    case JXRC_FMT_24bppBGR:
314
0
    case JXRC_FMT_32bppBGR:
315
0
    case JXRC_FMT_32bppBGRA:
316
0
    case JXRC_FMT_32bppPBGRA:
317
0
      return 1;
318
0
    default:
319
0
      return 0;
320
0
    }
321
0
  }
322
0
}
323
324
/* Padding information in the container, returns 1 if a padding channel is indicated */
325
int jxrc_includes_padding_channel(jxr_container_t container)
326
0
{
327
0
  if (container->table == NULL) {
328
0
    return 0; /* is not kept in the container, and need not to be so. */
329
0
  } else {
330
0
    switch(_jxrc_image_pixelformat(container,0)) {
331
0
    case JXRC_FMT_128bppRGBFloat:
332
0
    case JXRC_FMT_128bppRGBFixedPoint:
333
0
    case JXRC_FMT_64bppRGBFixedPoint:
334
0
    case JXRC_FMT_64bppRGBHalf:
335
0
    case JXRC_FMT_32bppBGR:
336
0
      return 1;
337
0
    default:
338
0
      return 0;
339
0
    }
340
0
  }
341
0
}
342
343
void jxr_set_INTERNAL_CLR_FMT(jxr_image_t image, jxr_color_fmt_t fmt, int channels, int alpha_channels)
344
0
{
345
0
  switch (fmt) {
346
0
  case JXR_YONLY:
347
0
    image->use_clr_fmt  = fmt;
348
0
    image->num_channels = 1;
349
0
    break;
350
0
  case JXR_YUV420:
351
0
  case JXR_YUV422:
352
0
  case JXR_YUV444:
353
0
    image->use_clr_fmt = fmt;
354
0
    image->num_channels = 3;
355
0
    break;
356
0
  case JXR_YUVK:
357
0
    image->use_clr_fmt = fmt;
358
0
    image->num_channels = 4;
359
0
    break;
360
0
  case JXR_OCF_NCOMPONENT:
361
0
    image->use_clr_fmt = fmt;
362
0
    image->num_channels = channels;
363
0
    break;
364
0
  default:
365
0
    image->use_clr_fmt = fmt;
366
0
    image->num_channels = channels;
367
0
    break;
368
0
  }
369
0
  image->container_nc = channels + alpha_channels;
370
0
}
371
372
void jxr_set_CHROMA_CENTERING(jxr_image_t image,unsigned x,unsigned y)
373
0
{
374
0
  image->chroma_centering_x = x;
375
0
  image->chroma_centering_y = y;
376
0
}
377
378
/*
379
** Interchange red and blue in the color transform for the
380
** BD555,BD565 and BD101010 flag.
381
** NOTE: This is only for legacy implementations. All new
382
** implementations should follow the specs and handle the
383
** data correctly.
384
**
385
** The problem happens because HDPhoto defined the blue to be
386
** in the MSBs of the packed formats, whereas the standard DIB
387
** formats expect blue in the MSB. If you just feed in data
388
** blindly without noting the difference, you get incorrect
389
** images that just appear correctly because the same mistake
390
** is made at the decoder side.
391
** The latest version of the specs do account for such errors
392
** and allows this, which is then indicated by a flag.
393
** This call modifies the encoding appropriately to address the
394
** needs of legacy decoders.
395
**
396
** You should actually *not* use this flag but rather write your
397
** applications be aware of the correct color ordering and the
398
** corresponding flag.
399
*/
400
void jxr_set_R_B_swapped(jxr_image_t image,int bgr_flag)
401
0
{
402
0
  if (SOURCE_CLR_FMT(image) == JXR_OCF_RGB &&
403
0
      ((image->header_flags_fmt & 0x0f) == JXR_BD5   ||
404
0
       (image->header_flags_fmt & 0x0f) == JXR_BD10  ||
405
0
       (image->header_flags_fmt & 0x0f) == JXR_BD565)
406
0
      ) {
407
0
    if (bgr_flag == 0) {
408
0
      image->header_flags2 |= 0x04;
409
0
    } else {
410
0
      image->header_flags2 &= ~0x04;
411
0
    }
412
0
  } else if (bgr_flag) {
413
0
    fprintf(stderr,"R-B interchange is only available for 555,565 and 101010 pixel formats.\n");
414
0
  }
415
0
}
416
417
void jxr_set_OUTPUT_CLR_FMT(jxr_image_t image, jxr_output_clr_fmt_t fmt)
418
0
{
419
0
    image->output_clr_fmt = fmt;
420
421
0
    switch (fmt) {
422
0
    case JXR_OCF_YONLY: /* YONLY */
423
0
      image->header_flags_fmt |= 0x00; /* OUTPUT_CLR_FMT==0 */
424
0
      break;
425
0
    case JXR_OCF_YUV420: /* YUV420 */
426
0
      image->header_flags_fmt |= 0x10; /* OUTPUT_CLR_FMT==1 */
427
0
      break;
428
0
    case JXR_OCF_YUV422: /* YUV422 */
429
0
      image->header_flags_fmt |= 0x20; /* OUTPUT_CLR_FMT==2 */
430
0
      break;
431
0
    case JXR_OCF_YUV444: /* YUV444 */
432
0
      image->header_flags_fmt |= 0x30; /* OUTPUT_CLR_FMT==3 */
433
0
      break;
434
0
    case JXR_OCF_CMYK: /* CMYK */
435
0
      image->header_flags_fmt |= 0x40; /* OUTPUT_CLR_FMT=4 (CMYK) */
436
0
      break;
437
0
    case JXR_OCF_CMYKDIRECT: /* CMYKDIRECT */
438
0
      image->header_flags_fmt |= 0x50; /* OUTPUT_CLR_FMT=5 (CMYKDIRECT) */
439
0
      break;
440
0
    case JXR_OCF_RGB: /* RGB color */
441
0
      image->header_flags_fmt |= 0x70; /* OUTPUT_CLR_FMT=7 (RGB) */
442
0
      break;
443
0
    case JXR_OCF_RGBE: /* RGBE color */
444
0
      image->header_flags_fmt |= 0x80; /* OUTPUT_CLR_FMT=8 (RGBE) */
445
0
      break;
446
0
    case JXR_OCF_NCOMPONENT: /* N-channel color */
447
0
      image->header_flags_fmt |= 0x60; /* OUTPUT_CLR_FMT=6 (NCOMPONENT) */
448
0
      break;
449
0
    default:
450
0
      fprintf(stderr, "Unsupported external color format (%d)! \n", fmt);
451
0
      break;
452
0
    }
453
0
}
454
455
jxr_output_clr_fmt_t jxr_get_OUTPUT_CLR_FMT(jxr_image_t image)
456
0
{
457
0
    return SOURCE_CLR_FMT(image); // JNB fix, was: image->output_clr_fmt;
458
0
}
459
460
461
jxr_bitdepth_t jxr_get_OUTPUT_BITDEPTH(jxr_image_t image)
462
0
{
463
0
    return (jxr_bitdepth_t) SOURCE_BITDEPTH(image);
464
0
}
465
466
void jxr_set_OUTPUT_BITDEPTH(jxr_image_t image, jxr_bitdepth_t bd)
467
0
{
468
0
    image->header_flags_fmt &= ~0x0f;
469
0
    image->header_flags_fmt |= bd;
470
0
}
471
472
void jxr_set_BANDS_PRESENT(jxr_image_t image, jxr_bands_present_t bp)
473
0
{
474
0
    image->bands_present = bp;
475
0
    image->bands_present_of_primary = image->bands_present;
476
0
}
477
478
void jxr_set_FREQUENCY_MODE_CODESTREAM_FLAG(jxr_image_t image, int flag)
479
0
{
480
0
    assert(flag >= 0 && flag <= 1);
481
0
    image->header_flags1 &= ~0x40;
482
0
    image->header_flags1 |= (flag << 6);
483
484
    /* Enable INDEX_TABLE_PRESENT_FLAG */
485
0
    if (flag) {
486
0
        jxr_set_INDEX_TABLE_PRESENT_FLAG(image, 1);
487
0
    }
488
0
}
489
490
void jxr_set_INDEX_TABLE_PRESENT_FLAG(jxr_image_t image, int flag)
491
0
{
492
0
    assert(flag >= 0 && flag <= 1);
493
0
    image->header_flags1 &= ~0x04;
494
0
    image->header_flags1 |= (flag << 2);
495
0
}
496
497
void jxr_set_PROFILE_IDC(jxr_image_t image, int profile_idc)
498
0
{
499
0
    assert(profile_idc >= 0 && profile_idc <= 255);
500
0
    image->profile_idc = (uint8_t) profile_idc;
501
0
}
502
503
void jxr_set_LEVEL_IDC(jxr_image_t image, int level_idc)
504
0
{
505
0
    assert(level_idc >= 0 && level_idc <= 255);
506
0
    image->level_idc = (uint8_t) level_idc;
507
0
}
508
509
void jxr_set_LONG_WORD_FLAG(jxr_image_t image, int flag)
510
0
{
511
0
    assert(flag >= 0 && flag <= 1);
512
0
    image->header_flags2 &= ~0x40;
513
0
    image->header_flags2 |= (flag << 6);
514
0
}
515
516
int jxr_test_PROFILE_IDC(jxr_image_t image, int flag)
517
0
{
518
    /*
519
    ** flag = 0 - encoder
520
    ** flag = 1 - decoder
521
    */
522
0
    jxr_bitdepth_t obd = jxr_get_OUTPUT_BITDEPTH(image);
523
0
    jxr_output_clr_fmt_t ocf = jxr_get_OUTPUT_CLR_FMT(image);
524
525
0
    unsigned char profile = image->profile_idc;
526
    /*
527
    * For forward compatability
528
    * Though only specified profiles are currently applicable, decoder shouldn't reject other profiles.
529
    */
530
0
    if (flag) {
531
0
        if (profile <= 44)
532
0
            profile = 44;
533
0
        else if (profile <= 55)
534
0
            profile = 55;
535
0
        else if (profile <= 66)
536
0
            profile = 66;
537
0
        else if (profile <= 111)
538
0
            profile = 111;
539
0
    }
540
541
0
    switch (profile) {
542
0
        case 44:
543
0
            if (OVERLAP_INFO(image) >= 2)
544
0
                return JXR_EC_BADFORMAT;
545
0
            if (LONG_WORD_FLAG(image))
546
0
                return JXR_EC_BADFORMAT;
547
0
            if (image->num_channels != 1 && image->num_channels != 3)
548
0
                return JXR_EC_BADFORMAT;
549
0
            if (image->alpha)
550
0
                return JXR_EC_BADFORMAT;
551
0
            if ((obd == JXR_BD16) || (obd == JXR_BD16S) || (obd == JXR_BD16F) || (obd == JXR_BD32S) || (obd == JXR_BD32F))
552
0
                return JXR_EC_BADFORMAT;
553
0
            if ((ocf != JXR_OCF_RGB) && (ocf != JXR_OCF_YONLY))
554
0
                return JXR_EC_BADFORMAT;
555
0
            break;
556
0
        case 55:
557
0
            if (image->num_channels != 1 && image->num_channels != 3)
558
0
                return JXR_EC_BADFORMAT;
559
0
            if (image->alpha)
560
0
                return JXR_EC_BADFORMAT;
561
0
            if ((obd == JXR_BD16F) || (obd == JXR_BD32S) || (obd == JXR_BD32F))
562
0
                return JXR_EC_BADFORMAT;
563
0
            if ((ocf != JXR_OCF_RGB) && (ocf != JXR_OCF_YONLY))
564
0
                return JXR_EC_BADFORMAT;
565
0
            break;
566
0
        case 66:
567
0
            if ((ocf == JXR_OCF_CMYKDIRECT) || (ocf == JXR_OCF_YUV420) || (ocf == JXR_OCF_YUV422) || (ocf == JXR_OCF_YUV444))
568
0
                return JXR_EC_BADFORMAT;
569
0
            break;
570
0
        case 111:
571
0
            break;
572
0
        default:
573
0
            return JXR_EC_BADFORMAT;
574
0
            break;
575
0
    }
576
577
0
    return JXR_EC_OK;
578
0
}
579
580
int jxr_test_LEVEL_IDC(jxr_image_t image, int flag)
581
0
{
582
    /*
583
    ** flag = 0 - encoder
584
    ** flag = 1 - decoder
585
    */
586
0
    unsigned tr = image->tile_rows - 1;
587
0
    unsigned tc = image->tile_columns - 1;
588
0
    uint64_t h = (uint64_t) image->extended_height - 1;
589
0
    uint64_t w = (uint64_t) image->extended_width - 1;
590
0
    uint64_t n = (uint64_t) image->num_channels;
591
0
    uint64_t buf_size = 1;
592
593
0
    unsigned i;
594
0
    uint64_t max_tile_width = 0, max_tile_height = 0;
595
0
    unsigned *tdim;
596
0
    unsigned char level;
597
598
0
    tdim = (image->tile_column_width)?(image->tile_column_width):(image->tile_column_width_input);
599
600
0
    if (tdim) {
601
0
      for (i = 0; i < image->tile_columns; i++)
602
0
        max_tile_width = (uint64_t) (tdim[i] > max_tile_width ? tdim[i] : max_tile_width);
603
0
    } else {
604
0
      max_tile_width = image->extended_width >> 4;
605
0
    }
606
607
0
    tdim = (image->tile_row_height)?(image->tile_row_height):(image->tile_row_height_input);
608
609
0
    if (tdim) {
610
0
      for (i = 0; i < image->tile_rows; i++)
611
0
        max_tile_height = (uint64_t) (tdim[i] > max_tile_height ? tdim[i] : max_tile_height);
612
0
    } else {
613
0
      max_tile_height = image->extended_height >> 4;
614
0
    }
615
616
    /* JNB fix: convert the tile size to a pixel size */
617
0
    max_tile_width  *= 16;
618
0
    max_tile_height *= 16;
619
620
0
    if (image->alpha)
621
0
        n += 1;
622
623
0
    switch (SOURCE_BITDEPTH(image)) {
624
0
        case 1: /* BD8 */
625
0
            buf_size = n * (h + 1) * (w + 1);
626
0
            break;
627
0
        case 2: /* BD16 */
628
0
        case 3: /* BD16S */
629
0
        case 4: /* BD16F */
630
0
            buf_size = 2 * n * (h + 1) * (w + 1);
631
0
            break;
632
0
        case 6: /* BD32S */
633
0
        case 7: /* BD32F */
634
0
            buf_size = 4 * n * (h + 1) * (w + 1);
635
0
            break;
636
0
        case 0: /* BD1WHITE1 */
637
0
        case 15: /* BD1BLACK1 */
638
0
            buf_size = ((h + 8) >> 3) * ((w + 8) >> 3) * 8;
639
0
            break;
640
0
        case 8: /* BD5 */
641
0
        case 10: /* BD565 */
642
0
            buf_size = 2 * (h + 1) * (w + 1);
643
0
            break;
644
0
        case 9: /* BD10 */
645
0
            if (image->output_clr_fmt == JXR_OCF_RGB)
646
0
                buf_size = 4 * (h + 1) * (w + 1);
647
0
            else
648
0
                buf_size = 2 * n * (h + 1) * (w + 1);
649
0
            break;
650
0
        default: /* RESERVED */
651
0
            return JXR_EC_BADFORMAT;
652
0
            break;
653
0
    }
654
655
0
    level = image->level_idc;
656
    /*
657
    * For forward compatability
658
    * Though only specified levels are currently applicable, decoder shouldn't reject other levels.
659
    */
660
0
    if (flag) {
661
      /* JNB fix: level adjustment was wrong - adjust to the next higher level. */
662
0
      if (level <= 4)
663
0
        level = 4;
664
0
      else if (level <= 8)
665
0
        level = 8;
666
0
      else if (level <= 16)
667
0
        level = 16;
668
0
      else if (level <= 32)
669
0
        level = 32;
670
0
      else if (level <= 64)
671
0
        level = 64;
672
0
      else if (level <= 128)
673
0
        level = 128;
674
0
      else
675
0
        level = 255;
676
0
    }
677
678
0
    switch (level) {
679
0
        case 4:
680
0
            if ((w >> 10) || (h >> 10) || (tc >> 4) || (tr >> 4) || (max_tile_width >> 10) || (max_tile_height >> 10) || (buf_size >> 22))
681
0
                return JXR_EC_BADFORMAT;
682
0
            break;
683
0
        case 8:
684
0
            if ((w >> 11) || (h >> 11) || (tc >> 5) || (tr >> 5) || (max_tile_width >> 11) || (max_tile_height >> 11) || (buf_size >> 24))
685
0
                return JXR_EC_BADFORMAT;
686
0
            break;
687
0
        case 16:
688
0
            if ((w >> 12) || (h >> 12) || (tc >> 6) || (tr >> 6) || (max_tile_width >> 12) || (max_tile_height >> 12) || (buf_size >> 26))
689
0
                return JXR_EC_BADFORMAT;
690
0
            break;
691
0
        case 32:
692
0
            if ((w >> 13) || (h >> 13) || (tc >> 7) || (tr >> 7) || (max_tile_width >> 12) || (max_tile_height >> 12) || (buf_size >> 28))
693
0
                return JXR_EC_BADFORMAT;
694
0
            break;
695
0
        case 64:
696
0
            if ((w >> 14) || (h >> 14) || (tc >> 8) || (tr >> 8) || (max_tile_width >> 12) || (max_tile_height >> 12) || (buf_size >> 30))
697
0
                return JXR_EC_BADFORMAT;
698
0
            break;
699
0
        case 128:
700
0
            if ((w >> 16) || (h >> 16) || (tc >> 10) || (tr >> 10) || (max_tile_width >> 12) || (max_tile_height >> 12) || (buf_size >> 32))
701
0
                return JXR_EC_BADFORMAT;
702
0
            break;
703
0
        case 255: /* width and height restriction is 2^32 */
704
0
            if ((w >> 32) || (h >> 32) || (tc >> 12) || (tr >> 12) || (max_tile_width >> 32) || (max_tile_height >> 32))
705
0
                return JXR_EC_BADFORMAT;
706
0
            break;
707
0
        default:
708
0
            return JXR_EC_BADFORMAT;
709
0
            break;
710
0
    }
711
712
0
    return JXR_EC_OK;
713
0
}
714
715
void jxr_set_NUM_VER_TILES_MINUS1(jxr_image_t image, unsigned num)
716
0
{
717
0
    assert( num > 0 && num < 4097 );
718
0
    image->tile_columns = num;
719
720
0
    if (num > 1)
721
0
        jxr_set_TILING_FLAG(image, 1);
722
0
}
723
724
void jxr_set_TILE_WIDTH_IN_MB(jxr_image_t image, unsigned* list)
725
0
{
726
0
  if (list == 0 || list[0] == 0) {
727
0
    unsigned idx, total_width = 0;
728
0
    image->tile_column_width = (unsigned *)jxr_calloc(image->alloc, 2*image->tile_columns, sizeof(unsigned));
729
    /* FIXME: Called in this mode, we do not check the results of the allocation. GS does not use this. */
730
0
    image->tile_column_position = image->tile_column_width + image->tile_columns;
731
0
    for ( idx = 0 ; idx < image->tile_columns - 1 ; idx++ ) {
732
0
      image->tile_column_width[idx] = (image->extended_width >> 4) / image->tile_columns;
733
0
      image->tile_column_position[idx] = total_width;
734
0
      total_width += image->tile_column_width[idx];
735
0
    }
736
0
    image->tile_column_width[image->tile_columns - 1] = (image->extended_width >> 4) - total_width;
737
0
    image->tile_column_position[image->tile_columns - 1] = total_width;
738
0
  } else {
739
0
    image->tile_column_width_input = list;
740
0
    image->tile_column_width       = NULL;
741
0
    image->tile_column_position    = NULL;
742
0
  }
743
0
}
744
745
void jxr_set_NUM_HOR_TILES_MINUS1(jxr_image_t image, unsigned num)
746
0
{
747
0
    assert( num > 0 && num < 4097 );
748
0
    image->tile_rows = num;
749
750
0
    if (num > 1)
751
0
        jxr_set_TILING_FLAG(image, 1);
752
0
}
753
754
void jxr_set_TILE_HEIGHT_IN_MB(jxr_image_t image, unsigned* list)
755
0
{
756
0
  if (list == 0 || list[0] == 0) {
757
0
    unsigned idx, total_height = 0;
758
0
    image->tile_row_height     = (unsigned *)jxr_calloc(image->alloc, 2*image->tile_rows, sizeof(unsigned));
759
    /* FIXME: Called in this mode, we do not check the results of the allocation. GS does not use this. */
760
0
    image->tile_row_position   = image->tile_row_height + image->tile_rows;
761
762
0
    total_height = 0;
763
0
    for ( idx = 0 ; idx < image->tile_rows - 1 ; idx++ ) {
764
0
      image->tile_row_height[idx] = (image->extended_height >> 4) / image->tile_rows;
765
0
      image->tile_row_position[idx] = total_height;
766
0
      total_height += image->tile_row_height[idx];
767
0
    }
768
0
    image->tile_row_height[image->tile_rows - 1] = (image->extended_height >> 4) - total_height;
769
0
    image->tile_row_position[image->tile_rows - 1] = total_height;
770
0
  } else {
771
0
    image->tile_row_height_input = list;
772
0
    image->tile_row_height       = NULL;
773
0
    image->tile_row_position     = NULL;
774
0
  }
775
0
}
776
777
void jxr_set_TILING_FLAG(jxr_image_t image, int flag)
778
0
{
779
0
    assert(flag >= 0 && flag <= 1);
780
0
    image->header_flags1 &= ~0x80;
781
0
    image->header_flags1 |= (flag << 7);
782
783
    /* Enable INDEX_TABLE_PRESENT_FLAG */
784
0
    if (flag) {
785
0
        jxr_set_INDEX_TABLE_PRESENT_FLAG(image, 1);
786
0
    }
787
0
}
788
789
void jxr_set_TRIM_FLEXBITS(jxr_image_t image, int trim_flexbits)
790
0
{
791
0
    assert(trim_flexbits >= 0 && trim_flexbits < 16);
792
0
    image->trim_flexbits = trim_flexbits;
793
0
}
794
795
void jxr_set_OVERLAP_FILTER(jxr_image_t image, int flag)
796
0
{
797
0
    assert(flag >= 0 && flag <= 3);
798
0
    image->header_flags1 &= ~0x03;
799
0
    image->header_flags1 |= flag&0x03;
800
0
}
801
802
void jxr_set_DISABLE_TILE_OVERLAP(jxr_image_t image, int disable_tile_overlap)
803
0
{
804
0
    image->disableTileOverlapFlag = disable_tile_overlap;
805
0
}
806
807
void jxr_set_QP_LOSSLESS(jxr_image_t image)
808
0
{
809
0
    unsigned char q[MAX_CHANNELS];
810
0
    int idx;
811
0
    for (idx = 0 ; idx < MAX_CHANNELS ; idx += 1)
812
0
        q[idx] = 0;
813
814
0
    jxr_set_QP_INDEPENDENT(image, q);
815
816
0
    if (image->num_channels == 1) {
817
0
        image->dc_component_mode = JXR_CM_UNIFORM;
818
0
        image->lp_component_mode = JXR_CM_UNIFORM;
819
0
        image->hp_component_mode = JXR_CM_UNIFORM;
820
0
    } else if (image->num_channels == 3) {
821
0
        image->dc_component_mode = JXR_CM_SEPARATE;
822
0
        image->lp_component_mode = JXR_CM_SEPARATE;
823
0
        image->hp_component_mode = JXR_CM_SEPARATE;
824
0
    }
825
0
}
826
827
void jxr_set_QP_INDEPENDENT(jxr_image_t image, unsigned char*quant_per_channel)
828
0
{
829
    /*
830
    * SCALED_FLAG MUST be set false if lossless compressing.
831
    * SCALED_FLAG SHOULD be true otherwise.
832
    *
833
    * So assume that we are setting up for lossless compression
834
    * until we find a QP flag that indicates otherwlse. If that
835
    * happens, turn SCALED_FLAG on.
836
    */
837
0
    int idx;
838
839
0
    image->scaled_flag = 0;
840
841
0
    if (image->bands_present != JXR_BP_ALL)
842
0
        image->scaled_flag = 1;
843
844
0
    if (image->num_channels == 1) {
845
0
        image->dc_component_mode = JXR_CM_UNIFORM;
846
0
        image->lp_component_mode = JXR_CM_UNIFORM;
847
0
        image->hp_component_mode = JXR_CM_UNIFORM;
848
0
    } else {
849
0
        image->dc_component_mode = JXR_CM_INDEPENDENT;
850
0
        image->lp_component_mode = JXR_CM_INDEPENDENT;
851
0
        image->hp_component_mode = JXR_CM_INDEPENDENT;
852
0
    }
853
854
0
    image->dc_frame_uniform = 1;
855
0
    image->lp_frame_uniform = 1;
856
0
    image->hp_frame_uniform = 1;
857
0
    image->lp_use_dc_qp = 0;
858
0
    image->hp_use_lp_qp = 0;
859
860
0
    image->num_lp_qps = 1;
861
0
    image->num_hp_qps = 1;
862
863
0
    for (idx = 0 ; idx < image->num_channels ; idx += 1) {
864
0
        if (quant_per_channel[idx] >= 1)
865
0
            image->scaled_flag = 1;
866
867
0
        image->dc_quant_ch[idx] = quant_per_channel[idx];
868
0
        image->lp_quant_ch[idx][0] = quant_per_channel[idx];
869
0
        image->hp_quant_ch[idx][0] = quant_per_channel[idx];
870
0
    }
871
0
}
872
873
void jxr_set_QP_UNIFORM(jxr_image_t image, unsigned char quant)
874
0
{
875
0
    int idx;
876
877
0
    image->scaled_flag = 0;
878
879
0
    image->dc_component_mode = JXR_CM_UNIFORM;
880
0
    image->lp_component_mode = JXR_CM_UNIFORM;
881
0
    image->hp_component_mode = JXR_CM_UNIFORM;
882
883
0
    image->dc_frame_uniform = 1;
884
0
    image->lp_frame_uniform = 1;
885
0
    image->hp_frame_uniform = 1;
886
0
    image->lp_use_dc_qp = 0;
887
0
    image->hp_use_lp_qp = 0;
888
889
0
    image->num_lp_qps = 1;
890
0
    image->num_hp_qps = 1;
891
892
0
    if (quant >= 1)
893
0
        image->scaled_flag = 1;
894
0
    if (image->bands_present != JXR_BP_ALL)
895
0
        image->scaled_flag = 1;
896
897
0
    for (idx = 0 ; idx < image->num_channels ; idx += 1) {
898
0
        image->dc_quant_ch[idx] = quant;
899
0
        image->lp_quant_ch[idx][0] = quant;
900
0
        image->hp_quant_ch[idx][0] = quant;
901
0
    }
902
0
}
903
904
void jxr_set_QP_SEPARATE(jxr_image_t image, unsigned char*quant_per_channel)
905
0
{
906
    /*
907
    * SCALED_FLAG MUST be set false if lossless compressing.
908
    * SCALED_FLAG SHOULD be true otherwise.
909
    *
910
    * So assume that we are setting up for lossless compression
911
    * until we find a QP flag that indicates otherwlse. If that
912
    * happens, turn SCALED_FLAG on.
913
    */
914
0
    int ch;
915
916
0
    image->scaled_flag = 0;
917
918
0
    if (image->bands_present != JXR_BP_ALL)
919
0
        image->scaled_flag = 1;
920
921
    /* XXXX Only thought out how to handle 1 channel. */
922
0
    assert(image->num_channels >= 3);
923
924
0
    image->dc_component_mode = JXR_CM_SEPARATE;
925
0
    image->lp_component_mode = JXR_CM_SEPARATE;
926
0
    image->hp_component_mode = JXR_CM_SEPARATE;
927
928
0
    image->dc_frame_uniform = 1;
929
0
    image->lp_frame_uniform = 1;
930
0
    image->hp_frame_uniform = 1;
931
0
    image->lp_use_dc_qp = 0;
932
0
    image->hp_use_lp_qp = 0;
933
934
0
    if (quant_per_channel[0] >= 1)
935
0
        image->scaled_flag = 1;
936
937
0
    image->dc_quant_ch[0] = quant_per_channel[0];
938
0
    image->lp_quant_ch[0][0] = quant_per_channel[0];
939
0
    image->hp_quant_ch[0][0] = quant_per_channel[0];
940
941
0
    if (quant_per_channel[1] >= 1)
942
0
        image->scaled_flag = 1;
943
944
0
    for (ch = 1 ; ch < image->num_channels ; ch += 1) {
945
0
        image->dc_quant_ch[ch] = quant_per_channel[1];
946
0
        image->lp_quant_ch[ch][0] = quant_per_channel[1];
947
0
        image->hp_quant_ch[ch][0] = quant_per_channel[1];
948
0
    }
949
0
}
950
951
void jxr_set_QP_DISTRIBUTED(jxr_image_t image, struct jxr_tile_qp*qp)
952
0
{
953
0
    image->dc_frame_uniform = 0;
954
0
    image->lp_frame_uniform = 0;
955
0
    image->hp_frame_uniform = 0;
956
0
    image->lp_use_dc_qp = 0;
957
0
    image->hp_use_lp_qp = 0;
958
959
0
    image->tile_quant = qp;
960
0
}
961
962
void jxr_set_SHIFT_BITS(jxr_image_t image, unsigned char shift_bits)
963
0
{
964
0
    image->shift_bits = shift_bits;
965
0
}
966
967
void jxr_set_FLOAT(jxr_image_t image, unsigned char len_mantissa, char exp_bias)
968
0
{
969
0
    image->len_mantissa = len_mantissa;
970
0
    image->exp_bias = exp_bias;
971
0
}
972
973
/*
974
* $Log: api.c,v $
975
* Revision 1.19  2012-05-17 12:42:57  thor
976
* Bumped to 1.41, fixed PNM writer, extended the API a bit.
977
*
978
* Revision 1.18  2012-03-19 15:48:19  thor
979
* Fixed YOnly and the container_nc field of the image to contain always
980
* the correct number of container components including the alpha channel.
981
*
982
* Revision 1.17  2012-03-18 21:47:07  thor
983
* Fixed double adjustments of window parameters. Fixed handling of
984
* N-channel coding in tiff.
985
*
986
* Revision 1.16  2012-02-16 16:36:25  thor
987
* Heavily reworked, but not yet tested.
988
*
989
* Revision 1.15  2011-11-24 11:44:09  thor
990
* Added an R-B swap flag.
991
*
992
* Revision 1.14  2011-11-11 17:13:50  thor
993
* Fixed a memory bug, fixed padding channel on encoding bug.
994
* Fixed window sizes (again).
995
*
996
* Revision 1.13  2011-11-08 20:17:29  thor
997
* Merged a couple of fixes from the JNB.
998
*
999
* Revision 1.12  2011-04-28 08:45:42  thor
1000
* Fixed compiler warnings, ported to gcc 4.4, removed obsolete files.
1001
*
1002
* Revision 1.11  2011-03-04 12:12:12  thor
1003
* Bumped to 1.16. Fixed RGB-YOnly handling, including the handling of
1004
* YOnly for which a new -f flag has been added.
1005
*
1006
* Revision 1.10  2011-02-26 10:24:39  thor
1007
* Fixed bugs for alpha and separate alpha.
1008
*
1009
* Revision 1.9  2010-06-19 11:48:35  thor
1010
* Fixed memory leaks.
1011
*
1012
* Revision 1.8  2010-05-13 16:30:03  thor
1013
* Added options to set the chroma centering. Fixed writing of BGR565.
1014
* Made the "-p" output option nicer.
1015
*
1016
* Revision 1.7  2010-03-31 07:50:58  thor
1017
* Replaced by the latest MS version.
1018
*
1019
* Revision 1.20 2009/05/29 12:00:00 microsoft
1020
* Reference Software v1.6 updates.
1021
*
1022
* Revision 1.19 2009/04/13 12:00:00 microsoft
1023
* Reference Software v1.5 updates.
1024
*
1025
* Revision 1.18 2008/03/21 18:05:53 steve
1026
* Proper CMYK formatting on input.
1027
*
1028
* Revision 1.17 2008/03/06 02:05:48 steve
1029
* Distributed quantization
1030
*
1031
* Revision 1.16 2008/03/05 04:04:30 steve
1032
* Clarify constraints on USE_DC_QP in image plane header.
1033
*
1034
* Revision 1.15 2008/03/05 01:27:15 steve
1035
* QP_UNIFORM may use USE_DC_LP optionally.
1036
*
1037
* Revision 1.14 2008/03/05 00:31:17 steve
1038
* Handle UNIFORM/IMAGEPLANE_UNIFORM compression.
1039
*
1040
* Revision 1.13 2008/03/04 23:01:28 steve
1041
* Cleanup QP API in preparation for distributed QP
1042
*
1043
* Revision 1.12 2008/03/02 19:56:27 steve
1044
* Infrastructure to read write BD16 files.
1045
*
1046
* Revision 1.11 2008/02/26 23:52:44 steve
1047
* Remove ident for MS compilers.
1048
*
1049
* Revision 1.10 2008/02/01 22:49:52 steve
1050
* Handle compress of YUV444 color DCONLY
1051
*
1052
* Revision 1.9 2008/01/08 01:06:20 steve
1053
* Add first pass overlap filtering.
1054
*
1055
* Revision 1.8 2008/01/07 16:19:10 steve
1056
* Properly configure TRIM_FLEXBITS_FLAG bit.
1057
*
1058
* Revision 1.7 2008/01/06 01:29:28 steve
1059
* Add support for TRIM_FLEXBITS in compression.
1060
*
1061
* Revision 1.6 2008/01/04 17:07:35 steve
1062
* API interface for setting QP values.
1063
*
1064
* Revision 1.5 2007/11/30 01:50:58 steve
1065
* Compression of DCONLY GRAY.
1066
*
1067
* Revision 1.4 2007/11/26 01:47:15 steve
1068
* Add copyright notices per MS request.
1069
*
1070
* Revision 1.3 2007/11/08 02:52:32 steve
1071
* Some progress in some encoding infrastructure.
1072
*
1073
* Revision 1.2 2007/09/08 01:01:43 steve
1074
* YUV444 color parses properly.
1075
*
1076
* Revision 1.1 2007/06/06 17:19:12 steve
1077
* Introduce to CVS.
1078
*
1079
*/
1080