Coverage Report

Created: 2026-08-17 07:50

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/LibRaw/src/decoders/kodak_decoders.cpp
Line
Count
Source
1
/* -*- C++ -*-
2
 * Copyright 2019-2025 LibRaw LLC (info@libraw.org)
3
 *
4
 LibRaw uses code from dcraw.c -- Dave Coffin's raw photo decoder,
5
 dcraw.c is copyright 1997-2018 by Dave Coffin, dcoffin a cybercom o net.
6
 LibRaw do not use RESTRICTED code from dcraw.c
7
8
 LibRaw is free software; you can redistribute it and/or modify
9
 it under the terms of the one of two licenses as you choose:
10
11
1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
12
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
13
14
2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
15
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
16
17
 */
18
19
#include "../../internal/dcraw_defs.h"
20
21
0
#define radc_token(tree) ((signed char)getbithuff(8, huff + (tree) * 256))
22
23
#define FORYX                                                                  \
24
0
  for (y = 1; y < 3; y++)                                                      \
25
0
    for (x = col + 1; x >= col; x--)
26
27
#define PREDICTOR                                                              \
28
0
  (c ? (buf[c][y - 1][x] + buf[c][y][x + 1]) / 2                               \
29
0
     : (buf[c][y - 1][x + 1] + 2 * buf[c][y - 1][x] + buf[c][y][x + 1]) / 4)
