File indexing completed on 2025-01-05 03:57:09
0001 /* -*- C++ -*- 0002 * Copyright 2019-2021 LibRaw LLC (info@libraw.org) 0003 * 0004 0005 LibRaw is free software; you can redistribute it and/or modify 0006 it under the terms of the one of two licenses as you choose: 0007 0008 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1 0009 (See file LICENSE.LGPL provided in LibRaw distribution archive for details). 0010 0011 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 0012 (See file LICENSE.CDDL provided in LibRaw distribution archive for details). 0013 0014 */ 0015 0016 #include "../../internal/libraw_cxx_defs.h" 0017 0018 #ifdef __cplusplus 0019 extern "C" 0020 { 0021 #endif 0022 0023 void default_data_callback(void *, const char *file, const int offset) 0024 { 0025 if (offset < 0) 0026 fprintf(stderr, "%s: Unexpected end of file\n", 0027 file ? file : "unknown file"); 0028 else 0029 fprintf(stderr, "%s: data corrupted at %d\n", 0030 file ? file : "unknown file", offset); 0031 } 0032 const char *libraw_strerror(int e) 0033 { 0034 enum LibRaw_errors errorcode = (LibRaw_errors)e; 0035 switch (errorcode) 0036 { 0037 case LIBRAW_SUCCESS: 0038 return "No error"; 0039 case LIBRAW_UNSPECIFIED_ERROR: 0040 return "Unspecified error"; 0041 case LIBRAW_FILE_UNSUPPORTED: 0042 return "Unsupported file format or not RAW file"; 0043 case LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE: 0044 return "Request for nonexisting image number"; 0045 case LIBRAW_OUT_OF_ORDER_CALL: 0046 return "Out of order call of libraw function"; 0047 case LIBRAW_NO_THUMBNAIL: 0048 return "No thumbnail in file"; 0049 case LIBRAW_UNSUPPORTED_THUMBNAIL: 0050 return "Unsupported thumbnail format"; 0051 case LIBRAW_INPUT_CLOSED: 0052 return "No input stream, or input stream closed"; 0053 case LIBRAW_NOT_IMPLEMENTED: 0054 return "Decoder not implemented for this data format"; 0055 case LIBRAW_REQUEST_FOR_NONEXISTENT_THUMBNAIL: 0056 return "Request for nonexisting thumbnail number"; 0057 case LIBRAW_MEMPOOL_OVERFLOW: 0058 return "Libraw internal mempool overflowed"; 0059 case LIBRAW_UNSUFFICIENT_MEMORY: 0060 return "Unsufficient memory"; 0061 case LIBRAW_DATA_ERROR: 0062 return "Corrupted data or unexpected EOF"; 0063 case LIBRAW_IO_ERROR: 0064 return "Input/output error"; 0065 case LIBRAW_CANCELLED_BY_CALLBACK: 0066 return "Cancelled by user callback"; 0067 case LIBRAW_BAD_CROP: 0068 return "Bad crop box"; 0069 case LIBRAW_TOO_BIG: 0070 return "Image too big for processing"; 0071 default: 0072 return "Unknown error code"; 0073 } 0074 } 0075 0076 #ifdef __cplusplus 0077 } 0078 #endif 0079 0080 unsigned LibRaw::parse_custom_cameras(unsigned limit, 0081 libraw_custom_camera_t table[], 0082 char **list) 0083 { 0084 if (!list) 0085 return 0; 0086 unsigned index = 0; 0087 for (unsigned i = 0; i < limit; i++) 0088 { 0089 if (!list[i]) 0090 break; 0091 if (strlen(list[i]) < 10) 0092 continue; 0093 char *string = (char *)malloc(strlen(list[i]) + 1); 0094 strcpy(string, list[i]); 0095 char *start = string; 0096 memset(&table[index], 0, sizeof(table[0])); 0097 for (int j = 0; start && j < 14; j++) 0098 { 0099 char *end = strchr(start, ','); 0100 if (end) 0101 { 0102 *end = 0; 0103 end++; 0104 } // move to next char 0105 while (isspace(*start) && *start) 0106 start++; // skip leading spaces? 0107 unsigned val = strtol(start, 0, 10); 0108 switch (j) 0109 { 0110 case 0: 0111 table[index].fsize = val; 0112 break; 0113 case 1: 0114 table[index].rw = val; 0115 break; 0116 case 2: 0117 table[index].rh = val; 0118 break; 0119 case 3: 0120 table[index].lm = val; 0121 break; 0122 case 4: 0123 table[index].tm = val; 0124 break; 0125 case 5: 0126 table[index].rm = val; 0127 break; 0128 case 6: 0129 table[index].bm = val; 0130 break; 0131 case 7: 0132 table[index].lf = val; 0133 break; 0134 case 8: 0135 table[index].cf = val; 0136 break; 0137 case 9: 0138 table[index].max = val; 0139 break; 0140 case 10: 0141 table[index].flags = val; 0142 break; 0143 case 11: 0144 strncpy(table[index].t_make, start, sizeof(table[index].t_make) - 1); 0145 break; 0146 case 12: 0147 strncpy(table[index].t_model, start, sizeof(table[index].t_model) - 1); 0148 break; 0149 case 13: 0150 table[index].offset = val; 0151 break; 0152 default: 0153 break; 0154 } 0155 start = end; 0156 } 0157 free(string); 0158 if (table[index].t_make[0]) 0159 index++; 0160 } 0161 return index; 0162 } 0163 0164 void LibRaw::derror() 0165 { 0166 if (!libraw_internal_data.unpacker_data.data_error && 0167 libraw_internal_data.internal_data.input) 0168 { 0169 if (libraw_internal_data.internal_data.input->eof()) 0170 { 0171 if (callbacks.data_cb) 0172 (*callbacks.data_cb)(callbacks.datacb_data, 0173 libraw_internal_data.internal_data.input->fname(), 0174 -1); 0175 throw LIBRAW_EXCEPTION_IO_EOF; 0176 } 0177 else 0178 { 0179 if (callbacks.data_cb) 0180 (*callbacks.data_cb)(callbacks.datacb_data, 0181 libraw_internal_data.internal_data.input->fname(), 0182 libraw_internal_data.internal_data.input->tell()); 0183 // throw LIBRAW_EXCEPTION_IO_CORRUPT; 0184 } 0185 } 0186 libraw_internal_data.unpacker_data.data_error++; 0187 } 0188 0189 const char *LibRaw::version() { return LIBRAW_VERSION_STR; } 0190 int LibRaw::versionNumber() { return LIBRAW_VERSION; } 0191 const char *LibRaw::strerror(int p) { return libraw_strerror(p); } 0192 0193 unsigned LibRaw::capabilities() 0194 { 0195 unsigned ret = 0; 0196 #ifdef USE_RAWSPEED 0197 ret |= LIBRAW_CAPS_RAWSPEED; 0198 #endif 0199 #ifdef USE_RAWSPEED3 0200 ret |= LIBRAW_CAPS_RAWSPEED3; 0201 #endif 0202 #ifdef USE_RAWSPEED_BITS 0203 ret |= LIBRAW_CAPS_RAWSPEED_BITS; 0204 #endif 0205 #ifdef USE_DNGSDK 0206 ret |= LIBRAW_CAPS_DNGSDK; 0207 #ifdef USE_GPRSDK 0208 ret |= LIBRAW_CAPS_GPRSDK; 0209 #endif 0210 #ifdef LIBRAW_WIN32_UNICODEPATHS 0211 ret |= LIBRAW_CAPS_UNICODEPATHS; 0212 #endif 0213 #endif 0214 #ifdef USE_X3FTOOLS 0215 ret |= LIBRAW_CAPS_X3FTOOLS; 0216 #endif 0217 #ifdef USE_6BY9RPI 0218 ret |= LIBRAW_CAPS_RPI6BY9; 0219 #endif 0220 #ifdef USE_ZLIB 0221 ret |= LIBRAW_CAPS_ZLIB; 0222 #endif 0223 #ifdef USE_JPEG 0224 ret |= LIBRAW_CAPS_JPEG; 0225 #endif 0226 return ret; 0227 } 0228 0229 int LibRaw::is_sraw() 0230 { 0231 return load_raw == &LibRaw::canon_sraw_load_raw || 0232 load_raw == &LibRaw::nikon_load_sraw; 0233 } 0234 int LibRaw::is_coolscan_nef() 0235 { 0236 return load_raw == &LibRaw::nikon_coolscan_load_raw; 0237 } 0238 int LibRaw::is_jpeg_thumb() 0239 { 0240 return libraw_internal_data.unpacker_data.thumb_format == LIBRAW_INTERNAL_THUMBNAIL_JPEG; 0241 } 0242 0243 int LibRaw::is_nikon_sraw() { return load_raw == &LibRaw::nikon_load_sraw; } 0244 int LibRaw::sraw_midpoint() 0245 { 0246 if (load_raw == &LibRaw::canon_sraw_load_raw) 0247 return 8192; 0248 else if (load_raw == &LibRaw::nikon_load_sraw) 0249 return 2048; 0250 else 0251 return 0; 0252 } 0253 0254 void *LibRaw::malloc(size_t t) 0255 { 0256 void *p = memmgr.malloc(t); 0257 if (!p) 0258 throw LIBRAW_EXCEPTION_ALLOC; 0259 return p; 0260 } 0261 void *LibRaw::realloc(void *q, size_t t) 0262 { 0263 void *p = memmgr.realloc(q, t); 0264 if (!p) 0265 throw LIBRAW_EXCEPTION_ALLOC; 0266 return p; 0267 } 0268 0269 void *LibRaw::calloc(size_t n, size_t t) 0270 { 0271 void *p = memmgr.calloc(n, t); 0272 if (!p) 0273 throw LIBRAW_EXCEPTION_ALLOC; 0274 return p; 0275 } 0276 void LibRaw::free(void *p) { memmgr.free(p); } 0277 0278 void LibRaw::recycle_datastream() 0279 { 0280 if (libraw_internal_data.internal_data.input && 0281 libraw_internal_data.internal_data.input_internal) 0282 { 0283 delete libraw_internal_data.internal_data.input; 0284 libraw_internal_data.internal_data.input = NULL; 0285 } 0286 libraw_internal_data.internal_data.input_internal = 0; 0287 } 0288 0289 void LibRaw::clearCancelFlag() 0290 { 0291 #ifdef _MSC_VER 0292 InterlockedExchange(&_exitflag, 0); 0293 #else 0294 __sync_fetch_and_and(&_exitflag, 0); 0295 #endif 0296 #ifdef RAWSPEED_FASTEXIT 0297 if (_rawspeed_decoder) 0298 { 0299 RawSpeed::RawDecoder *d = 0300 static_cast<RawSpeed::RawDecoder *>(_rawspeed_decoder); 0301 d->resumeProcessing(); 0302 } 0303 #endif 0304 } 0305 0306 void LibRaw::setCancelFlag() 0307 { 0308 #ifdef _MSC_VER 0309 InterlockedExchange(&_exitflag, 1); 0310 #else 0311 __sync_fetch_and_add(&_exitflag, 1); 0312 #endif 0313 #ifdef RAWSPEED_FASTEXIT 0314 if (_rawspeed_decoder) 0315 { 0316 RawSpeed::RawDecoder *d = 0317 static_cast<RawSpeed::RawDecoder *>(_rawspeed_decoder); 0318 d->cancelProcessing(); 0319 } 0320 #endif 0321 } 0322 0323 void LibRaw::checkCancel() 0324 { 0325 #ifdef _MSC_VER 0326 if (InterlockedExchange(&_exitflag, 0)) 0327 throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; 0328 #else 0329 if (__sync_fetch_and_and(&_exitflag, 0)) 0330 throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK; 0331 #endif 0332 } 0333 0334 int LibRaw::is_curve_linear() 0335 { 0336 for (int i = 0; i < 0x10000; i++) 0337 if (imgdata.color.curve[i] != i) 0338 return 0; 0339 return 1; 0340 } 0341 0342 void LibRaw::free_image(void) 0343 { 0344 if (imgdata.image) 0345 { 0346 free(imgdata.image); 0347 imgdata.image = 0; 0348 imgdata.progress_flags = LIBRAW_PROGRESS_START | LIBRAW_PROGRESS_OPEN | 0349 LIBRAW_PROGRESS_IDENTIFY | 0350 LIBRAW_PROGRESS_SIZE_ADJUST | 0351 LIBRAW_PROGRESS_LOAD_RAW; 0352 } 0353 } 0354 0355 int LibRaw::is_phaseone_compressed() 0356 { 0357 return (load_raw == &LibRaw::phase_one_load_raw_c || 0358 load_raw == &LibRaw::phase_one_load_raw_s || 0359 load_raw == &LibRaw::phase_one_load_raw); 0360 } 0361 0362 int LibRaw::is_canon_600() { return load_raw == &LibRaw::canon_600_load_raw; } 0363 const char *LibRaw::strprogress(enum LibRaw_progress p) 0364 { 0365 switch (p) 0366 { 0367 case LIBRAW_PROGRESS_START: 0368 return "Starting"; 0369 case LIBRAW_PROGRESS_OPEN: 0370 return "Opening file"; 0371 case LIBRAW_PROGRESS_IDENTIFY: 0372 return "Reading metadata"; 0373 case LIBRAW_PROGRESS_SIZE_ADJUST: 0374 return "Adjusting size"; 0375 case LIBRAW_PROGRESS_LOAD_RAW: 0376 return "Reading RAW data"; 0377 case LIBRAW_PROGRESS_REMOVE_ZEROES: 0378 return "Clearing zero values"; 0379 case LIBRAW_PROGRESS_BAD_PIXELS: 0380 return "Removing dead pixels"; 0381 case LIBRAW_PROGRESS_DARK_FRAME: 0382 return "Subtracting dark frame data"; 0383 case LIBRAW_PROGRESS_FOVEON_INTERPOLATE: 0384 return "Interpolating Foveon sensor data"; 0385 case LIBRAW_PROGRESS_SCALE_COLORS: 0386 return "Scaling colors"; 0387 case LIBRAW_PROGRESS_PRE_INTERPOLATE: 0388 return "Pre-interpolating"; 0389 case LIBRAW_PROGRESS_INTERPOLATE: 0390 return "Interpolating"; 0391 case LIBRAW_PROGRESS_MIX_GREEN: 0392 return "Mixing green channels"; 0393 case LIBRAW_PROGRESS_MEDIAN_FILTER: 0394 return "Median filter"; 0395 case LIBRAW_PROGRESS_HIGHLIGHTS: 0396 return "Highlight recovery"; 0397 case LIBRAW_PROGRESS_FUJI_ROTATE: 0398 return "Rotating Fuji diagonal data"; 0399 case LIBRAW_PROGRESS_FLIP: 0400 return "Flipping image"; 0401 case LIBRAW_PROGRESS_APPLY_PROFILE: 0402 return "ICC conversion"; 0403 case LIBRAW_PROGRESS_CONVERT_RGB: 0404 return "Converting to RGB"; 0405 case LIBRAW_PROGRESS_STRETCH: 0406 return "Stretching image"; 0407 case LIBRAW_PROGRESS_THUMB_LOAD: 0408 return "Loading thumbnail"; 0409 default: 0410 return "Some strange things"; 0411 } 0412 } 0413 int LibRaw::adjust_sizes_info_only(void) 0414 { 0415 CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY); 0416 0417 raw2image_start(); 0418 if (O.use_fuji_rotate) 0419 { 0420 if (IO.fuji_width) 0421 { 0422 IO.fuji_width = (IO.fuji_width - 1 + IO.shrink) >> IO.shrink; 0423 S.iwidth = (ushort)(IO.fuji_width / sqrt(0.5)); 0424 S.iheight = (ushort)((S.iheight - IO.fuji_width) / sqrt(0.5)); 0425 } 0426 else 0427 { 0428 if (S.pixel_aspect < 0.995) 0429 S.iheight = (ushort)(S.iheight / S.pixel_aspect + 0.5); 0430 if (S.pixel_aspect > 1.005) 0431 S.iwidth = (ushort)(S.iwidth * S.pixel_aspect + 0.5); 0432 } 0433 } 0434 SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE); 0435 if (S.flip & 4) 0436 { 0437 unsigned short t = S.iheight; 0438 S.iheight = S.iwidth; 0439 S.iwidth = t; 0440 SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP); 0441 } 0442 return 0; 0443 } 0444 int LibRaw::adjust_maximum() 0445 { 0446 ushort real_max; 0447 float auto_threshold; 0448 0449 if (O.adjust_maximum_thr < 0.00001) 0450 return LIBRAW_SUCCESS; 0451 else if (O.adjust_maximum_thr > 0.99999) 0452 auto_threshold = LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD; 0453 else 0454 auto_threshold = O.adjust_maximum_thr; 0455 0456 real_max = C.data_maximum; 0457 if (real_max > 0 && real_max < C.maximum && 0458 real_max > C.maximum * auto_threshold) 0459 { 0460 C.maximum = real_max; 0461 } 0462 return LIBRAW_SUCCESS; 0463 } 0464 void LibRaw::adjust_bl() 0465 { 0466 int clear_repeat = 0; 0467 if (O.user_black >= 0) 0468 { 0469 C.black = O.user_black; 0470 clear_repeat = 1; 0471 } 0472 for (int i = 0; i < 4; i++) 0473 if (O.user_cblack[i] > -1000000) 0474 { 0475 C.cblack[i] = O.user_cblack[i]; 0476 clear_repeat = 1; 0477 } 0478 0479 if (clear_repeat) 0480 C.cblack[4] = C.cblack[5] = 0; 0481 0482 // Add common part to cblack[] early 0483 if (imgdata.idata.filters > 1000 && (C.cblack[4] + 1) / 2 == 1 && 0484 (C.cblack[5] + 1) / 2 == 1) 0485 { 0486 int clrs[4]; 0487 int lastg = -1, gcnt = 0; 0488 for (int c = 0; c < 4; c++) 0489 { 0490 clrs[c] = FC(c / 2, c % 2); 0491 if (clrs[c] == 1) 0492 { 0493 gcnt++; 0494 lastg = c; 0495 } 0496 } 0497 if (gcnt > 1 && lastg >= 0) 0498 clrs[lastg] = 3; 0499 for (int c = 0; c < 4; c++) 0500 C.cblack[clrs[c]] += 0501 C.cblack[6 + c / 2 % C.cblack[4] * C.cblack[5] + c % 2 % C.cblack[5]]; 0502 C.cblack[4] = C.cblack[5] = 0; 0503 // imgdata.idata.filters = sfilters; 0504 } 0505 else if (imgdata.idata.filters <= 1000 && C.cblack[4] == 1 && 0506 C.cblack[5] == 1) // Fuji RAF dng 0507 { 0508 for (int c = 0; c < 4; c++) 0509 C.cblack[c] += C.cblack[6]; 0510 C.cblack[4] = C.cblack[5] = 0; 0511 } 0512 // remove common part from C.cblack[] 0513 int i = C.cblack[3]; 0514 int c; 0515 for (c = 0; c < 3; c++) 0516 if (i > (int)C.cblack[c]) 0517 i = C.cblack[c]; 0518 0519 for (c = 0; c < 4; c++) 0520 C.cblack[c] -= i; // remove common part 0521 C.black += i; 0522 0523 // Now calculate common part for cblack[6+] part and move it to C.black 0524 0525 if (C.cblack[4] && C.cblack[5]) 0526 { 0527 i = C.cblack[6]; 0528 for (c = 1; c < int(C.cblack[4] * C.cblack[5]); c++) 0529 if (i > int(C.cblack[6 + c])) 0530 i = C.cblack[6 + c]; 0531 // Remove i from cblack[6+] 0532 int nonz = 0; 0533 for (c = 0; c < int(C.cblack[4] * C.cblack[5]); c++) 0534 { 0535 C.cblack[6 + c] -= i; 0536 if (C.cblack[6 + c]) 0537 nonz++; 0538 } 0539 C.black += i; 0540 if (!nonz) 0541 C.cblack[4] = C.cblack[5] = 0; 0542 } 0543 for (c = 0; c < 4; c++) 0544 C.cblack[c] += C.black; 0545 } 0546 int LibRaw::getwords(char *line, char *words[], int maxwords, int maxlen) 0547 { 0548 line[maxlen - 1] = 0; 0549 unsigned char *p = (unsigned char*)line; 0550 int nwords = 0; 0551 0552 while (1) 0553 { 0554 while (isspace(*p)) 0555 p++; 0556 if (*p == '\0') 0557 return nwords; 0558 words[nwords++] = (char*)p; 0559 while (!isspace(*p) && *p != '\0') 0560 p++; 0561 if (*p == '\0') 0562 return nwords; 0563 *p++ = '\0'; 0564 if (nwords >= maxwords) 0565 return nwords; 0566 } 0567 } 0568 int LibRaw::stread(char *buf, size_t len, LibRaw_abstract_datastream *fp) 0569 { 0570 if (len > 0) 0571 { 0572 int r = fp->read(buf, len, 1); 0573 buf[len - 1] = 0; 0574 return r; 0575 } 0576 else 0577 return 0; 0578 } 0579 0580 int LibRaw::find_ifd_by_offset(int o) 0581 { 0582 for(unsigned i = 0; i < libraw_internal_data.identify_data.tiff_nifds && i < LIBRAW_IFD_MAXCOUNT; i++) 0583 if(tiff_ifd[i].offset == o) 0584 return i; 0585 return -1; 0586 } 0587 0588 short LibRaw::tiff_sget (unsigned save, uchar *buf, unsigned buf_len, INT64 *tag_offset, 0589 unsigned *tag_id, unsigned *tag_type, INT64 *tag_dataoffset, 0590 unsigned *tag_datalen, int *tag_dataunitlen) { 0591 uchar *pos = buf + *tag_offset; 0592 if ((((*tag_offset) + 12) > buf_len) || (*tag_offset < 0)) { // abnormal, tag buffer overrun 0593 return -1; 0594 } 0595 *tag_id = sget2(pos); pos += 2; 0596 *tag_type = sget2(pos); pos += 2; 0597 *tag_datalen = sget4(pos); pos += 4; 0598 *tag_dataunitlen = tagtype_dataunit_bytes[(*tag_type <= LIBRAW_EXIFTAG_TYPE_IFD8) ? *tag_type : 0]; 0599 if ((*tag_datalen * (*tag_dataunitlen)) > 4) { 0600 *tag_dataoffset = sget4(pos) - save; 0601 if ((*tag_dataoffset + *tag_datalen) > buf_len) { // abnormal, tag data buffer overrun 0602 return -2; 0603 } 0604 } else *tag_dataoffset = *tag_offset + 8; 0605 *tag_offset += 12; 0606 return 0; 0607 } 0608 0609 #define rICC imgdata.sizes.raw_inset_crops 0610 #define S imgdata.sizes 0611 #define RS imgdata.rawdata.sizes 0612 int LibRaw::adjust_to_raw_inset_crop(unsigned mask, float maxcrop) 0613 0614 { 0615 int adjindex = -1; 0616 int limwidth = S.width * maxcrop; 0617 int limheight = S.height * maxcrop; 0618 0619 for(int i = 1; i >= 0; i--) 0620 if (mask & (1<<i)) 0621 if (rICC[i].ctop < 0xffff && rICC[i].cleft < 0xffff 0622 && rICC[i].cleft + rICC[i].cwidth <= S.raw_width 0623 && rICC[i].ctop + rICC[i].cheight <= S.raw_height 0624 && rICC[i].cwidth >= limwidth && rICC[i].cheight >= limheight) 0625 { 0626 adjindex = i; 0627 break; 0628 } 0629 0630 if (adjindex >= 0) 0631 { 0632 RS.left_margin = S.left_margin = rICC[adjindex].cleft; 0633 RS.top_margin = S.top_margin = rICC[adjindex].ctop; 0634 RS.width = S.width = MIN(rICC[adjindex].cwidth, int(S.raw_width) - int(S.left_margin)); 0635 RS.height = S.height = MIN(rICC[adjindex].cheight, int(S.raw_height) - int(S.top_margin)); 0636 } 0637 return adjindex + 1; 0638 } 0639 0640 char** LibRaw::malloc_omp_buffers(int buffer_count, size_t buffer_size) 0641 { 0642 char** buffers = (char**)calloc(sizeof(char*), buffer_count); 0643 0644 for (int i = 0; i < buffer_count; i++) 0645 { 0646 buffers[i] = (char*)malloc(buffer_size); 0647 } 0648 return buffers; 0649 } 0650 0651 void LibRaw::free_omp_buffers(char** buffers, int buffer_count) 0652 { 0653 for (int i = 0; i < buffer_count; i++) 0654 if(buffers[i]) 0655 free(buffers[i]); 0656 free(buffers); 0657 } 0658 0659 void LibRaw::libraw_swab(void *arr, size_t len) 0660 { 0661 #ifdef LIBRAW_OWN_SWAB 0662 uint16_t *array = (uint16_t*)arr; 0663 size_t bytes = len/2; 0664 for(; bytes; --bytes) 0665 { 0666 *array = ((*array << 8) & 0xff00) | ((*array >> 8) & 0xff); 0667 array++; 0668 } 0669 #else 0670 swab((char*)arr,(char*)arr,len); 0671 #endif 0672 0673 }