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 }