30
31
#ifdef __GNUC__
32
#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
33
#pragma GCC optimize("no-aggressive-loop-optimizations")
34
#endif
35
#endif
36
37
void LibRaw::kodak_radc_load_raw()
38
0
{
39
  // All kodak radc images are 768x512
40
0
  if (width > 768 || raw_width > 768 || height > 512 || raw_height > 512)
41
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
42
0
  static const signed char src[] = {
43
0
      1, 1,   2, 3,   3, 4,   4, 2,   5, 7,   6, 5,   7, 6,   7, 8,   1, 0,
44
0
      2, 1,   3, 3,   4, 4,   5, 2,   6, 7,   7, 6,   8, 5,   8, 8,   2, 1,
45
0
      2, 3,   3, 0,   3, 2,   3, 4,   4, 6,   5, 5,   6, 7,   6, 8,   2, 0,
46
0
      2, 1,   2, 3,   3, 2,   4, 4,   5, 6,   6, 7,   7, 5,   7, 8,   2, 1,
47
0
      2, 4,   3, 0,   3, 2,   3, 3,   4, 7,   5, 5,   6, 6,   6, 8,   2, 3,
48
0
      3, 1,   3, 2,   3, 4,   3, 5,   3, 6,   4, 7,   5, 0,   5, 8,   2, 3,
49
0
      2, 6,   3, 0,   3, 1,   4, 4,   4, 5,   4, 7,   5, 2,   5, 8,   2, 4,
50
0
      2, 7,   3, 3,   3, 6,   4, 1,   4, 2,   4, 5,   5, 0,   5, 8,   2, 6,
51
0
      3, 1,   3, 3,   3, 5,   3, 7,   3, 8,   4, 0,   5, 2,   5, 4,   2, 0,
52
0
      2, 1,   3, 2,   3, 3,   4, 4,   4, 5,   5, 6,   5, 7,   4, 8,   1, 0,
53
0
      2, 2,   2, -2,  1, -3,  1, 3,   2, -17, 2, -5,  2, 5,   2, 17,  2, -7,
54
0
      2, 2,   2, 9,   2, 18,  2, -18, 2, -9,  2, -2,  2, 7,   2, -28, 2, 28,
55
0
      3, -49, 3, -9,  3, 9,   4, 49,  5, -79, 5, 79,  2, -1,  2, 13,  2, 26,
56
0
      3, 39,  4, -16, 5, 55,  6, -37, 6, 76,  2, -26, 2, -13, 2, 1,   3, -39,
57
0
      4, 16,  5, -55, 6, -76, 6, 37};
58
0
  std::vector<ushort> huff_buffer(19 * 256,0);
59
0
  ushort* huff = &huff_buffer[0];
60
0
  int row, col, tree, nreps, rep, step, i, c, s, r, x, y, val;
61
0
  short last[3] = {16, 16, 16}, mul[3], buf[3][3][386];
62
0
  static const ushort pt[] = {0,    0,    1280, 1344,  2320,  3616,
63
0
                              3328, 8000, 4095, 16383, 65535, 16383};
64
65
0
  for (i = 2; i < 12; i += 2)
66
0
    for (c = pt[i - 2]; c <= pt[i]; c++)
67
0
      curve[c] = ushort((float)(c - pt[i - 2]) / (pt[i] - pt[i - 2]) *
68
0
                     (pt[i + 1] - pt[i - 1]) +
69
0
                 pt[i - 1] + 0.5f);
70
0
  for (s = i = 0; i < int(sizeof src); i += 2)
71
0
    FORC(256 >> src[i])
72
0
  ((ushort *)huff)[s++] = src[i] << 8 | (uchar)src[i + 1];
73
0
  s = kodak_cbpp == 243 ? 2 : 3;
74
0
  FORC(256) huff[18 * 256 + c] = (8 - s) << 8 | c >> s << s | 1 << (s - 1);
75
0
  getbits(-1);
76
0
  for (i = 0; i < int(sizeof(buf) / sizeof(short)); i++)
77
0
    ((short *)buf)[i] = 2048;
78
0
  for (row = 0; row < height; row += 4)
79
0
  {
80
0
    checkCancel();
81
0
    FORC3 mul[c] = getbits(6);
82
0
    if (!mul[0] || !mul[1] || !mul[2])
83
0
      throw LIBRAW_EXCEPTION_IO_CORRUPT;
84
0
    FORC3
85
0
    {
86
0
      val = ((0x1000000 / last[c] + 0x7ff) >> 12) * mul[c];
87
0
      s = val > 65564 ? 10 : 12;
88
0
      x = ~((~0u) << (s - 1));
89
0
      val <<= 12 - s;
90
0
      for (i = 0; i < int(sizeof(buf[0]) / sizeof(short)); i++)
91
0
        ((short *)buf[c])[i] =
92
0
            short((MIN(0x7FFFFFFF, (((short *)buf[c])[i] * static_cast<long long>(val) + x)) >> s) & 0xffff);
93
0
      last[c] = mul[c];
94
0
      for (r = 0; r <= int(!c); r++)
95
0
      {
96
0
        buf[c][1][width / 2] = buf[c][2][width / 2] = mul[c] << 7;
97
0
        for (tree = 1, col = width / 2; col > 0;)
98
0
        {
99
0
          if ((tree = radc_token(tree)))
100
0
          {
101
0
            col -= 2;
102
0
            if (col >= 0)
103
0
            {
104
0
              if (tree == 8)
105
0
                FORYX buf[c][y][x] = (uchar)radc_token(18) * mul[c];
106
0
              else
107
0
                FORYX buf[c][y][x] = radc_token(tree + 10) * 16 + PREDICTOR;
108
0
            }
109
0
          }
110
0
          else
111
0
            do
112
0
            {
113
0
              nreps = (col > 2) ? radc_token(9) + 1 : 1;
114
0
              for (rep = 0; rep < 8 && rep < nreps && col > 0; rep++)
115
0
              {
116
0
                col -= 2;
117
0
                if (col >= 0)
118
0
                  FORYX buf[c][y][x] = PREDICTOR;
119
0
                if (rep & 1)
120
0
                {
121
0
                  step = radc_token(10) << 4;
122
0
                  FORYX buf[c][y][x] += step;
123
0
                }
124
0
              }
125
0
            } while (nreps == 9);
126
0
        }
127
0
        for (y = 0; y < 2; y++)
128
0
          for (x = 0; x < width / 2; x++)
129
0
          {
130
0
            val = (buf[c][y + 1][x] << 4) / mul[c];
131
0
            if (val < 0)
132
0
              val = 0;
133
0
            if (c)
134
0
              RAW(row + y * 2 + c - 1, x * 2 + 2 - c) = val;
135
0
            else
136
0
              RAW(row + r * 2 + y, x * 2 + y) = val;
137
0
          }
138
0
        memcpy(buf[c][0] + !c, buf[c][2], sizeof buf[c][0] - 2 * !c);
139
0
      }
140
0
    }
141
0
    for (y = row; y < row + 4; y++)
142
0
      for (x = 0; x < width; x++)
143
0
        if ((x + y) & 1)
144
0
        {
145
0
          r = x ? x - 1 : x + 1;
146
0
          s = x + 1 < width ? x + 1 : x - 1;
147
0
          val = (RAW(y, x) - 2048) * 2 + (RAW(y, r) + RAW(y, s)) / 2;
148
0
          if (val < 0)
149
0
            val = 0;
150
0
          RAW(y, x) = val;
151
0
        }
152
0
  }
153
0
  for (i = 0; i < height * width; i++)
154
0
    raw_image[i] = curve[raw_image[i]];
155
0
  maximum = 0x3fff;
156
0
}
157
158
#undef FORYX
159
#undef PREDICTOR
160
161
#ifdef NO_JPEG
162
0
void LibRaw::kodak_jpeg_load_raw() {}
163
#else
164
static void jpegErrorExit_k(j_common_ptr /*cinfo*/)
165
{
166
  throw LIBRAW_EXCEPTION_DECODE_JPEG;
167
}
168
169
// LibRaw's Kodak_jpeg_load_raw
170
void LibRaw::kodak_jpeg_load_raw()
171
{
172
  if (data_size < 1)
173
    throw LIBRAW_EXCEPTION_DECODE_JPEG;
174
175
  int row, col;
176
  struct jpeg_decompress_struct cinfo;
177
  struct jpeg_error_mgr pub;
178
  cinfo.err = jpeg_std_error(&pub);
179
  pub.error_exit = jpegErrorExit_k;
180
181
  if (INT64(data_size) >
182
          INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024))
