File indexing completed on 2025-01-05 03:56:53
0001 /* -*- C++ -*- 0002 * File: libraw_fuji_compressed.cpp 0003 * Copyright (C) 2016-2019 Alexey Danilchenko 0004 * 0005 * Adopted to LibRaw by Alex Tutubalin, lexa@lexa.ru 0006 * LibRaw Fujifilm/compressed decoder 0007 0008 LibRaw is free software; you can redistribute it and/or modify 0009 it under the terms of the one of two licenses as you choose: 0010 0011 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 0012 (See file LICENSE.LGPL provided in LibRaw distribution archive for details). 0013 0014 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 0015 (See file LICENSE.CDDL provided in LibRaw distribution archive for details). 0016 0017 */ 0018 0019 #include "../../internal/libraw_cxx_defs.h" 0020 0021 #ifdef _abs 0022 #undef _abs 0023 #undef _min 0024 #undef _max 0025 #endif 0026 #define _abs(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31)) 0027 #define _min(a, b) ((a) < (b) ? (a) : (b)) 0028 #define _max(a, b) ((a) > (b) ? (a) : (b)) 0029 0030 struct int_pair 0031 { 0032 int value1; 0033 int value2; 0034 }; 0035 0036 enum _xt_lines 0037 { 0038 _R0 = 0, 0039 _R1, 0040 _R2, 0041 _R3, 0042 _R4, 0043 _G0, 0044 _G1, 0045 _G2, 0046 _G3, 0047 _G4, 0048 _G5, 0049 _G6, 0050 _G7, 0051 _B0, 0052 _B1, 0053 _B2, 0054 _B3, 0055 _B4, 0056 _ltotal 0057 }; 0058 0059 // tables of gradients for single sample level 0060 struct fuji_grads 0061 { 0062 int_pair grads[41]; 0063 int_pair lossy_grads[3][5]; 0064 }; 0065 0066 struct fuji_compressed_block 0067 { 0068 int cur_bit; // current bit being read (from left to right) 0069 int cur_pos; // current position in a buffer 0070 INT64 cur_buf_offset; // offset of this buffer in a file 0071 unsigned max_read_size; // Amount of data to be read 0072 int cur_buf_size; // buffer size 0073 uchar *cur_buf; // currently read block 0074 int fillbytes; // Counter to add extra byte for block size N*16 0075 LibRaw_abstract_datastream *input; 0076 fuji_grads even[3]; // tables of even gradients 0077 fuji_grads odd[3]; // tables of odd gradients 0078 ushort *linealloc; 0079 ushort *linebuf[_ltotal]; 0080 }; 0081 0082 static inline int log2ceil(int val) 0083 { 0084 int result = 0; 0085 if (val--) 0086 do 0087 ++result; 0088 while (val >>= 1); 0089 0090 return result; 0091 } 0092 0093 void setup_qlut(int8_t *qt, int *q_point) 0094 { 0095 for (int curVal = -q_point[4]; curVal <= q_point[4]; ++qt, ++curVal) 0096 { 0097 if (curVal <= -q_point[3]) 0098 *qt = -4; 0099 else if (curVal <= -q_point[2]) 0100 *qt = -3; 0101 else if (curVal <= -q_point[1]) 0102 *qt = -2; 0103 else if (curVal < -q_point[0]) 0104 *qt = -1; 0105 else if (curVal <= q_point[0]) 0106 *qt = 0; 0107 else if (curVal < q_point[1]) 0108 *qt = 1; 0109 else if (curVal < q_point[2]) 0110 *qt = 2; 0111 else if (curVal < q_point[3]) 0112 *qt = 3; 0113 else 0114 *qt = 4; 0115 } 0116 } 0117 0118 void init_main_qtable(fuji_compressed_params *params, uchar q_base) 0119 { 0120 fuji_q_table *qt = params->qt; 0121 int qp[5]; 0122 int maxVal = params->max_value + 1; 0123 qp[0] = q_base; 0124 qp[1] = 3 * q_base + 0x12; 0125 qp[2] = 5 * q_base + 0x43; 0126 qp[3] = 7 * q_base + 0x114; 0127 qp[4] = params->max_value; 0128 if (qp[1] >= maxVal || qp[1] < q_base + 1) 0129 qp[1] = q_base + 1; 0130 if (qp[2] < qp[1] || qp[2] >= maxVal) 0131 qp[2] = qp[1]; 0132 if (qp[3] < qp[2] || qp[3] >= maxVal) 0133 qp[3] = qp[2]; 0134 setup_qlut(qt->q_table, qp); 0135 qt->q_base = q_base; 0136 qt->max_grad = 0; 0137 qt->total_values = (qp[4] + 2 * q_base) / (2 * q_base + 1) + 1; 0138 qt->raw_bits = log2ceil(qt->total_values); 0139 qt->q_grad_mult = 9; 0140 params->max_bits = 4 * log2ceil(qp[4] + 1); 0141 } 0142 0143 void LibRaw::init_fuji_compr(fuji_compressed_params *params) 0144 { 0145 if ((libraw_internal_data.unpacker_data.fuji_block_width % 3 && 0146 libraw_internal_data.unpacker_data.fuji_raw_type == 16) || 0147 (libraw_internal_data.unpacker_data.fuji_block_width & 1 && 0148 libraw_internal_data.unpacker_data.fuji_raw_type == 0)) 0149 derror(); 0150 0151 size_t q_table_size = 2 << libraw_internal_data.unpacker_data.fuji_bits; 0152 if (libraw_internal_data.unpacker_data.fuji_lossless) 0153 params->buf = malloc(q_table_size); 0154 else 0155 params->buf = malloc(3 * q_table_size); 0156 0157 if (libraw_internal_data.unpacker_data.fuji_raw_type == 16) 0158 params->line_width = (libraw_internal_data.unpacker_data.fuji_block_width * 2) / 3; 0159 else 0160 params->line_width = libraw_internal_data.unpacker_data.fuji_block_width >> 1; 0161 0162 params->min_value = 0x40; 0163 params->max_value = (1 << libraw_internal_data.unpacker_data.fuji_bits) - 1; 0164 0165 // setup qtables 0166 if (libraw_internal_data.unpacker_data.fuji_lossless) 0167 { 0168 // setup main qtable only, zero the rest 0169 memset(params->qt + 1, 0, 3 * sizeof(fuji_q_table)); 0170 params->qt[0].q_table = (int8_t *)params->buf; 0171 params->qt[0].q_base = -1; 0172 init_main_qtable(params, 0); 0173 } 0174 else 0175 { 0176 // setup 3 extra qtables - main one will be set for each block 0177 memset(params->qt, 0, sizeof(fuji_q_table)); 0178 int qp[5]; 0179 0180 qp[0] = 0; 0181 qp[4] = params->max_value; 0182 0183 // table 0 0184 params->qt[1].q_table = (int8_t *)params->buf; 0185 params->qt[1].q_base = 0; 0186 params->qt[1].max_grad = 5; 0187 params->qt[1].q_grad_mult = 3; 0188 params->qt[1].total_values = qp[4] + 1; 0189 params->qt[1].raw_bits = log2ceil(params->qt[1].total_values); 0190 0191 qp[1] = qp[4] >= 0x12 ? 0x12 : qp[0] + 1; 0192 qp[2] = qp[4] >= 0x43 ? 0x43 : qp[1]; 0193 qp[3] = qp[4] >= 0x114 ? 0x114 : qp[2]; 0194 setup_qlut(params->qt[1].q_table, qp); 0195 0196 // table 1 0197 params->qt[2].q_table = params->qt[1].q_table + q_table_size; 0198 params->qt[2].q_base = 1; 0199 params->qt[2].max_grad = 6; 0200 params->qt[2].q_grad_mult = 3; 0201 params->qt[2].total_values = (qp[4] + 2) / 3 + 1; 0202 params->qt[2].raw_bits = log2ceil(params->qt[2].total_values); 0203 0204 qp[0] = params->qt[2].q_base; 0205 qp[1] = qp[4] >= 0x15 ? 0x15 : qp[0] + 1; 0206 qp[2] = qp[4] >= 0x48 ? 0x48 : qp[1]; 0207 qp[3] = qp[4] >= 0x11B ? 0x11B : qp[2]; 0208 setup_qlut(params->qt[2].q_table, qp); 0209 0210 // table 2 0211 params->qt[3].q_table = params->qt[2].q_table + q_table_size; 0212 params->qt[3].q_base = 2; 0213 params->qt[3].max_grad = 7; 0214 params->qt[3].q_grad_mult = 3; 0215 params->qt[3].total_values = (qp[4] + 4) / 5 + 1; 0216 params->qt[3].raw_bits = log2ceil(params->qt[3].total_values); 0217 0218 qp[0] = params->qt[3].q_base; 0219 qp[1] = qp[4] >= 0x18 ? 0x18 : qp[0] + 1; 0220 qp[2] = qp[4] >= 0x4D ? 0x4D : qp[1]; 0221 qp[3] = qp[4] >= 0x122 ? 0x122 : qp[2]; 0222 setup_qlut(params->qt[3].q_table, qp); 0223 } 0224 } 0225 0226 #define XTRANS_BUF_SIZE 0x10000 0227 0228 static inline void fuji_fill_buffer(fuji_compressed_block *info) 0229 { 0230 if (info->cur_pos >= info->cur_buf_size) 0231 { 0232 info->cur_pos = 0; 0233 info->cur_buf_offset += info->cur_buf_size; 0234 #ifdef LIBRAW_USE_OPENMP 0235 #pragma omp critical 0236 #endif 0237 { 0238 #ifndef LIBRAW_USE_OPENMP 0239 info->input->lock(); 0240 #endif 0241 info->input->seek(info->cur_buf_offset, SEEK_SET); 0242 info->cur_buf_size = info->input->read(info->cur_buf, 1, _min(info->max_read_size, XTRANS_BUF_SIZE)); 0243 #ifndef LIBRAW_USE_OPENMP 0244 info->input->unlock(); 0245 #endif 0246 if (info->cur_buf_size < 1) // nothing read 0247 { 0248 if (info->fillbytes > 0) 0249 { 0250 int ls = _max(1, _min(info->fillbytes, XTRANS_BUF_SIZE)); 0251 memset(info->cur_buf, 0, ls); 0252 info->fillbytes -= ls; 0253 } 0254 else 0255 throw LIBRAW_EXCEPTION_IO_EOF; 0256 } 0257 info->max_read_size -= info->cur_buf_size; 0258 } 0259 } 0260 } 0261 0262 void init_main_grads(const fuji_compressed_params *params, fuji_compressed_block *info) 0263 { 0264 int max_diff = _max(2, (params->qt->total_values + 0x20) >> 6); 0265 for (int j = 0; j < 3; j++) 0266 for (int i = 0; i < 41; i++) 0267 { 0268 info->even[j].grads[i].value1 = max_diff; 0269 info->even[j].grads[i].value2 = 1; 0270 info->odd[j].grads[i].value1 = max_diff; 0271 info->odd[j].grads[i].value2 = 1; 0272 } 0273 } 0274 0275 void LibRaw::init_fuji_block(fuji_compressed_block *info, const fuji_compressed_params *params, INT64 raw_offset, 0276 unsigned dsize) 0277 { 0278 info->linealloc = (ushort *)calloc(sizeof(ushort), _ltotal * (params->line_width + 2)); 0279 0280 INT64 fsize = libraw_internal_data.internal_data.input->size(); 0281 info->max_read_size = _min(unsigned(fsize - raw_offset), dsize); // Data size may be incorrect? 0282 info->fillbytes = 1; 0283 0284 info->input = libraw_internal_data.internal_data.input; 0285 info->linebuf[_R0] = info->linealloc; 0286 for (int i = _R1; i <= _B4; i++) 0287 info->linebuf[i] = info->linebuf[i - 1] + params->line_width + 2; 0288 0289 // init buffer 0290 info->cur_buf = (uchar *)malloc(XTRANS_BUF_SIZE); 0291 info->cur_bit = 0; 0292 info->cur_pos = 0; 0293 info->cur_buf_offset = raw_offset; 0294 info->cur_buf_size = 0; 0295 fuji_fill_buffer(info); 0296 0297 // init grads for lossy and lossless 0298 if (libraw_internal_data.unpacker_data.fuji_lossless) 0299 init_main_grads(params, info); 0300 else 0301 { 0302 // init static grads for lossy only - main ones are done per line 0303 for (int k = 0; k < 3; ++k) 0304 { 0305 int max_diff = _max(2, ((params->qt[k + 1].total_values + 0x20) >> 6)); 0306 for (int j = 0; j < 3; ++j) 0307 for (int i = 0; i < 5; ++i) 0308 { 0309 info->even[j].lossy_grads[k][i].value1 = max_diff; 0310 info->even[j].lossy_grads[k][i].value2 = 1; 0311 info->odd[j].lossy_grads[k][i].value1 = max_diff; 0312 info->odd[j].lossy_grads[k][i].value2 = 1; 0313 } 0314 } 0315 } 0316 } 0317 0318 void LibRaw::copy_line_to_xtrans(fuji_compressed_block *info, int cur_line, int cur_block, int cur_block_width) 0319 { 0320 ushort *lineBufB[3]; 0321 ushort *lineBufG[6]; 0322 ushort *lineBufR[3]; 0323 unsigned pixel_count; 0324 ushort *line_buf; 0325 int index; 0326 0327 int offset = libraw_internal_data.unpacker_data.fuji_block_width * cur_block + 6 * imgdata.sizes.raw_width * cur_line; 0328 ushort *raw_block_data = imgdata.rawdata.raw_image + offset; 0329 int row_count = 0; 0330 0331 for (int i = 0; i < 3; i++) 0332 { 0333 lineBufR[i] = info->linebuf[_R2 + i] + 1; 0334 lineBufB[i] = info->linebuf[_B2 + i] + 1; 0335 } 0336 for (int i = 0; i < 6; i++) 0337 lineBufG[i] = info->linebuf[_G2 + i] + 1; 0338 0339 while (row_count < 6) 0340 { 0341 pixel_count = 0; 0342 while (pixel_count < (unsigned)cur_block_width) 0343 { 0344 switch (imgdata.idata.xtrans_abs[row_count][(pixel_count % 6)]) 0345 { 0346 case 0: // red 0347 line_buf = lineBufR[row_count >> 1]; 0348 break; 0349 case 1: // green 0350 default: // to make static analyzer happy 0351 line_buf = lineBufG[row_count]; 0352 break; 0353 case 2: // blue 0354 line_buf = lineBufB[row_count >> 1]; 0355 break; 0356 } 0357 0358 index = (((pixel_count * 2 / 3) & 0x7FFFFFFE) | ((pixel_count % 3) & 1)) + ((pixel_count % 3) >> 1); 0359 raw_block_data[pixel_count] = line_buf[index]; 0360 0361 ++pixel_count; 0362 } 0363 ++row_count; 0364 raw_block_data += imgdata.sizes.raw_width; 0365 } 0366 } 0367 0368 void LibRaw::copy_line_to_bayer(fuji_compressed_block *info, int cur_line, int cur_block, int cur_block_width) 0369 { 0370 ushort *lineBufB[3]; 0371 ushort *lineBufG[6]; 0372 ushort *lineBufR[3]; 0373 unsigned pixel_count; 0374 ushort *line_buf; 0375 0376 int fuji_bayer[2][2]; 0377 for (int r = 0; r < 2; r++) 0378 for (int c = 0; c < 2; c++) 0379 fuji_bayer[r][c] = FC(r, c); // We'll downgrade G2 to G below 0380 0381 int offset = libraw_internal_data.unpacker_data.fuji_block_width * cur_block + 6 * imgdata.sizes.raw_width * cur_line; 0382 ushort *raw_block_data = imgdata.rawdata.raw_image + offset; 0383 int row_count = 0; 0384 0385 for (int i = 0; i < 3; i++) 0386 { 0387 lineBufR[i] = info->linebuf[_R2 + i] + 1; 0388 lineBufB[i] = info->linebuf[_B2 + i] + 1; 0389 } 0390 for (int i = 0; i < 6; i++) 0391 lineBufG[i] = info->linebuf[_G2 + i] + 1; 0392 0393 while (row_count < 6) 0394 { 0395 pixel_count = 0; 0396 while (pixel_count < (unsigned)cur_block_width) 0397 { 0398 switch (fuji_bayer[row_count & 1][pixel_count & 1]) 0399 { 0400 case 0: // red 0401 line_buf = lineBufR[row_count >> 1]; 0402 break; 0403 case 1: // green 0404 case 3: // second green 0405 default: // to make static analyzer happy 0406 line_buf = lineBufG[row_count]; 0407 break; 0408 case 2: // blue 0409 line_buf = lineBufB[row_count >> 1]; 0410 break; 0411 } 0412 0413 raw_block_data[pixel_count] = line_buf[pixel_count >> 1]; 0414 ++pixel_count; 0415 } 0416 ++row_count; 0417 raw_block_data += imgdata.sizes.raw_width; 0418 } 0419 } 0420 0421 #define fuji_quant_gradient(max, q, v1, v2) (q->q_grad_mult * q->q_table[(max) + (v1)] + q->q_table[(max) + (v2)]) 0422 0423 static inline void fuji_zerobits(fuji_compressed_block *info, int *count) 0424 { 0425 uchar zero = 0; 0426 *count = 0; 0427 while (zero == 0) 0428 { 0429 zero = (info->cur_buf[info->cur_pos] >> (7 - info->cur_bit)) & 1; 0430 info->cur_bit++; 0431 info->cur_bit &= 7; 0432 if (!info->cur_bit) 0433 { 0434 ++info->cur_pos; 0435 fuji_fill_buffer(info); 0436 } 0437 if (zero) 0438 break; 0439 ++*count; 0440 } 0441 } 0442 0443 static inline void fuji_read_code(fuji_compressed_block *info, int *data, int bits_to_read) 0444 { 0445 uchar bits_left = bits_to_read; 0446 uchar bits_left_in_byte = 8 - (info->cur_bit & 7); 0447 *data = 0; 0448 if (!bits_to_read) 0449 return; 0450 if (bits_to_read >= bits_left_in_byte) 0451 { 0452 do 0453 { 0454 *data <<= bits_left_in_byte; 0455 bits_left -= bits_left_in_byte; 0456 *data |= info->cur_buf[info->cur_pos] & ((1 << bits_left_in_byte) - 1); 0457 ++info->cur_pos; 0458 fuji_fill_buffer(info); 0459 bits_left_in_byte = 8; 0460 } while (bits_left >= 8); 0461 } 0462 if (!bits_left) 0463 { 0464 info->cur_bit = (8 - (bits_left_in_byte & 7)) & 7; 0465 return; 0466 } 0467 *data <<= bits_left; 0468 bits_left_in_byte -= bits_left; 0469 *data |= ((1 << bits_left) - 1) & ((unsigned)info->cur_buf[info->cur_pos] >> bits_left_in_byte); 0470 info->cur_bit = (8 - (bits_left_in_byte & 7)) & 7; 0471 } 0472 0473 static inline int bitDiff(int value1, int value2) 0474 { 0475 int decBits = 0; 0476 if (value2 < value1) 0477 while (decBits <= 14 && (value2 << ++decBits) < value1) 0478 ; 0479 return decBits; 0480 } 0481 0482 static inline int fuji_decode_sample_even(fuji_compressed_block *info, const fuji_compressed_params *params, 0483 ushort *line_buf, int pos, fuji_grads *grad_params) 0484 { 0485 int interp_val = 0; 0486 // ushort decBits; 0487 int errcnt = 0; 0488 0489 int sample = 0, code = 0; 0490 ushort *line_buf_cur = line_buf + pos; 0491 int Rb = line_buf_cur[-2 - params->line_width]; 0492 int Rc = line_buf_cur[-3 - params->line_width]; 0493 int Rd = line_buf_cur[-1 - params->line_width]; 0494 int Rf = line_buf_cur[-4 - 2 * params->line_width]; 0495 0496 int grad, gradient, diffRcRb, diffRfRb, diffRdRb; 0497 0498 diffRcRb = _abs(Rc - Rb); 0499 diffRfRb = _abs(Rf - Rb); 0500 diffRdRb = _abs(Rd - Rb); 0501 0502 const fuji_q_table *qt = params->qt; 0503 int_pair *grads = grad_params->grads; 0504 for (int i = 1; params->qt[0].q_base >= i && i < 4; ++i) 0505 if (diffRfRb + diffRcRb <= params->qt[i].max_grad) 0506 { 0507 qt = params->qt + i; 0508 grads = grad_params->lossy_grads[i - 1]; 0509 break; 0510 } 0511 0512 grad = fuji_quant_gradient(params->max_value, qt, Rb - Rf, Rc - Rb); 0513 gradient = _abs(grad); 0514 0515 if (diffRcRb > diffRfRb && diffRcRb > diffRdRb) 0516 interp_val = Rf + Rd + 2 * Rb; 0517 else if (diffRdRb > diffRcRb && diffRdRb > diffRfRb) 0518 interp_val = Rf + Rc + 2 * Rb; 0519 else 0520 interp_val = Rd + Rc + 2 * Rb; 0521 0522 fuji_zerobits(info, &sample); 0523 0524 if (sample < params->max_bits - qt->raw_bits - 1) 0525 { 0526 int decBits = bitDiff(grads[gradient].value1, grads[gradient].value2); 0527 fuji_read_code(info, &code, decBits); 0528 code += sample << decBits; 0529 } 0530 else 0531 { 0532 fuji_read_code(info, &code, qt->raw_bits); 0533 ++code; 0534 } 0535 0536 if (code < 0 || code >= qt->total_values) 0537 ++errcnt; 0538 0539 if (code & 1) 0540 code = -1 - code / 2; 0541 else 0542 code /= 2; 0543 0544 grads[gradient].value1 += _abs(code); 0545 if (grads[gradient].value2 == params->min_value) 0546 { 0547 grads[gradient].value1 >>= 1; 0548 grads[gradient].value2 >>= 1; 0549 } 0550 ++grads[gradient].value2; 0551 if (grad < 0) 0552 interp_val = (interp_val >> 2) - code * (2 * qt->q_base + 1); 0553 else 0554 interp_val = (interp_val >> 2) + code * (2 * qt->q_base + 1); 0555 if (interp_val < -qt->q_base) 0556 interp_val += qt->total_values * (2 * qt->q_base + 1); 0557 else if (interp_val > qt->q_base + params->max_value) 0558 interp_val -= qt->total_values * (2 * qt->q_base + 1); 0559 0560 if (interp_val >= 0) 0561 line_buf_cur[0] = _min(interp_val, params->max_value); 0562 else 0563 line_buf_cur[0] = 0; 0564 return errcnt; 0565 } 0566 0567 static inline int fuji_decode_sample_odd(fuji_compressed_block *info, const fuji_compressed_params *params, 0568 ushort *line_buf, int pos, fuji_grads *grad_params) 0569 { 0570 int interp_val = 0; 0571 int errcnt = 0; 0572 0573 int sample = 0, code = 0; 0574 ushort *line_buf_cur = line_buf + pos; 0575 int Ra = line_buf_cur[-1]; 0576 int Rb = line_buf_cur[-2 - params->line_width]; 0577 int Rc = line_buf_cur[-3 - params->line_width]; 0578 int Rd = line_buf_cur[-1 - params->line_width]; 0579 int Rg = line_buf_cur[1]; 0580 0581 int grad, gradient; 0582 0583 int diffRcRa = _abs(Rc - Ra); 0584 int diffRbRc = _abs(Rb - Rc); 0585 0586 const fuji_q_table *qt = params->qt; 0587 int_pair *grads = grad_params->grads; 0588 for (int i = 1; params->qt[0].q_base >= i && i < 4; ++i) 0589 if (diffRbRc + diffRcRa <= params->qt[i].max_grad) 0590 { 0591 qt = params->qt + i; 0592 grads = grad_params->lossy_grads[i - 1]; 0593 break; 0594 } 0595 0596 grad = fuji_quant_gradient(params->max_value, qt, Rb - Rc, Rc - Ra); 0597 gradient = _abs(grad); 0598 0599 if ((Rb > Rc && Rb > Rd) || (Rb < Rc && Rb < Rd)) 0600 interp_val = (Rg + Ra + 2 * Rb) >> 2; 0601 else 0602 interp_val = (Ra + Rg) >> 1; 0603 0604 fuji_zerobits(info, &sample); 0605 0606 if (sample < params->max_bits - qt->raw_bits - 1) 0607 { 0608 int decBits = bitDiff(grads[gradient].value1, grads[gradient].value2); 0609 fuji_read_code(info, &code, decBits); 0610 code += sample << decBits; 0611 } 0612 else 0613 { 0614 fuji_read_code(info, &code, qt->raw_bits); 0615 ++code; 0616 } 0617 0618 if (code < 0 || code >= qt->total_values) 0619 ++errcnt; 0620 0621 if (code & 1) 0622 code = -1 - code / 2; 0623 else 0624 code /= 2; 0625 0626 grads[gradient].value1 += _abs(code); 0627 if (grads[gradient].value2 == params->min_value) 0628 { 0629 grads[gradient].value1 >>= 1; 0630 grads[gradient].value2 >>= 1; 0631 } 0632 ++grads[gradient].value2; 0633 if (grad < 0) 0634 interp_val -= code * (2 * qt->q_base + 1); 0635 else 0636 interp_val += code * (2 * qt->q_base + 1); 0637 if (interp_val < -qt->q_base) 0638 interp_val += qt->total_values * (2 * qt->q_base + 1); 0639 else if (interp_val > qt->q_base + params->max_value) 0640 interp_val -= qt->total_values * (2 * qt->q_base + 1); 0641 0642 if (interp_val >= 0) 0643 line_buf_cur[0] = _min(interp_val, params->max_value); 0644 else 0645 line_buf_cur[0] = 0; 0646 return errcnt; 0647 } 0648 0649 static void fuji_decode_interpolation_even(int line_width, ushort *line_buf, int pos) 0650 { 0651 ushort *line_buf_cur = line_buf + pos; 0652 int Rb = line_buf_cur[-2 - line_width]; 0653 int Rc = line_buf_cur[-3 - line_width]; 0654 int Rd = line_buf_cur[-1 - line_width]; 0655 int Rf = line_buf_cur[-4 - 2 * line_width]; 0656 int diffRcRb = _abs(Rc - Rb); 0657 int diffRfRb = _abs(Rf - Rb); 0658 int diffRdRb = _abs(Rd - Rb); 0659 if (diffRcRb > diffRfRb && diffRcRb > diffRdRb) 0660 *line_buf_cur = (Rf + Rd + 2 * Rb) >> 2; 0661 else if (diffRdRb > diffRcRb && diffRdRb > diffRfRb) 0662 *line_buf_cur = (Rf + Rc + 2 * Rb) >> 2; 0663 else 0664 *line_buf_cur = (Rd + Rc + 2 * Rb) >> 2; 0665 } 0666 0667 static void fuji_extend_generic(ushort *linebuf[_ltotal], int line_width, int start, int end) 0668 { 0669 for (int i = start; i <= end; i++) 0670 { 0671 linebuf[i][0] = linebuf[i - 1][1]; 0672 linebuf[i][line_width + 1] = linebuf[i - 1][line_width]; 0673 } 0674 } 0675 0676 static void fuji_extend_red(ushort *linebuf[_ltotal], int line_width) 0677 { 0678 fuji_extend_generic(linebuf, line_width, _R2, _R4); 0679 } 0680 0681 static void fuji_extend_green(ushort *linebuf[_ltotal], int line_width) 0682 { 0683 fuji_extend_generic(linebuf, line_width, _G2, _G7); 0684 } 0685 0686 static void fuji_extend_blue(ushort *linebuf[_ltotal], int line_width) 0687 { 0688 fuji_extend_generic(linebuf, line_width, _B2, _B4); 0689 } 0690 0691 void LibRaw::xtrans_decode_block(fuji_compressed_block *info, const fuji_compressed_params *params, int /*cur_line*/) 0692 { 0693 int r_even_pos = 0, r_odd_pos = 1; 0694 int g_even_pos = 0, g_odd_pos = 1; 0695 int b_even_pos = 0, b_odd_pos = 1; 0696 0697 int errcnt = 0; 0698 0699 const int line_width = params->line_width; 0700 0701 while (g_even_pos < line_width || g_odd_pos < line_width) 0702 { 0703 if (g_even_pos < line_width) 0704 { 0705 fuji_decode_interpolation_even(line_width, info->linebuf[_R2] + 1, r_even_pos); 0706 r_even_pos += 2; 0707 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G2] + 1, g_even_pos, &info->even[0]); 0708 g_even_pos += 2; 0709 } 0710 if (g_even_pos > 8) 0711 { 0712 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R2] + 1, r_odd_pos, &info->odd[0]); 0713 r_odd_pos += 2; 0714 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G2] + 1, g_odd_pos, &info->odd[0]); 0715 g_odd_pos += 2; 0716 } 0717 } 0718 0719 fuji_extend_red(info->linebuf, line_width); 0720 fuji_extend_green(info->linebuf, line_width); 0721 0722 g_even_pos = 0, g_odd_pos = 1; 0723 0724 while (g_even_pos < line_width || g_odd_pos < line_width) 0725 { 0726 if (g_even_pos < line_width) 0727 { 0728 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G3] + 1, g_even_pos, &info->even[1]); 0729 g_even_pos += 2; 0730 fuji_decode_interpolation_even(line_width, info->linebuf[_B2] + 1, b_even_pos); 0731 b_even_pos += 2; 0732 } 0733 if (g_even_pos > 8) 0734 { 0735 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G3] + 1, g_odd_pos, &info->odd[1]); 0736 g_odd_pos += 2; 0737 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B2] + 1, b_odd_pos, &info->odd[1]); 0738 b_odd_pos += 2; 0739 } 0740 } 0741 0742 fuji_extend_green(info->linebuf, line_width); 0743 fuji_extend_blue(info->linebuf, line_width); 0744 0745 r_even_pos = 0, r_odd_pos = 1; 0746 g_even_pos = 0, g_odd_pos = 1; 0747 0748 while (g_even_pos < line_width || g_odd_pos < line_width) 0749 { 0750 if (g_even_pos < line_width) 0751 { 0752 if (r_even_pos & 3) 0753 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R3] + 1, r_even_pos, &info->even[2]); 0754 else 0755 fuji_decode_interpolation_even(line_width, info->linebuf[_R3] + 1, r_even_pos); 0756 r_even_pos += 2; 0757 fuji_decode_interpolation_even(line_width, info->linebuf[_G4] + 1, g_even_pos); 0758 g_even_pos += 2; 0759 } 0760 if (g_even_pos > 8) 0761 { 0762 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R3] + 1, r_odd_pos, &info->odd[2]); 0763 r_odd_pos += 2; 0764 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G4] + 1, g_odd_pos, &info->odd[2]); 0765 g_odd_pos += 2; 0766 } 0767 } 0768 0769 fuji_extend_red(info->linebuf, line_width); 0770 fuji_extend_green(info->linebuf, line_width); 0771 0772 g_even_pos = 0, g_odd_pos = 1; 0773 b_even_pos = 0, b_odd_pos = 1; 0774 0775 while (g_even_pos < line_width || g_odd_pos < line_width) 0776 { 0777 if (g_even_pos < line_width) 0778 { 0779 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G5] + 1, g_even_pos, &info->even[0]); 0780 g_even_pos += 2; 0781 if ((b_even_pos & 3) == 2) 0782 fuji_decode_interpolation_even(line_width, info->linebuf[_B3] + 1, b_even_pos); 0783 else 0784 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B3] + 1, b_even_pos, &info->even[0]); 0785 b_even_pos += 2; 0786 } 0787 if (g_even_pos > 8) 0788 { 0789 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G5] + 1, g_odd_pos, &info->odd[0]); 0790 g_odd_pos += 2; 0791 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B3] + 1, b_odd_pos, &info->odd[0]); 0792 b_odd_pos += 2; 0793 } 0794 } 0795 0796 fuji_extend_green(info->linebuf, line_width); 0797 fuji_extend_blue(info->linebuf, line_width); 0798 0799 r_even_pos = 0, r_odd_pos = 1; 0800 g_even_pos = 0, g_odd_pos = 1; 0801 0802 while (g_even_pos < line_width || g_odd_pos < line_width) 0803 { 0804 if (g_even_pos < line_width) 0805 { 0806 if ((r_even_pos & 3) == 2) 0807 fuji_decode_interpolation_even(line_width, info->linebuf[_R4] + 1, r_even_pos); 0808 else 0809 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R4] + 1, r_even_pos, &info->even[1]); 0810 r_even_pos += 2; 0811 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G6] + 1, g_even_pos, &info->even[1]); 0812 g_even_pos += 2; 0813 } 0814 if (g_even_pos > 8) 0815 { 0816 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R4] + 1, r_odd_pos, &info->odd[1]); 0817 r_odd_pos += 2; 0818 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G6] + 1, g_odd_pos, &info->odd[1]); 0819 g_odd_pos += 2; 0820 } 0821 } 0822 0823 fuji_extend_red(info->linebuf, line_width); 0824 fuji_extend_green(info->linebuf, line_width); 0825 0826 g_even_pos = 0, g_odd_pos = 1; 0827 b_even_pos = 0, b_odd_pos = 1; 0828 0829 while (g_even_pos < line_width || g_odd_pos < line_width) 0830 { 0831 if (g_even_pos < line_width) 0832 { 0833 fuji_decode_interpolation_even(line_width, info->linebuf[_G7] + 1, g_even_pos); 0834 g_even_pos += 2; 0835 if (b_even_pos & 3) 0836 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B4] + 1, b_even_pos, &info->even[2]); 0837 else 0838 fuji_decode_interpolation_even(line_width, info->linebuf[_B4] + 1, b_even_pos); 0839 b_even_pos += 2; 0840 } 0841 if (g_even_pos > 8) 0842 { 0843 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G7] + 1, g_odd_pos, &info->odd[2]); 0844 g_odd_pos += 2; 0845 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B4] + 1, b_odd_pos, &info->odd[2]); 0846 b_odd_pos += 2; 0847 } 0848 } 0849 0850 fuji_extend_green(info->linebuf, line_width); 0851 fuji_extend_blue(info->linebuf, line_width); 0852 0853 if (errcnt) 0854 derror(); 0855 } 0856 0857 void LibRaw::fuji_bayer_decode_block(fuji_compressed_block *info, const fuji_compressed_params *params, int /*cur_line*/) 0858 { 0859 int r_even_pos = 0, r_odd_pos = 1; 0860 int g_even_pos = 0, g_odd_pos = 1; 0861 int b_even_pos = 0, b_odd_pos = 1; 0862 0863 int errcnt = 0; 0864 0865 const int line_width = params->line_width; 0866 0867 while (g_even_pos < line_width || g_odd_pos < line_width) 0868 { 0869 if (g_even_pos < line_width) 0870 { 0871 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R2] + 1, r_even_pos, &info->even[0]); 0872 r_even_pos += 2; 0873 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G2] + 1, g_even_pos, &info->even[0]); 0874 g_even_pos += 2; 0875 } 0876 if (g_even_pos > 8) 0877 { 0878 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R2] + 1, r_odd_pos, &info->odd[0]); 0879 r_odd_pos += 2; 0880 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G2] + 1, g_odd_pos, &info->odd[0]); 0881 g_odd_pos += 2; 0882 } 0883 } 0884 0885 fuji_extend_red(info->linebuf, line_width); 0886 fuji_extend_green(info->linebuf, line_width); 0887 0888 g_even_pos = 0, g_odd_pos = 1; 0889 0890 while (g_even_pos < line_width || g_odd_pos < line_width) 0891 { 0892 if (g_even_pos < line_width) 0893 { 0894 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G3] + 1, g_even_pos, &info->even[1]); 0895 g_even_pos += 2; 0896 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B2] + 1, b_even_pos, &info->even[1]); 0897 b_even_pos += 2; 0898 } 0899 if (g_even_pos > 8) 0900 { 0901 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G3] + 1, g_odd_pos, &info->odd[1]); 0902 g_odd_pos += 2; 0903 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B2] + 1, b_odd_pos, &info->odd[1]); 0904 b_odd_pos += 2; 0905 } 0906 } 0907 0908 fuji_extend_green(info->linebuf, line_width); 0909 fuji_extend_blue(info->linebuf, line_width); 0910 0911 r_even_pos = 0, r_odd_pos = 1; 0912 g_even_pos = 0, g_odd_pos = 1; 0913 0914 while (g_even_pos < line_width || g_odd_pos < line_width) 0915 { 0916 if (g_even_pos < line_width) 0917 { 0918 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R3] + 1, r_even_pos, &info->even[2]); 0919 r_even_pos += 2; 0920 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G4] + 1, g_even_pos, &info->even[2]); 0921 g_even_pos += 2; 0922 } 0923 if (g_even_pos > 8) 0924 { 0925 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R3] + 1, r_odd_pos, &info->odd[2]); 0926 r_odd_pos += 2; 0927 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G4] + 1, g_odd_pos, &info->odd[2]); 0928 g_odd_pos += 2; 0929 } 0930 } 0931 0932 fuji_extend_red(info->linebuf, line_width); 0933 fuji_extend_green(info->linebuf, line_width); 0934 0935 g_even_pos = 0, g_odd_pos = 1; 0936 b_even_pos = 0, b_odd_pos = 1; 0937 0938 while (g_even_pos < line_width || g_odd_pos < line_width) 0939 { 0940 if (g_even_pos < line_width) 0941 { 0942 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G5] + 1, g_even_pos, &info->even[0]); 0943 g_even_pos += 2; 0944 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B3] + 1, b_even_pos, &info->even[0]); 0945 b_even_pos += 2; 0946 } 0947 if (g_even_pos > 8) 0948 { 0949 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G5] + 1, g_odd_pos, &info->odd[0]); 0950 g_odd_pos += 2; 0951 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B3] + 1, b_odd_pos, &info->odd[0]); 0952 b_odd_pos += 2; 0953 } 0954 } 0955 0956 fuji_extend_green(info->linebuf, line_width); 0957 fuji_extend_blue(info->linebuf, line_width); 0958 0959 r_even_pos = 0, r_odd_pos = 1; 0960 g_even_pos = 0, g_odd_pos = 1; 0961 0962 while (g_even_pos < line_width || g_odd_pos < line_width) 0963 { 0964 if (g_even_pos < line_width) 0965 { 0966 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_R4] + 1, r_even_pos, &info->even[1]); 0967 r_even_pos += 2; 0968 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G6] + 1, g_even_pos, &info->even[1]); 0969 g_even_pos += 2; 0970 } 0971 if (g_even_pos > 8) 0972 { 0973 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_R4] + 1, r_odd_pos, &info->odd[1]); 0974 r_odd_pos += 2; 0975 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G6] + 1, g_odd_pos, &info->odd[1]); 0976 g_odd_pos += 2; 0977 } 0978 } 0979 0980 fuji_extend_red(info->linebuf, line_width); 0981 fuji_extend_green(info->linebuf, line_width); 0982 0983 g_even_pos = 0, g_odd_pos = 1; 0984 b_even_pos = 0, b_odd_pos = 1; 0985 0986 while (g_even_pos < line_width || g_odd_pos < line_width) 0987 { 0988 if (g_even_pos < line_width) 0989 { 0990 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_G7] + 1, g_even_pos, &info->even[2]); 0991 g_even_pos += 2; 0992 errcnt += fuji_decode_sample_even(info, params, info->linebuf[_B4] + 1, b_even_pos, &info->even[2]); 0993 b_even_pos += 2; 0994 } 0995 if (g_even_pos > 8) 0996 { 0997 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_G7] + 1, g_odd_pos, &info->odd[2]); 0998 g_odd_pos += 2; 0999 errcnt += fuji_decode_sample_odd(info, params, info->linebuf[_B4] + 1, b_odd_pos, &info->odd[2]); 1000 b_odd_pos += 2; 1001 } 1002 } 1003 1004 fuji_extend_green(info->linebuf, line_width); 1005 fuji_extend_blue(info->linebuf, line_width); 1006 1007 if (errcnt) 1008 derror(); 1009 } 1010 1011 void LibRaw::fuji_decode_strip(fuji_compressed_params *params, int cur_block, INT64 raw_offset, unsigned dsize, 1012 uchar *q_bases) 1013 { 1014 int cur_block_width, cur_line; 1015 unsigned line_size; 1016 fuji_compressed_block info; 1017 fuji_compressed_params *info_common = params; 1018 1019 if (!libraw_internal_data.unpacker_data.fuji_lossless) 1020 { 1021 int buf_size = sizeof(fuji_compressed_params) + (2 << libraw_internal_data.unpacker_data.fuji_bits); 1022 1023 info_common = (fuji_compressed_params *)malloc(buf_size); 1024 memcpy(info_common, params, sizeof(fuji_compressed_params)); 1025 info_common->qt[0].q_table = (int8_t *)(info_common + 1); 1026 info_common->qt[0].q_base = -1; 1027 } 1028 init_fuji_block(&info, info_common, raw_offset, dsize); 1029 line_size = sizeof(ushort) * (info_common->line_width + 2); 1030 1031 cur_block_width = libraw_internal_data.unpacker_data.fuji_block_width; 1032 if (cur_block + 1 == libraw_internal_data.unpacker_data.fuji_total_blocks) 1033 { 1034 cur_block_width = imgdata.sizes.raw_width - (libraw_internal_data.unpacker_data.fuji_block_width * cur_block); 1035 /* Old code, may get incorrect results on GFX50, but luckily large optical 1036 black cur_block_width = imgdata.sizes.raw_width % 1037 libraw_internal_data.unpacker_data.fuji_block_width; 1038 */ 1039 } 1040 1041 struct i_pair 1042 { 1043 int a, b; 1044 }; 1045 const i_pair mtable[6] = {{_R0, _R3}, {_R1, _R4}, {_G0, _G6}, {_G1, _G7}, {_B0, _B3}, {_B1, _B4}}, 1046 ztable[3] = {{_R2, 3}, {_G2, 6}, {_B2, 3}}; 1047 for (cur_line = 0; cur_line < libraw_internal_data.unpacker_data.fuji_total_lines; cur_line++) 1048 { 1049 // init grads and main qtable 1050 if (!libraw_internal_data.unpacker_data.fuji_lossless) 1051 { 1052 int q_base = q_bases ? q_bases[cur_line] : 0; 1053 if (!cur_line || q_base != info_common->qt[0].q_base) 1054 { 1055 init_main_qtable(info_common, q_bases[cur_line]); 1056 init_main_grads(info_common, &info); 1057 } 1058 } 1059 1060 if (libraw_internal_data.unpacker_data.fuji_raw_type == 16) 1061 xtrans_decode_block(&info, info_common, cur_line); 1062 else 1063 fuji_bayer_decode_block(&info, info_common, cur_line); 1064 1065 // copy data from line buffers and advance 1066 for (int i = 0; i < 6; i++) 1067 memcpy(info.linebuf[mtable[i].a], info.linebuf[mtable[i].b], line_size); 1068 1069 if (libraw_internal_data.unpacker_data.fuji_raw_type == 16) 1070 copy_line_to_xtrans(&info, cur_line, cur_block, cur_block_width); 1071 else 1072 copy_line_to_bayer(&info, cur_line, cur_block, cur_block_width); 1073 1074 for (int i = 0; i < 3; i++) 1075 { 1076 memset(info.linebuf[ztable[i].a], 0, ztable[i].b * line_size); 1077 info.linebuf[ztable[i].a][0] = info.linebuf[ztable[i].a - 1][1]; 1078 info.linebuf[ztable[i].a][info_common->line_width + 1] = info.linebuf[ztable[i].a - 1][info_common->line_width]; 1079 } 1080 } 1081 1082 // release data 1083 if (!libraw_internal_data.unpacker_data.fuji_lossless) 1084 free(info_common); 1085 free(info.linealloc); 1086 free(info.cur_buf); 1087 } 1088 1089 void LibRaw::fuji_compressed_load_raw() 1090 { 1091 fuji_compressed_params common_info; 1092 int cur_block; 1093 unsigned *block_sizes; 1094 uchar *q_bases = 0; 1095 INT64 raw_offset, *raw_block_offsets; 1096 1097 init_fuji_compr(&common_info); 1098 1099 // read block sizes 1100 block_sizes = (unsigned *)malloc(sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks); 1101 raw_block_offsets = (INT64 *)malloc(sizeof(INT64) * libraw_internal_data.unpacker_data.fuji_total_blocks); 1102 1103 libraw_internal_data.internal_data.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET); 1104 int sizesToRead = sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks; 1105 if (libraw_internal_data.internal_data.input->read(block_sizes, 1, sizesToRead) != sizesToRead) 1106 { 1107 free(block_sizes); 1108 free(raw_block_offsets); 1109 throw LIBRAW_EXCEPTION_IO_EOF; 1110 } 1111 1112 raw_offset = ((sizeof(unsigned) * libraw_internal_data.unpacker_data.fuji_total_blocks) + 0xF) & ~0xF; 1113 1114 // read q bases for lossy 1115 if (!libraw_internal_data.unpacker_data.fuji_lossless) 1116 { 1117 int total_q_bases = libraw_internal_data.unpacker_data.fuji_total_blocks * 1118 ((libraw_internal_data.unpacker_data.fuji_total_lines + 0xF) & ~0xF); 1119 q_bases = (uchar *)malloc(total_q_bases); 1120 libraw_internal_data.internal_data.input->seek(raw_offset + libraw_internal_data.unpacker_data.data_offset, 1121 SEEK_SET); 1122 libraw_internal_data.internal_data.input->read(q_bases, 1, total_q_bases); 1123 raw_offset += total_q_bases; 1124 } 1125 1126 raw_offset += libraw_internal_data.unpacker_data.data_offset; 1127 1128 // calculating raw block offsets 1129 raw_block_offsets[0] = raw_offset; 1130 for (cur_block = 0; cur_block < libraw_internal_data.unpacker_data.fuji_total_blocks; cur_block++) 1131 { 1132 unsigned bsize = sgetn(4, (uchar *)(block_sizes + cur_block)); 1133 block_sizes[cur_block] = bsize; 1134 } 1135 1136 for (cur_block = 1; cur_block < libraw_internal_data.unpacker_data.fuji_total_blocks; cur_block++) 1137 raw_block_offsets[cur_block] = raw_block_offsets[cur_block - 1] + block_sizes[cur_block - 1]; 1138 1139 fuji_decode_loop(&common_info, libraw_internal_data.unpacker_data.fuji_total_blocks, raw_block_offsets, block_sizes, 1140 q_bases); 1141 1142 free(q_bases); 1143 free(block_sizes); 1144 free(raw_block_offsets); 1145 free(common_info.buf); 1146 } 1147 1148 void LibRaw::fuji_decode_loop(fuji_compressed_params *common_info, int count, INT64 *raw_block_offsets, 1149 unsigned *block_sizes, uchar *q_bases) 1150 { 1151 int cur_block; 1152 const int lineStep = (libraw_internal_data.unpacker_data.fuji_total_lines + 0xF) & ~0xF; 1153 #ifdef LIBRAW_USE_OPENMP 1154 #pragma omp parallel for private(cur_block) 1155 #endif 1156 for (cur_block = 0; cur_block < count; cur_block++) 1157 { 1158 fuji_decode_strip(common_info, cur_block, raw_block_offsets[cur_block], block_sizes[cur_block], 1159 q_bases ? q_bases + cur_block * lineStep : 0); 1160 } 1161 } 1162 1163 void LibRaw::parse_fuji_compressed_header() 1164 { 1165 unsigned signature, lossless, h_raw_type, h_raw_bits, h_raw_height, h_raw_rounded_width, h_raw_width, h_block_size, 1166 h_blocks_in_row, h_total_lines; 1167 1168 uchar header[16]; 1169 1170 libraw_internal_data.internal_data.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET); 1171 if (libraw_internal_data.internal_data.input->read(header, 1, sizeof(header)) != sizeof(header)) 1172 return; 1173 1174 // read all header 1175 signature = sgetn(2, header); 1176 lossless = header[2]; 1177 h_raw_type = header[3]; 1178 h_raw_bits = header[4]; 1179 h_raw_height = sgetn(2, header + 5); 1180 h_raw_rounded_width = sgetn(2, header + 7); 1181 h_raw_width = sgetn(2, header + 9); 1182 h_block_size = sgetn(2, header + 11); 1183 h_blocks_in_row = header[13]; 1184 h_total_lines = sgetn(2, header + 14); 1185 1186 // general validation 1187 if (signature != 0x4953 || lossless > 1 || h_raw_height > 0x4002 || h_raw_height < 6 || h_raw_height % 6 || 1188 h_block_size < 1 || h_raw_width > 0x4200 || h_raw_width < 0x300 || h_raw_width % 24 || 1189 h_raw_rounded_width > 0x4200 || h_raw_rounded_width < h_block_size || h_raw_rounded_width % h_block_size || 1190 h_raw_rounded_width - h_raw_width >= h_block_size || h_block_size != 0x300 || h_blocks_in_row > 0x10 || 1191 h_blocks_in_row == 0 || h_blocks_in_row != h_raw_rounded_width / h_block_size || h_total_lines > 0xAAB || 1192 h_total_lines == 0 || h_total_lines != h_raw_height / 6 || 1193 (h_raw_bits != 12 && h_raw_bits != 14 && h_raw_bits != 16) || (h_raw_type != 16 && h_raw_type != 0)) 1194 return; 1195 1196 // modify data 1197 libraw_internal_data.unpacker_data.fuji_total_lines = h_total_lines; 1198 libraw_internal_data.unpacker_data.fuji_total_blocks = h_blocks_in_row; 1199 libraw_internal_data.unpacker_data.fuji_block_width = h_block_size; 1200 libraw_internal_data.unpacker_data.fuji_bits = h_raw_bits; 1201 libraw_internal_data.unpacker_data.fuji_raw_type = h_raw_type; 1202 libraw_internal_data.unpacker_data.fuji_lossless = lossless; 1203 imgdata.sizes.raw_width = h_raw_width; 1204 imgdata.sizes.raw_height = h_raw_height; 1205 libraw_internal_data.unpacker_data.data_offset += 16; 1206 load_raw = &LibRaw::fuji_compressed_load_raw; 1207 } 1208 1209 #undef _abs 1210 #undef _min