183
    throw LIBRAW_EXCEPTION_TOOBIG;
184
185
  unsigned char *jpg_buf = (unsigned char *)calloc(data_size,1);
186
  std::vector<uchar> pixel_buf(width * 3, 0);
187
  jpeg_create_decompress(&cinfo);
188
189
  fread(jpg_buf, data_size, 1, ifp);
190
  libraw_swab(jpg_buf, int(data_size));
191
  try
192
  {
193
    jpeg_mem_src(&cinfo, jpg_buf, (unsigned long)data_size);
194
    int rc = jpeg_read_header(&cinfo, TRUE);
195
    if (rc != 1)
196
      throw LIBRAW_EXCEPTION_DECODE_JPEG;
197
198
    jpeg_start_decompress(&cinfo);
199
    if ((cinfo.output_width != width) || (cinfo.output_height * 2 != height) ||
200
        (cinfo.output_components != 3))
201
    {
202
      throw LIBRAW_EXCEPTION_DECODE_JPEG;
203
    }
204
205
    unsigned char *buf[1];
206
    buf[0] = pixel_buf.data();
207
208
    while (cinfo.output_scanline < cinfo.output_height)
209
    {
210
      checkCancel();
211
      row = cinfo.output_scanline * 2;
212
      jpeg_read_scanlines(&cinfo, buf, 1);
213
      unsigned char(*pixel)[3] = (unsigned char(*)[3])buf[0];
214
      for (col = 0; col < width; col += 2)
215
      {
216
        RAW(row + 0, col + 0) = pixel[col + 0][1] << 1;
217
        RAW(row + 1, col + 1) = pixel[col + 1][1] << 1;
218
        RAW(row + 0, col + 1) = pixel[col][0] + pixel[col + 1][0];
219
        RAW(row + 1, col + 0) = pixel[col][2] + pixel[col + 1][2];
220
      }
221
    }
222
  }
223
  catch (...)
224
  {
225
    jpeg_finish_decompress(&cinfo);
226
    jpeg_destroy_decompress(&cinfo);
227
    free(jpg_buf);
228
    throw;
229
  }
230
  jpeg_finish_decompress(&cinfo);
231
  jpeg_destroy_decompress(&cinfo);
232
  free(jpg_buf);
233
  maximum = 0xff << 1;
234
}
235
#endif
236
237
void LibRaw::kodak_dc120_load_raw()
238
0
{
239
0
  static const int mul[4] = {162, 192, 187, 92};
240
0
  static const int add[4] = {0, 636, 424, 212};
241
0
  uchar pixel[848];
242
0
  int row, shift, col;
243
244
0
  for (row = 0; row < height; row++)
245
0
  {
246
0
    checkCancel();
247
0
    if (fread(pixel, 1, 848, ifp) < 848)
248
0
      derror();
249
0
    shift = row * mul[row & 3] + add[row & 3];
250
0
    for (col = 0; col < width; col++)
251
0
      RAW(row, col) = (ushort)pixel[(col + shift) % 848];
252
0
  }
253
0
  maximum = 0xff;
254
0
}
255
void LibRaw::kodak_c330_load_raw()
256
0
{
257
0
  if (!image)
258
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
259
0
  int row, col, y, cb, cr, rgb[3], c;
260
261
0
  std::vector<uchar> pixel(raw_width*2 + 4);
262
263
0
  for (row = 0; row < height; row++)
264
0
  {
265
0
      checkCancel();
266
0
      if (fread(pixel.data(), raw_width, 2, ifp) < 2)
267
0
          derror();
268
0
      if (load_flags && (row & 31) == 31)
269
0
          fseek(ifp, raw_width * 32, SEEK_CUR);
270
0
      for (col = 0; col < width; col++)
271
0
      {
272
0
          y = pixel[col * 2];
273
0
          cb = pixel[(col * 2 & -4) | 1] - 128;
274
0
          cr = pixel[(col * 2 & -4) | 3] - 128;
275
0
          rgb[1] = y - ((cb + cr + 2) >> 2);
276
0
          rgb[2] = rgb[1] + cb;
277
0
          rgb[0] = rgb[1] + cr;
278
0
          FORC3 image[row * width + col][c] = curve[LIM(rgb[c], 0, 255)];
279
0
      }
280
0
  }
281
0
  maximum = curve[0xff];
282
0
}
283
284
void LibRaw::kodak_c603_load_raw()
285
0
{
286
0
  if (!image)
287
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
288
0
  int row, col, y, cb, cr, rgb[3], c;
289
290
0
  std::vector<uchar> pixel(raw_width * 3);
291
0
  for (row = 0; row < height; row++)
292
0
  {
293
0
      checkCancel();
294
0
      if (~row & 1)
295
0
          if (fread(pixel.data(), raw_width, 3, ifp) < 3)
296
0
              derror();
297
0
      for (col = 0; col < width; col++)
298
0
      {
299
0
          y = pixel[width * 2 * (row & 1) + col];
300
0
          cb = pixel[width + (col & -2)] - 128;
301
0
          cr = pixel[width + (col & -2) + 1] - 128;
302
0
          rgb[1] = y - ((cb + cr + 2) >> 2);
303
0
          rgb[2] = rgb[1] + cb;
304
0
          rgb[0] = rgb[1] + cr;
305
0
          FORC3 image[row * width + col][c] = curve[LIM(rgb[c], 0, 255)];
306
0
      }
307
0
  }
308
0
  maximum = curve[0xff];
309
0
}
310
311
void LibRaw::kodak_262_load_raw()
312
0
{
313
0
  static const uchar kodak_tree[2][26] = {
314
0
      {0, 1, 5, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0,
315
0
       0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9},
316
0
      {0, 3, 1, 1, 1, 1, 1, 2, 0, 0, 0, 0, 0,
317
0
       0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
318
0
  ushort *huff[2];
319
0
  int *strip, ns, c, row, col, chess, pi = 0, pi1, pi2, pred, val;
320
321
0
  FORC(2) huff[c] = make_decoder(kodak_tree[c]);
322
0
  ns = (raw_height + 63) >> 5;
323
0
  std::vector<uchar> pixel(raw_width * 32 + ns * 4);
324
0
  strip = (int *)(pixel.data() + raw_width * 32);
325
0
  order = 0x4d4d;
326
0
  FORC(ns) strip[c] = get4();
327
0
  try
328
0
  {
329
0
    for (row = 0; row < raw_height; row++)
330
0
    {
331
0
      checkCancel();
332
0
      if ((row & 31) == 0)
333
0
      {
334
0
        fseek(ifp, strip[row >> 5], SEEK_SET);
335
0
        getbits(-1);
336
0
        pi = 0;
337
0
      }
338
0
      for (col = 0; col < raw_width; col++)
339
0
      {
340
0
        chess = (row + col) & 1;
341
0
        pi1 = chess ? pi - 2 : pi - raw_width - 1;
342
0
        pi2 = chess ? pi - 2 * raw_width : pi - raw_width + 1;
343
0
        if (col <= chess)
344
0
          pi1 = -1;
345
0
        if (pi1 < 0)
346
0
          pi1 = pi2;
347
0
        if (pi2 < 0)
348
0
          pi2 = pi1;
349
0
        if (pi1 < 0 && col > 1)
350
0
          pi1 = pi2 = pi - 2;
351
0
        pred = (pi1 < 0) ? 0 : (pixel[pi1] + pixel[pi2]) >> 1;
352
0
        pixel[pi] = val = pred + ljpeg_diff(huff[chess]);
353
0
        if (val >> 8)
354
0
          derror();
355
0
        val = curve[pixel[pi++]];
356
0
        RAW(row, col) = val;
357
0
      }
358
0
    }
359
0
  }
360
0
  catch (...)
361
0
  {
362
0
      FORC(2) free(huff[c]);
363
0
      throw;
364
0
  }
365
0
  FORC(2) free(huff[c]);
366
0
}
367
368
int LibRaw::kodak_65000_decode(short *out, int bsize)
369
0
{
370
0
  uchar c, blen[768];
371
0
  ushort raw[6];
372
0
  INT64 bitbuf = 0;
373
0
  int bits = 0, i, j, len, diff;
374
0
  INT64 save;
375
376
0
  save = ftell(ifp);
377
0
  bsize = (bsize + 3) & -4;
378
0
  for (i = 0; i < bsize; i += 2)
379
0
  {
380
0
    c = fgetc(ifp);
381
0
    if ((blen[i] = c & 15) > 12 || (blen[i + 1] = c >> 4) > 12)
382
0
    {
383
0
      fseek(ifp, save, SEEK_SET);
384
0
      for (i = 0; i < bsize; i += 8)
385
0
      {
386
0
        read_shorts(raw, 6);
387
0
        out[i] = raw[0] >> 12 << 8 | raw[2] >> 12 << 4 | raw[4] >> 12;
388
0
        out[i + 1] = raw[1] >> 12 << 8 | raw[3] >> 12 << 4 | raw[5] >> 12;
389
0
        for (j = 0; j < 6; j++)
390
0
          out[i + 2 + j] = raw[j] & 0xfff;
391
0
      }
392
0
      return 1;
393
0
    }
394
0
  }
395
0
  if ((bsize & 7) == 4)
396
0
  {
397
0
    bitbuf = fgetc(ifp) << 8;
398
0
    bitbuf += fgetc(ifp);
399
0
    bits = 16;
400
0
  }
401
0
  for (i = 0; i < bsize; i++)
402
0
  {
403
0
    len = blen[i];
404
0
    if (bits < len)
405
0
    {
406
0
      for (j = 0; j < 32; j += 8)
407
0
        bitbuf += (INT64)fgetc(ifp) << (bits + (j ^ 8));
408
0
      bits += 32;
409
0
    }
410
0
    diff = bitbuf & (0xffff >> (16 - len));
411
0
    bitbuf >>= len;
412
0
    bits -= len;
413
0
    if (len > 0 && (diff & (1 << (len - 1))) == 0)
414
0
      diff -= (1 << len) - 1;
415
0
    out[i] = diff;
416
0
  }
417
0
  return 0;
418
0
}
419
420
void LibRaw::kodak_65000_load_raw()
421
0
{
422
0
  short buf[272]; /* 264 looks enough */
423
0
  int row, col, len, pred[2], ret, i;
424
425
0
  for (row = 0; row < height; row++)
426
0
  {
427
0
    checkCancel();
428
0
    for (col = 0; col < width; col += 256)
429
0
    {
430
0
      pred[0] = pred[1] = 0;
431
0
      len = MIN(256, width - col);
432
0
      ret = kodak_65000_decode(buf, len);
433
0
      for (i = 0; i < len; i++)
434
0
      {
435
0
        int idx = ret ? buf[i] : (pred[i & 1] += buf[i]);
436
0
        if (idx >= 0 && idx < 0xffff)
437
0
        {
438
0
          if ((RAW(row, col + i) = curve[idx]) >> 12)
439
0
            derror();
440
0
        }
441
0
        else
442
0
          derror();
443
0
      }
444
0
    }
445
0
  }
446
0
}
447
448
void LibRaw::kodak_ycbcr_load_raw()
449
0
{
450
0
  if (!image)
451
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
452
0
  short buf[384], *bp;
453
0
  int row, col, len, c, i, j, k, y[2][2], cb, cr, rgb[3];
454
0
  ushort *ip;
455
456
0
  unsigned int bits =
457
0
      (load_flags && load_flags > 9 && load_flags < 17) ? load_flags : 10;
458
0
  const int pixels = int(width)*int(height);
459
0
  for (row = 0; row < height; row += 2)
460
0
  {
461
0
    checkCancel();
462
0
    for (col = 0; col < width; col += 128)
463
0
    {
464
0
      len = MIN(128, width - col);
465
0
      kodak_65000_decode(buf, len * 3);
466
0
      y[0][1] = y[1][1] = cb = cr = 0;
467
0
      for (bp = buf, i = 0; i < len; i += 2, bp += 2)
468
0
      {
469
0
        cb += bp[4];
470
0
        cr += bp[5];
471
0
        rgb[1] = -((cb + cr + 2) >> 2);
472
0
        rgb[2] = rgb[1] + cb;
473
0
        rgb[0] = rgb[1] + cr;
474
0
        for (j = 0; j < 2; j++)
475
0
          for (k = 0; k < 2; k++)
476
0
          {
477
0
            if ((y[j][k] = y[j][k ^ 1] + *bp++) >> bits)
478
0
              derror();
479
0
            int indx = (row + j) * width + col + i + k;
480
0
            if(indx>=0 && indx < pixels)
481
0
            {
482
0
                ip = image[indx];
483
0
                FORC3 ip[c] = curve[LIM(y[j][k] + rgb[c], 0, 0xfff)];
484
0
            }
485
0
          }
486
0
      }
487
0
    }
488
0
  }
489
0
}
490
491
void LibRaw::kodak_rgb_load_raw()
492
0
{
493
0
  if (!image)
494
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
495
0
  short buf[768], *bp;
496
0
  int row, col, len, c, i, rgb[3], ret;
497
0
  ushort *ip = image[0];
498
499
0
  for (row = 0; row < height; row++)
500
0
  {
501
0
    checkCancel();
502
0
    for (col = 0; col < width; col += 256)
503
0
    {
504
0
      len = MIN(256, width - col);
505
0
      ret = kodak_65000_decode(buf, len * 3);
506
0
      memset(rgb, 0, sizeof rgb);
507
0
      for (bp = buf, i = 0; i < len; i++, ip += 4)
508
0
        if (load_flags == 12)
509
0
          FORC3 ip[c] = ret ? (*bp++) : (rgb[c] += *bp++);
510
0
        else
511
0
          FORC3 if ((ip[c] = ret ? (*bp++) : (rgb[c] += *bp++)) >> 12) derror();
512
0
    }
513
0
  }
514
0
}
515
516
void LibRaw::kodak_thumb_load_raw()
517
0
{
518
0
  if (!image)
519
0
    throw LIBRAW_EXCEPTION_IO_CORRUPT;
520
0
  int row, col;
521
0
  colors = thumb_misc >> 5;
522
0
  for (row = 0; row < height; row++)
523
0
    for (col = 0; col < width; col++)
524
0
      read_shorts(image[row * width + col], colors);
525
0
  maximum = (1 << (thumb_misc & 31)) - 1;
526
0
}