PageRenderTime 326ms CodeModel.GetById 2ms app.highlight 204ms RepoModel.GetById 1ms app.codeStats 1ms

/src/FreeImage/Source/LibRawLite/src/libraw_cxx.cpp

https://bitbucket.org/cabalistic/ogredeps/
C++ | 2789 lines | 2394 code | 297 blank | 98 comment | 519 complexity | b4e1584f4136f83772c17d3d5c8a25df MD5 | raw file
   1/* -*- C++ -*-
   2 * File: libraw_cxx.cpp
   3 * Copyright 2008-2010 LibRaw LLC (info@libraw.org)
   4 * Created: Sat Mar  8 , 2008
   5 *
   6 * LibRaw C++ interface (implementation)
   7
   8LibRaw is free software; you can redistribute it and/or modify
   9it under the terms of the one of three licenses as you choose:
  10
  111. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
  12   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
  13
  142. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
  15   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
  16
  173. LibRaw Software License 27032010
  18   (See file LICENSE.LibRaw.pdf provided in LibRaw distribution archive for details).
  19
  20 */
  21
  22#include <math.h>
  23#include <errno.h>
  24#include <float.h>
  25#include <new>
  26#include <sys/types.h>
  27#include <sys/stat.h>
  28#ifndef WIN32
  29#include <netinet/in.h>
  30#else
  31#include <winsock2.h>
  32#endif
  33#define LIBRAW_LIBRARY_BUILD
  34#include "libraw/libraw.h"
  35#include "internal/defines.h"
  36
  37#ifdef __cplusplus
  38extern "C" 
  39{
  40#endif
  41    void default_memory_callback(void *,const char *file,const char *where)
  42    {
  43        fprintf (stderr,"%s: Out of memory in %s\n", file?file:"unknown file", where);
  44    }
  45
  46    void default_data_callback(void*,const char *file, const int offset)
  47    {
  48        if(offset < 0)
  49            fprintf (stderr,"%s: Unexpected end of file\n", file?file:"unknown file");
  50        else
  51            fprintf (stderr,"%s: data corrupted at %d\n",file?file:"unknown file",offset); 
  52    }
  53    const char *libraw_strerror(int e)
  54    {
  55        enum LibRaw_errors errorcode = (LibRaw_errors)e;
  56        switch(errorcode)
  57            {
  58            case        LIBRAW_SUCCESS:
  59                return "No error";
  60            case        LIBRAW_UNSPECIFIED_ERROR:
  61                return "Unspecified error";
  62            case        LIBRAW_FILE_UNSUPPORTED:
  63                return "Unsupported file format or not RAW file";
  64            case        LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE:
  65                return "Request for nonexisting image number";
  66            case        LIBRAW_OUT_OF_ORDER_CALL:
  67                return "Out of order call of libraw function";
  68            case    LIBRAW_NO_THUMBNAIL:
  69                return "No thumbnail in file";
  70            case    LIBRAW_UNSUPPORTED_THUMBNAIL:
  71                return "Unsupported thumbnail format";
  72            case    LIBRAW_UNSUFFICIENT_MEMORY:
  73                return "Unsufficient memory";
  74            case    LIBRAW_DATA_ERROR:
  75                return "Corrupted data or unexpected EOF";
  76            case    LIBRAW_IO_ERROR:
  77                return "Input/output error";
  78            case LIBRAW_CANCELLED_BY_CALLBACK:
  79                return "Cancelled by user callback";
  80            case LIBRAW_BAD_CROP:
  81                return "Bad crop box";
  82            default:
  83                return "Unknown error code";
  84        }
  85    }
  86
  87#ifdef __cplusplus
  88}
  89#endif
  90
  91
  92const double LibRaw_constants::xyz_rgb[3][3] = 
  93{
  94    { 0.412453, 0.357580, 0.180423 },
  95    { 0.212671, 0.715160, 0.072169 },
  96    { 0.019334, 0.119193, 0.950227 } 
  97};
  98
  99const float LibRaw_constants::d65_white[3] =  { 0.950456f, 1.0f, 1.088754f };
 100
 101#define P1 imgdata.idata
 102#define S imgdata.sizes
 103#define O imgdata.params
 104#define C imgdata.color
 105#define T imgdata.thumbnail
 106#define IO libraw_internal_data.internal_output_params
 107#define ID libraw_internal_data.internal_data
 108
 109#define EXCEPTION_HANDLER(e) do{                        \
 110        /* fprintf(stderr,"Exception %d caught\n",e);*/ \
 111        switch(e)                                       \
 112            {                                           \
 113            case LIBRAW_EXCEPTION_ALLOC:                \
 114                recycle();                              \
 115                return LIBRAW_UNSUFFICIENT_MEMORY;      \
 116            case LIBRAW_EXCEPTION_DECODE_RAW:           \
 117            case LIBRAW_EXCEPTION_DECODE_JPEG:          \
 118                recycle();                              \
 119                return LIBRAW_DATA_ERROR;               \
 120            case LIBRAW_EXCEPTION_DECODE_JPEG2000:      \
 121                recycle();                              \
 122                return LIBRAW_DATA_ERROR;               \
 123            case LIBRAW_EXCEPTION_IO_EOF:               \
 124            case LIBRAW_EXCEPTION_IO_CORRUPT:           \
 125                recycle();                              \
 126                return LIBRAW_IO_ERROR;                 \
 127            case LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK:\
 128                recycle();                              \
 129                return LIBRAW_CANCELLED_BY_CALLBACK;    \
 130            case LIBRAW_EXCEPTION_BAD_CROP:             \
 131                recycle();                              \
 132                return LIBRAW_BAD_CROP;                 \
 133            default:                                    \
 134                return LIBRAW_UNSPECIFIED_ERROR;        \
 135            } \
 136    }while(0)
 137
 138const char* LibRaw::version() { return LIBRAW_VERSION_STR;}
 139int LibRaw::versionNumber() { return LIBRAW_VERSION; }
 140const char* LibRaw::strerror(int p) { return libraw_strerror(p);}
 141
 142
 143void LibRaw::derror()
 144{
 145    if (!libraw_internal_data.unpacker_data.data_error && libraw_internal_data.internal_data.input) 
 146        {
 147            if (libraw_internal_data.internal_data.input->eof())
 148                {
 149                    if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
 150                                                              libraw_internal_data.internal_data.input->fname(),-1);
 151                    throw LIBRAW_EXCEPTION_IO_EOF;
 152                }
 153            else
 154                {
 155                    if(callbacks.data_cb)(*callbacks.data_cb)(callbacks.datacb_data,
 156                                                              libraw_internal_data.internal_data.input->fname(),
 157                                                              libraw_internal_data.internal_data.input->tell());
 158                    throw LIBRAW_EXCEPTION_IO_CORRUPT;
 159                }
 160        }
 161    libraw_internal_data.unpacker_data.data_error++;
 162}
 163
 164void LibRaw::dcraw_clear_mem(libraw_processed_image_t* p)
 165{
 166    if(p) ::free(p);
 167}
 168
 169#define ZERO(a) memset(&a,0,sizeof(a))
 170
 171
 172LibRaw:: LibRaw(unsigned int flags)
 173{
 174    double aber[4] = {1,1,1,1};
 175    double gamm[6] = { 0.45,4.5,0,0,0,0 };
 176    unsigned greybox[4] =  { 0, 0, UINT_MAX, UINT_MAX };
 177    unsigned cropbox[4] =  { 0, 0, UINT_MAX, UINT_MAX };
 178#ifdef DCRAW_VERBOSE
 179    verbose = 1;
 180#else
 181    verbose = 0;
 182#endif
 183    ZERO(imgdata);
 184    ZERO(libraw_internal_data);
 185    ZERO(callbacks);
 186    callbacks.mem_cb = (flags & LIBRAW_OPIONS_NO_MEMERR_CALLBACK) ? NULL:  &default_memory_callback;
 187    callbacks.data_cb = (flags & LIBRAW_OPIONS_NO_DATAERR_CALLBACK)? NULL : &default_data_callback;
 188    memmove(&imgdata.params.aber,&aber,sizeof(aber));
 189    memmove(&imgdata.params.gamm,&gamm,sizeof(gamm));
 190    memmove(&imgdata.params.greybox,&greybox,sizeof(greybox));
 191    memmove(&imgdata.params.cropbox,&cropbox,sizeof(cropbox));
 192    
 193    imgdata.params.bright=1;
 194    imgdata.params.use_camera_matrix=-1;
 195    imgdata.params.user_flip=-1;
 196    imgdata.params.user_black=-1;
 197    imgdata.params.user_sat=-1;
 198    imgdata.params.user_qual=-1;
 199    imgdata.params.output_color=1;
 200    imgdata.params.output_bps=8;
 201    imgdata.params.use_fuji_rotate=1;
 202    imgdata.params.exp_shift = 1.0;
 203    imgdata.params.auto_bright_thr = LIBRAW_DEFAULT_AUTO_BRIGHTNESS_THRESHOLD;
 204    imgdata.params.adjust_maximum_thr= LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD;
 205    imgdata.params.green_matching = 0;
 206    imgdata.parent_class = this;
 207    imgdata.progress_flags = 0;
 208    tls = new LibRaw_TLS;
 209    tls->init();
 210}
 211
 212
 213void* LibRaw:: malloc(size_t t)
 214{
 215    void *p = memmgr.malloc(t);
 216    return p;
 217}
 218void* LibRaw:: realloc(void *q,size_t t)
 219{
 220    void *p = memmgr.realloc(q,t);
 221    return p;
 222}
 223
 224
 225void* LibRaw::       calloc(size_t n,size_t t)
 226{
 227    void *p = memmgr.calloc(n,t);
 228    return p;
 229}
 230void  LibRaw::      free(void *p)
 231{
 232    memmgr.free(p);
 233}
 234
 235
 236int LibRaw:: fc (int row, int col)
 237{
 238    static const char filter[16][16] =
 239        { { 2,1,1,3,2,3,2,0,3,2,3,0,1,2,1,0 },
 240          { 0,3,0,2,0,1,3,1,0,1,1,2,0,3,3,2 },
 241          { 2,3,3,2,3,1,1,3,3,1,2,1,2,0,0,3 },
 242          { 0,1,0,1,0,2,0,2,2,0,3,0,1,3,2,1 },
 243          { 3,1,1,2,0,1,0,2,1,3,1,3,0,1,3,0 },
 244          { 2,0,0,3,3,2,3,1,2,0,2,0,3,2,2,1 },
 245          { 2,3,3,1,2,1,2,1,2,1,1,2,3,0,0,1 },
 246          { 1,0,0,2,3,0,0,3,0,3,0,3,2,1,2,3 },
 247          { 2,3,3,1,1,2,1,0,3,2,3,0,2,3,1,3 },
 248          { 1,0,2,0,3,0,3,2,0,1,1,2,0,1,0,2 },
 249          { 0,1,1,3,3,2,2,1,1,3,3,0,2,1,3,2 },
 250          { 2,3,2,0,0,1,3,0,2,0,1,2,3,0,1,0 },
 251          { 1,3,1,2,3,2,3,2,0,2,0,1,1,0,3,0 },
 252          { 0,2,0,3,1,0,0,1,1,3,3,2,3,2,2,1 },
 253          { 2,1,3,2,3,1,2,1,0,3,0,2,0,2,0,2 },
 254          { 0,3,1,0,0,2,0,3,2,1,3,1,1,3,1,3 } };
 255    
 256    if (imgdata.idata.filters != 1) return FC(row,col);
 257    return filter[(row+imgdata.sizes.top_margin) & 15][(col+imgdata.sizes.left_margin) & 15];
 258}
 259
 260void LibRaw:: recycle() 
 261{
 262    if(libraw_internal_data.internal_data.input && libraw_internal_data.internal_data.input_internal) 
 263        { 
 264            delete libraw_internal_data.internal_data.input; 
 265            libraw_internal_data.internal_data.input = NULL;
 266        }
 267    libraw_internal_data.internal_data.input_internal = 0;
 268#define FREE(a) do { if(a) { free(a); a = NULL;} }while(0)
 269            
 270    FREE(imgdata.image); 
 271    FREE(imgdata.thumbnail.thumb);
 272    FREE(libraw_internal_data.internal_data.meta_data);
 273    FREE(libraw_internal_data.output_data.histogram);
 274    FREE(libraw_internal_data.output_data.oprof);
 275    FREE(imgdata.color.profile);
 276    FREE(imgdata.rawdata.ph1_black);
 277    FREE(imgdata.rawdata.raw_alloc); 
 278#undef FREE
 279    ZERO(imgdata.rawdata);
 280    ZERO(imgdata.sizes);
 281    ZERO(imgdata.color);
 282    ZERO(libraw_internal_data);
 283    memmgr.cleanup();
 284    imgdata.thumbnail.tformat = LIBRAW_THUMBNAIL_UNKNOWN;
 285    imgdata.progress_flags = 0;
 286    
 287    tls->init();
 288}
 289
 290const char * LibRaw::unpack_function_name()
 291{
 292    libraw_decoder_info_t decoder_info;
 293    get_decoder_info(&decoder_info);
 294    return decoder_info.decoder_name;
 295}
 296
 297int LibRaw::get_decoder_info(libraw_decoder_info_t* d_info)
 298{
 299    if(!d_info)   return LIBRAW_UNSPECIFIED_ERROR;
 300    if(!load_raw) return LIBRAW_OUT_OF_ORDER_CALL;
 301    
 302    d_info->decoder_flags = LIBRAW_DECODER_NOTSET;
 303
 304    // sorted names order
 305    if (load_raw == &LibRaw::adobe_dng_load_raw_lj) 
 306        {
 307            // Check rbayer
 308            d_info->decoder_name = "adobe_dng_load_raw_lj()"; 
 309            d_info->decoder_flags = imgdata.idata.filters ? LIBRAW_DECODER_FLATFIELD : LIBRAW_DECODER_4COMPONENT ;
 310            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
 311        }
 312    else if (load_raw == &LibRaw::adobe_dng_load_raw_nc)
 313        {
 314            // Check rbayer
 315            d_info->decoder_name = "adobe_dng_load_raw_nc()"; 
 316            d_info->decoder_flags = imgdata.idata.filters ? LIBRAW_DECODER_FLATFIELD : LIBRAW_DECODER_4COMPONENT;
 317            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
 318        }
 319    else if (load_raw == &LibRaw::canon_600_load_raw) 
 320        {
 321            d_info->decoder_name = "canon_600_load_raw()";   
 322            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD; // WB set within decoder, no need to load raw
 323        }
 324    else if (load_raw == &LibRaw::canon_compressed_load_raw)
 325        {
 326            d_info->decoder_name = "canon_compressed_load_raw()"; 
 327            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 328        }
 329    else if (load_raw == &LibRaw::canon_sraw_load_raw) 
 330        {
 331            d_info->decoder_name = "canon_sraw_load_raw()";
 332            d_info->decoder_flags = LIBRAW_DECODER_LEGACY; 
 333        }
 334    else if (load_raw == &LibRaw::eight_bit_load_raw )
 335        {
 336            d_info->decoder_name = "eight_bit_load_raw()";
 337            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 338            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
 339        }
 340    else if (load_raw == &LibRaw::foveon_load_raw )
 341        {
 342            d_info->decoder_name = "foveon_load_raw()";
 343            d_info->decoder_flags = LIBRAW_DECODER_LEGACY; 
 344        }
 345    else if (load_raw == &LibRaw::fuji_load_raw ) 
 346        { 
 347            d_info->decoder_name = "fuji_load_raw()"; 
 348            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 349        }
 350    else if (load_raw == &LibRaw::hasselblad_load_raw )
 351        {
 352            d_info->decoder_name = "hasselblad_load_raw()"; 
 353            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 354        }
 355    else if (load_raw == &LibRaw::imacon_full_load_raw )
 356        {
 357            d_info->decoder_name = "imacon_full_load_raw()"; 
 358            d_info->decoder_flags = LIBRAW_DECODER_4COMPONENT; 
 359        }
 360    else if (load_raw == &LibRaw::kodak_262_load_raw )
 361        {
 362            d_info->decoder_name = "kodak_262_load_raw()"; // UNTESTED!
 363            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 364            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
 365        }
 366    else if (load_raw == &LibRaw::kodak_65000_load_raw )
 367        {
 368            d_info->decoder_name = "kodak_65000_load_raw()";
 369            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 370            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
 371        }
 372    else if (load_raw == &LibRaw::kodak_dc120_load_raw )
 373        {
 374            d_info->decoder_name = "kodak_dc120_load_raw()"; 
 375            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 376        }
 377    else if (load_raw == &LibRaw::kodak_jpeg_load_raw )
 378        {
 379            // UNTESTED + RBAYER
 380            d_info->decoder_name = "kodak_jpeg_load_raw()"; 
 381            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 382        }
 383    else if (load_raw == &LibRaw::kodak_radc_load_raw )
 384        {
 385            d_info->decoder_name = "kodak_radc_load_raw()"; 
 386            d_info->decoder_flags = LIBRAW_DECODER_4COMPONENT;
 387        }
 388    else if (load_raw == &LibRaw::kodak_rgb_load_raw ) 
 389        {
 390            // UNTESTED
 391            d_info->decoder_name = "kodak_rgb_load_raw()"; 
 392            d_info->decoder_flags = LIBRAW_DECODER_4COMPONENT;
 393        }
 394    else if (load_raw == &LibRaw::kodak_yrgb_load_raw )    
 395        {
 396            d_info->decoder_name = "kodak_yrgb_load_raw()"; 
 397            d_info->decoder_flags = LIBRAW_DECODER_4COMPONENT;
 398            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
 399        }
 400    else if (load_raw == &LibRaw::kodak_ycbcr_load_raw )
 401        {
 402            // UNTESTED
 403            d_info->decoder_name = "kodak_ycbcr_load_raw()"; 
 404            d_info->decoder_flags = LIBRAW_DECODER_4COMPONENT;
 405            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
 406        }
 407    else if (load_raw == &LibRaw::leaf_hdr_load_raw )
 408        {
 409            d_info->decoder_name = "leaf_hdr_load_raw()"; 
 410            d_info->decoder_flags = imgdata.idata.filters ? LIBRAW_DECODER_FLATFIELD : LIBRAW_DECODER_4COMPONENT;
 411        }
 412    else if (load_raw == &LibRaw::lossless_jpeg_load_raw)
 413        {
 414            // Check rbayer
 415            d_info->decoder_name = "lossless_jpeg_load_raw()"; 
 416            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD | LIBRAW_DECODER_HASCURVE;
 417        }
 418    else if (load_raw == &LibRaw::minolta_rd175_load_raw ) 
 419        {  
 420            // UNTESTED
 421            d_info->decoder_name = "minolta_rd175_load_raw()"; 
 422            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 423        }
 424    else if (load_raw == &LibRaw::nikon_compressed_load_raw)
 425        {
 426            // Check rbayer
 427            d_info->decoder_name = "nikon_compressed_load_raw()";
 428            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 429        }
 430    else if (load_raw == &LibRaw::nokia_load_raw )
 431        {
 432            // UNTESTED
 433            d_info->decoder_name = "nokia_load_raw()";
 434            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 435        }
 436    else if (load_raw == &LibRaw::olympus_load_raw )
 437        {
 438            d_info->decoder_name = "olympus_load_raw()"; 
 439            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 440        }
 441    else if (load_raw == &LibRaw::packed_load_raw )
 442        {
 443            d_info->decoder_name = "packed_load_raw()";
 444            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 445        }
 446    else if (load_raw == &LibRaw::panasonic_load_raw )
 447        {
 448            d_info->decoder_name = "panasonic_load_raw()";
 449            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 450        }
 451    else if (load_raw == &LibRaw::pentax_load_raw )
 452        {
 453            d_info->decoder_name = "pentax_load_raw()"; 
 454            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 455        }
 456    else if (load_raw == &LibRaw::phase_one_load_raw )
 457        {
 458            d_info->decoder_name = "phase_one_load_raw()"; 
 459            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 460        }
 461    else if (load_raw == &LibRaw::phase_one_load_raw_c )
 462        {
 463            d_info->decoder_name = "phase_one_load_raw_c()"; 
 464            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 465        }
 466    else if (load_raw == &LibRaw::quicktake_100_load_raw )
 467        {
 468            // UNTESTED
 469            d_info->decoder_name = "quicktake_100_load_raw()";
 470            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 471        }
 472    else if (load_raw == &LibRaw::rollei_load_raw )
 473        {
 474            // UNTESTED
 475            d_info->decoder_name = "rollei_load_raw()"; 
 476            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 477        }
 478    else if (load_raw == &LibRaw::sinar_4shot_load_raw )
 479        {
 480            // UNTESTED
 481            d_info->decoder_name = "sinar_4shot_load_raw()";
 482            d_info->decoder_flags = LIBRAW_DECODER_4COMPONENT;
 483        }
 484    else if (load_raw == &LibRaw::smal_v6_load_raw )
 485        {
 486            // UNTESTED
 487            d_info->decoder_name = "smal_v6_load_raw()";
 488            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 489        }
 490    else if (load_raw == &LibRaw::smal_v9_load_raw )
 491        {
 492            // UNTESTED
 493            d_info->decoder_name = "smal_v9_load_raw()";
 494            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 495        }
 496    else if (load_raw == &LibRaw::sony_load_raw )
 497        {
 498            d_info->decoder_name = "sony_load_raw()"; 
 499            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 500        }
 501    else if (load_raw == &LibRaw::sony_arw_load_raw )
 502        {
 503            d_info->decoder_name = "sony_arw_load_raw()";
 504            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 505        }
 506    else if (load_raw == &LibRaw::sony_arw2_load_raw )
 507        {
 508            d_info->decoder_name = "sony_arw2_load_raw()";
 509            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD;
 510            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
 511        }
 512    else if (load_raw == &LibRaw::unpacked_load_raw )
 513        {
 514            d_info->decoder_name = "unpacked_load_raw()"; 
 515            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD | LIBRAW_DECODER_USEBAYER2;
 516        }
 517    else  if (load_raw == &LibRaw::redcine_load_raw)
 518        {
 519            d_info->decoder_name = "redcine_load_raw()";
 520            d_info->decoder_flags = LIBRAW_DECODER_FLATFIELD; 
 521            d_info->decoder_flags |= LIBRAW_DECODER_HASCURVE;
 522        }
 523    else
 524        {
 525            d_info->decoder_name = "Unknown unpack function";
 526            d_info->decoder_flags = LIBRAW_DECODER_NOTSET;
 527        }
 528    return LIBRAW_SUCCESS;
 529}
 530
 531int LibRaw::adjust_maximum()
 532{
 533    int i;
 534    ushort real_max;
 535    float  auto_threshold;
 536
 537    if(O.adjust_maximum_thr < 0.00001)
 538        return LIBRAW_SUCCESS;
 539    else if (O.adjust_maximum_thr > 0.99999)
 540        auto_threshold = LIBRAW_DEFAULT_ADJUST_MAXIMUM_THRESHOLD;
 541    else
 542        auto_threshold = O.adjust_maximum_thr;
 543        
 544    
 545    real_max = C.channel_maximum[0];
 546    for(i = 1; i< 4; i++)
 547        if(real_max < C.channel_maximum[i])
 548            real_max = C.channel_maximum[i];
 549
 550    if (real_max > 0 && real_max < C.maximum && real_max > C.maximum* auto_threshold)
 551        {
 552            C.maximum = real_max;
 553        }
 554    return LIBRAW_SUCCESS;
 555}
 556
 557
 558void LibRaw:: merror (void *ptr, const char *where)
 559{
 560    if (ptr) return;
 561    if(callbacks.mem_cb)(*callbacks.mem_cb)(callbacks.memcb_data,
 562                                            libraw_internal_data.internal_data.input
 563                                            ?libraw_internal_data.internal_data.input->fname()
 564                                            :NULL,
 565                                            where);
 566    throw LIBRAW_EXCEPTION_ALLOC;
 567}
 568
 569
 570
 571int LibRaw::open_file(const char *fname, INT64 max_buf_size)
 572{
 573#ifndef WIN32
 574    struct stat st;
 575    if(stat(fname,&st))
 576        return LIBRAW_IO_ERROR;
 577    int big = (st.st_size > max_buf_size)?1:0;
 578#else
 579	struct _stati64 st;
 580    if(_stati64(fname,&st))	
 581        return LIBRAW_IO_ERROR;
 582    int big = (st.st_size > max_buf_size)?1:0;
 583#endif
 584
 585    LibRaw_abstract_datastream *stream;
 586    try {
 587        if(big)
 588         stream = new LibRaw_bigfile_datastream(fname);
 589        else
 590         stream = new LibRaw_file_datastream(fname);
 591    }
 592
 593    catch (std::bad_alloc)
 594        {
 595            recycle();
 596            return LIBRAW_UNSUFFICIENT_MEMORY;
 597        }
 598    if(!stream->valid())
 599        {
 600            delete stream;
 601            return LIBRAW_IO_ERROR;
 602        }
 603    ID.input_internal = 0; // preserve from deletion on error
 604    int ret = open_datastream(stream);
 605    if (ret == LIBRAW_SUCCESS)
 606        {
 607            ID.input_internal =1 ; // flag to delete datastream on recycle
 608        }
 609    else
 610        {
 611            delete stream;
 612            ID.input_internal = 0;
 613        }
 614    return ret;
 615}
 616
 617int LibRaw::open_buffer(void *buffer, size_t size)
 618{
 619    // this stream will close on recycle()
 620    if(!buffer  || buffer==(void*)-1)
 621        return LIBRAW_IO_ERROR;
 622
 623    LibRaw_buffer_datastream *stream;
 624    try {
 625        stream = new LibRaw_buffer_datastream(buffer,size);
 626    }
 627    catch (std::bad_alloc)
 628        {
 629            recycle();
 630            return LIBRAW_UNSUFFICIENT_MEMORY;
 631        }
 632    if(!stream->valid())
 633        {
 634            delete stream;
 635            return LIBRAW_IO_ERROR;
 636        }
 637    ID.input_internal = 0; // preserve from deletion on error
 638    int ret = open_datastream(stream);
 639    if (ret == LIBRAW_SUCCESS)
 640        {
 641            ID.input_internal =1 ; // flag to delete datastream on recycle
 642        }
 643    else
 644        {
 645            delete stream;
 646            ID.input_internal = 0;
 647        }
 648    return ret;
 649}
 650
 651
 652int LibRaw::open_datastream(LibRaw_abstract_datastream *stream)
 653{
 654
 655    if(!stream)
 656        return ENOENT;
 657    if(!stream->valid())
 658        return LIBRAW_IO_ERROR;
 659    recycle();
 660
 661    try {
 662        ID.input = stream;
 663        SET_PROC_FLAG(LIBRAW_PROGRESS_OPEN);
 664
 665        if (O.use_camera_matrix < 0)
 666            O.use_camera_matrix = O.use_camera_wb;
 667
 668        identify();
 669
 670        if(IO.fuji_width)
 671            {
 672                IO.fwidth = S.width;
 673                IO.fheight = S.height;
 674                S.iwidth = S.width = IO.fuji_width << (int)(!libraw_internal_data.unpacker_data.fuji_layout);
 675                S.iheight = S.height = S.raw_height;
 676                S.raw_height += 2*S.top_margin;
 677            }
 678
 679        if(C.profile_length)
 680            {
 681                if(C.profile) free(C.profile);
 682                C.profile = malloc(C.profile_length);
 683                merror(C.profile,"LibRaw::open_file()");
 684                ID.input->seek(ID.profile_offset,SEEK_SET);
 685                ID.input->read(C.profile,C.profile_length,1);
 686            }
 687        
 688        SET_PROC_FLAG(LIBRAW_PROGRESS_IDENTIFY);
 689    }
 690    catch ( LibRaw_exceptions err) {
 691        EXCEPTION_HANDLER(err);
 692    }
 693
 694    if(P1.raw_count < 1) 
 695        return LIBRAW_FILE_UNSUPPORTED;
 696
 697    
 698    write_fun = &LibRaw::write_ppm_tiff;
 699    
 700    if (load_raw == &LibRaw::kodak_ycbcr_load_raw) 
 701        {
 702            S.height += S.height & 1;
 703            S.width  += S.width  & 1;
 704        }
 705
 706    IO.shrink = P1.filters && (O.half_size ||
 707	((O.threshold || O.aber[0] != 1 || O.aber[2] != 1) ));
 708
 709    S.iheight = (S.height + IO.shrink) >> IO.shrink;
 710    S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
 711
 712    // Save color,sizes and internal data into raw_image fields
 713    memmove(&imgdata.rawdata.color,&imgdata.color,sizeof(imgdata.color));
 714    memmove(&imgdata.rawdata.sizes,&imgdata.sizes,sizeof(imgdata.sizes));
 715    memmove(&imgdata.rawdata.iparams,&imgdata.idata,sizeof(imgdata.idata));
 716    memmove(&imgdata.rawdata.ioparams,&libraw_internal_data.internal_output_params,sizeof(libraw_internal_data.internal_output_params));
 717    
 718    SET_PROC_FLAG(LIBRAW_PROGRESS_SIZE_ADJUST);
 719
 720
 721    return LIBRAW_SUCCESS;
 722}
 723
 724int LibRaw::unpack(void)
 725{
 726    CHECK_ORDER_HIGH(LIBRAW_PROGRESS_LOAD_RAW);
 727    CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
 728    try {
 729
 730        RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,0,2);
 731        if (O.shot_select >= P1.raw_count)
 732            return LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE;
 733        
 734        if(!load_raw)
 735            return LIBRAW_UNSPECIFIED_ERROR;
 736        
 737        if (O.use_camera_matrix && C.cmatrix[0][0] > 0.25) 
 738            {
 739                memcpy (C.rgb_cam, C.cmatrix, sizeof (C.cmatrix));
 740                IO.raw_color = 0;
 741            }
 742        // already allocated ?
 743        if(imgdata.image)
 744            {
 745                free(imgdata.image);
 746                imgdata.image = 0;
 747            }
 748
 749        if (libraw_internal_data.unpacker_data.meta_length) 
 750            {
 751                libraw_internal_data.internal_data.meta_data = 
 752                    (char *) malloc (libraw_internal_data.unpacker_data.meta_length);
 753                merror (libraw_internal_data.internal_data.meta_data, "LibRaw::unpack()");
 754            }
 755        ID.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET);
 756        int save_document_mode = O.document_mode;
 757        O.document_mode = 0;
 758
 759        libraw_decoder_info_t decoder_info;
 760        get_decoder_info(&decoder_info);
 761
 762        int save_iwidth = S.iwidth, save_iheight = S.iheight, save_shrink = IO.shrink;
 763
 764        int rwidth = S.raw_width, rheight = S.raw_height;
 765        if( !IO.fuji_width)
 766            {
 767                // adjust non-Fuji allocation
 768                if(rwidth < S.width + S.left_margin)
 769                    rwidth = S.width + S.left_margin;
 770                if(rheight < S.height + S.top_margin)
 771                    rheight = S.height + S.top_margin;
 772            }
 773        
 774        if(decoder_info.decoder_flags &  LIBRAW_DECODER_FLATFIELD)
 775            {
 776                imgdata.rawdata.raw_alloc = malloc(rwidth*rheight*sizeof(imgdata.rawdata.raw_image[0]));
 777                imgdata.rawdata.raw_image = (ushort*) imgdata.rawdata.raw_alloc;
 778            }
 779        else if (decoder_info.decoder_flags &  LIBRAW_DECODER_4COMPONENT)
 780            {
 781                S.iwidth = S.width;
 782                S.iheight= S.height;
 783                IO.shrink = 0;
 784                imgdata.rawdata.raw_alloc = calloc(rwidth*rheight,sizeof(*imgdata.rawdata.color_image));
 785                imgdata.rawdata.color_image = (ushort(*)[4]) imgdata.rawdata.raw_alloc;
 786            }
 787        else if (decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
 788            {
 789                // sRAW and Foveon only, so extra buffer size is just 1/4
 790                // Legacy converters does not supports half mode!
 791                S.iwidth = S.width;
 792                S.iheight= S.height;
 793                IO.shrink = 0;
 794                // allocate image as temporary buffer, size 
 795                imgdata.rawdata.raw_alloc = calloc(S.iwidth*S.iheight,sizeof(*imgdata.image));
 796                imgdata.image = (ushort (*)[4]) imgdata.rawdata.raw_alloc;
 797            }
 798
 799
 800        (this->*load_raw)();
 801
 802
 803        // recover saved
 804        if( decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
 805            {
 806                imgdata.image = 0; 
 807                imgdata.rawdata.color_image = (ushort (*)[4]) imgdata.rawdata.raw_alloc;
 808            }
 809
 810        // calculate channel maximum
 811        {
 812            for(int c=0;c<4;c++) C.channel_maximum[c] = 0;
 813            if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
 814                {
 815                    for(int rc = 0; rc < S.iwidth*S.iheight; rc++)
 816                        {
 817                            if(C.channel_maximum[0]<imgdata.rawdata.color_image[rc][0]) 
 818                                C.channel_maximum[0]=imgdata.rawdata.color_image[rc][0];
 819                            if(C.channel_maximum[1]<imgdata.rawdata.color_image[rc][1]) 
 820                                C.channel_maximum[1]=imgdata.rawdata.color_image[rc][1];
 821                            if(C.channel_maximum[2]<imgdata.rawdata.color_image[rc][2]) 
 822                                C.channel_maximum[2]=imgdata.rawdata.color_image[rc][2];
 823                            if(C.channel_maximum[3]<imgdata.rawdata.color_image[rc][3]) 
 824                                C.channel_maximum[3]=imgdata.rawdata.color_image[rc][3];
 825                        }
 826                }
 827            else if(decoder_info.decoder_flags &  LIBRAW_DECODER_4COMPONENT)
 828                {
 829                    for(int row = S.top_margin; row < S.height+S.top_margin; row++)
 830                        for(int col = S.left_margin; col < S.width+S.left_margin; col++)
 831                        {
 832                            int rc = row*S.raw_width+col;
 833                            if(C.channel_maximum[0]<imgdata.rawdata.color_image[rc][0]) 
 834                                C.channel_maximum[0]=imgdata.rawdata.color_image[rc][0];
 835                            if(C.channel_maximum[1]<imgdata.rawdata.color_image[rc][1]) 
 836                                C.channel_maximum[1]=imgdata.rawdata.color_image[rc][1];
 837                            if(C.channel_maximum[2]<imgdata.rawdata.color_image[rc][2]) 
 838                                C.channel_maximum[2]=imgdata.rawdata.color_image[rc][2];
 839                            if(C.channel_maximum[3]<imgdata.rawdata.color_image[rc][3]) 
 840                                C.channel_maximum[3]=imgdata.rawdata.color_image[rc][4];
 841                        }
 842                }
 843            else if (decoder_info.decoder_flags &  LIBRAW_DECODER_FLATFIELD)
 844                {
 845                        for(int row = 0; row < S.height; row++)
 846                            {
 847                                int colors[4];
 848                                for (int xx=0;xx<4;xx++)
 849                                    colors[xx] = COLOR(row,xx);
 850                                for(int col = 0; col < S.width; col++)
 851                                    {
 852                                        int cc = colors[col&3];
 853                                        if(C.channel_maximum[cc] 
 854                                           < imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_width
 855                                                                       +(col+S.left_margin)])
 856                                            C.channel_maximum[cc] = 
 857                                                imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_width
 858                                                                          +(col+S.left_margin)];
 859                                    }
 860                            }
 861                }
 862        }
 863        // recover image sizes
 864        S.iwidth = save_iwidth;
 865        S.iheight = save_iheight;
 866        IO.shrink = save_shrink;
 867
 868        // phase-one black
 869        if(imgdata.rawdata.ph1_black)
 870            C.ph1_black = imgdata.rawdata.ph1_black;
 871        O.document_mode = save_document_mode;
 872
 873        // adjust black to possible maximum
 874        unsigned int i = C.cblack[3];
 875        unsigned int c;
 876        for(c=0;c<3;c++)
 877            if (i > C.cblack[c]) i = C.cblack[c];
 878        for (c=0;c<4;c++)
 879            C.cblack[c] -= i;
 880        C.black += i;
 881
 882
 883        // Save color,sizes and internal data into raw_image fields
 884        memmove(&imgdata.rawdata.color,&imgdata.color,sizeof(imgdata.color));
 885        memmove(&imgdata.rawdata.sizes,&imgdata.sizes,sizeof(imgdata.sizes));
 886        memmove(&imgdata.rawdata.iparams,&imgdata.idata,sizeof(imgdata.idata));
 887        memmove(&imgdata.rawdata.ioparams,&libraw_internal_data.internal_output_params,sizeof(libraw_internal_data.internal_output_params));
 888
 889        SET_PROC_FLAG(LIBRAW_PROGRESS_LOAD_RAW);
 890        RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW,1,2);
 891        
 892        return 0;
 893    }
 894    catch ( LibRaw_exceptions err) {
 895        EXCEPTION_HANDLER(err);
 896    }
 897}
 898
 899void LibRaw::free_image(void)
 900{
 901    if(imgdata.image)
 902        {
 903            free(imgdata.image);
 904            imgdata.image = 0;
 905            imgdata.progress_flags 
 906                = LIBRAW_PROGRESS_START|LIBRAW_PROGRESS_OPEN
 907                |LIBRAW_PROGRESS_IDENTIFY|LIBRAW_PROGRESS_SIZE_ADJUST|LIBRAW_PROGRESS_LOAD_RAW;
 908        }
 909}
 910
 911
 912void LibRaw::raw2image_start()
 913{
 914        // restore color,sizes and internal data into raw_image fields
 915        memmove(&imgdata.color,&imgdata.rawdata.color,sizeof(imgdata.color));
 916        memmove(&imgdata.sizes,&imgdata.rawdata.sizes,sizeof(imgdata.sizes));
 917        memmove(&imgdata.idata,&imgdata.rawdata.iparams,sizeof(imgdata.idata));
 918        memmove(&libraw_internal_data.internal_output_params,&imgdata.rawdata.ioparams,sizeof(libraw_internal_data.internal_output_params));
 919
 920        if (O.user_flip >= 0)
 921            S.flip = O.user_flip;
 922        
 923        switch ((S.flip+3600) % 360) 
 924            {
 925            case 270:  S.flip = 5;  break;
 926            case 180:  S.flip = 3;  break;
 927            case  90:  S.flip = 6;  break;
 928            }
 929
 930        // adjust for half mode!
 931        IO.shrink = P1.filters && (O.half_size ||
 932                                   ((O.threshold || O.aber[0] != 1 || O.aber[2] != 1) ));
 933        
 934        S.iheight = (S.height + IO.shrink) >> IO.shrink;
 935        S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
 936
 937        if (O.user_black >= 0) 
 938            C.black = O.user_black;
 939}
 940
 941// Same as raw2image, but
 942// 1) Do raw2image and rotate_fuji_raw in one pass
 943// 2) Do raw2image and cropping in one pass
 944#ifndef MIN
 945#define MIN(a,b) ((a) < (b) ? (a) : (b))
 946#endif
 947int LibRaw::raw2image_ex(void)
 948{
 949    CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
 950
 951    raw2image_start();
 952
 953    // process cropping
 954    int do_crop = 0;
 955    unsigned save_filters = imgdata.idata.filters;
 956    unsigned save_width = S.width;
 957    if (~O.cropbox[2] && ~O.cropbox[3])
 958        {
 959            int crop[4],c,filt;
 960            for(int c=0;c<4;c++) 
 961                {
 962                    crop[c] = O.cropbox[c];
 963                    if(crop[c]<0)
 964                        crop[c]=0;
 965                }
 966            if(IO.fwidth) 
 967                {
 968                    crop[0] = (crop[0]/4)*4;
 969                    crop[1] = (crop[1]/4)*4;
 970                }
 971            do_crop = 1;
 972            crop[2] = MIN (crop[2], (signed) S.width-crop[0]);
 973            crop[3] = MIN (crop[3], (signed) S.height-crop[1]);
 974            if (crop[2] <= 0 || crop[3] <= 0)
 975                throw LIBRAW_EXCEPTION_BAD_CROP;
 976            
 977            // adjust sizes!
 978            S.left_margin+=crop[0];
 979            S.top_margin+=crop[1];
 980            S.width=crop[2];
 981            S.height=crop[3];
 982            
 983            S.iheight = (S.height + IO.shrink) >> IO.shrink;
 984            S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
 985            if(!IO.fwidth && imgdata.idata.filters)
 986                {
 987                    for (filt=c=0; c < 16; c++)
 988                        filt |= FC((c >> 1)+(crop[1]),
 989                                   (c &  1)+(crop[0])) << c*2;
 990                    imgdata.idata.filters = filt;
 991                }
 992        }
 993
 994    if(IO.fwidth) 
 995        {
 996            ushort fiwidth,fiheight;
 997            if(do_crop)
 998                {
 999                    IO.fuji_width = S.width >> !libraw_internal_data.unpacker_data.fuji_layout;
1000                    IO.fwidth = (S.height >> libraw_internal_data.unpacker_data.fuji_layout) + IO.fuji_width;
1001                    IO.fheight = IO.fwidth - 1;
1002                }
1003
1004            fiheight = (IO.fheight + IO.shrink) >> IO.shrink;
1005            fiwidth = (IO.fwidth + IO.shrink) >> IO.shrink;
1006            if(imgdata.image)
1007                    {
1008                        imgdata.image = (ushort (*)[4])realloc(imgdata.image,fiheight*fiwidth*sizeof (*imgdata.image));
1009                        memset(imgdata.image,0,fiheight*fiwidth *sizeof (*imgdata.image));
1010                    }
1011                else
1012                    imgdata.image = (ushort (*)[4]) calloc (fiheight*fiwidth, sizeof (*imgdata.image));
1013            merror (imgdata.image, "raw2image_ex()");
1014
1015            int cblk[4],i;
1016            for(i=0;i<4;i++)
1017                cblk[i] = C.cblack[i]+C.black;
1018            ZERO(C.channel_maximum);
1019
1020            int row,col;
1021            for(row=0;row<S.height;row++)
1022                {
1023                    for(col=0;col<S.width;col++)
1024                        {
1025                            int r,c;
1026                            if (libraw_internal_data.unpacker_data.fuji_layout) {
1027                                r = IO.fuji_width - 1 - col + (row >> 1);
1028                                c = col + ((row+1) >> 1);
1029                            } else {
1030                                r = IO.fuji_width - 1 + row - (col >> 1);
1031                                c = row + ((col+1) >> 1);
1032                            }
1033                            
1034                            int val = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_width
1035                                                            +(col+S.left_margin)];
1036                            int cc = FCF(row,col);
1037                            if(val > cblk[cc])
1038                                val -= cblk[cc];
1039                            else
1040                                val = 0;
1041                            imgdata.image[((r) >> IO.shrink)*fiwidth + ((c) >> IO.shrink)][cc] = val;
1042                            if(C.channel_maximum[cc] < val) C.channel_maximum[cc] = val;
1043                        }
1044                }
1045            C.maximum -= C.black;
1046            ZERO(C.cblack);
1047            C.black = 0;
1048
1049            // restore fuji sizes!
1050            S.height = IO.fheight;
1051            S.width = IO.fwidth;
1052            S.iheight = (S.height + IO.shrink) >> IO.shrink;
1053            S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
1054            S.raw_height -= 2*S.top_margin;
1055        }
1056    else
1057        {
1058
1059                if(imgdata.image)
1060                    {
1061                        imgdata.image = (ushort (*)[4]) realloc (imgdata.image,S.iheight*S.iwidth 
1062                                                                 *sizeof (*imgdata.image));
1063                        memset(imgdata.image,0,S.iheight*S.iwidth *sizeof (*imgdata.image));
1064                    }
1065                else
1066                    imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
1067
1068                merror (imgdata.image, "raw2image_ex()");
1069                
1070                libraw_decoder_info_t decoder_info;
1071                get_decoder_info(&decoder_info);
1072
1073
1074                if(decoder_info.decoder_flags & LIBRAW_DECODER_FLATFIELD)
1075                    {
1076                        if(decoder_info.decoder_flags & LIBRAW_DECODER_USEBAYER2)
1077#if defined(LIBRAW_USE_OPENMP)
1078#pragma omp parallel for default(shared)
1079#endif
1080                            for(int row = 0; row < S.height; row++)
1081                                for(int col = 0; col < S.width; col++)
1082                                    imgdata.image[(row >> IO.shrink)*S.iwidth + (col>>IO.shrink)][fc(row,col)]
1083                                        = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_width
1084                                                                    +(col+S.left_margin)];
1085                        else
1086#if defined(LIBRAW_USE_OPENMP)
1087#pragma omp parallel for default(shared)
1088#endif
1089                            for(int row = 0; row < S.height; row++)
1090                                {
1091                                    int colors[2];
1092                                    for (int xx=0;xx<2;xx++)
1093                                        colors[xx] = COLOR(row,xx);
1094                                    for(int col = 0; col < S.width; col++)
1095                                        {
1096                                            int cc = colors[col&1];
1097                                            imgdata.image[(row >> IO.shrink)*S.iwidth + (col>>IO.shrink)][cc] =
1098                                                imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_width
1099                                                                          +(col+S.left_margin)];
1100                                        }
1101                                }
1102                    }
1103                else if (decoder_info.decoder_flags & LIBRAW_DECODER_4COMPONENT)
1104                    {
1105#define FC0(row,col) (save_filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)
1106                        if(IO.shrink)
1107#if defined(LIBRAW_USE_OPENMP)
1108#pragma omp parallel for default(shared)
1109#endif
1110                            for(int row = 0; row < S.height; row++)
1111                                for(int col = 0; col < S.width; col++)
1112                                    imgdata.image[(row >> IO.shrink)*S.iwidth + (col>>IO.shrink)][FC(row,col)] 
1113                                        = imgdata.rawdata.color_image[(row+S.top_margin)*S.raw_width
1114                                                                      +S.left_margin+col]
1115                                        [FC0(row+S.top_margin,col+S.left_margin)];
1116#undef FC0
1117                        else
1118#if defined(LIBRAW_USE_OPENMP)
1119#pragma omp parallel for default(shared)
1120#endif
1121                            for(int row = 0; row < S.height; row++)
1122                                memmove(&imgdata.image[row*S.width],
1123                                        &imgdata.rawdata.color_image[(row+S.top_margin)*S.raw_width+S.left_margin],
1124                                        S.width*sizeof(*imgdata.image));
1125                    }
1126                else if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
1127                    {
1128                        if(do_crop)
1129#if defined(LIBRAW_USE_OPENMP)
1130#pragma omp parallel for default(shared)
1131#endif
1132                            for(int row = 0; row < S.height; row++)
1133                                memmove(&imgdata.image[row*S.width],
1134                                        &imgdata.rawdata.color_image[(row+S.top_margin)*save_width+S.left_margin],
1135                                        S.width*sizeof(*imgdata.image));
1136                                
1137                        else 
1138                            memmove(imgdata.image,imgdata.rawdata.color_image,
1139                                    S.width*S.height*sizeof(*imgdata.image));
1140                    }
1141
1142                if(imgdata.rawdata.use_ph1_correct) // Phase one unpacked!
1143                        phase_one_correct();
1144            }
1145    return LIBRAW_SUCCESS;
1146}
1147
1148#undef MIN
1149
1150
1151
1152
1153int LibRaw::raw2image(void)
1154{
1155
1156    CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
1157
1158    try {
1159        raw2image_start();
1160
1161        // free and re-allocate image bitmap
1162        if(imgdata.image)
1163            {
1164                imgdata.image = (ushort (*)[4]) realloc (imgdata.image,S.iheight*S.iwidth *sizeof (*imgdata.image));
1165                memset(imgdata.image,0,S.iheight*S.iwidth *sizeof (*imgdata.image));
1166            }
1167        else
1168            imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
1169
1170        merror (imgdata.image, "raw2image()");
1171
1172        libraw_decoder_info_t decoder_info;
1173        get_decoder_info(&decoder_info);
1174        
1175        // Move saved bitmap to imgdata.image
1176        if(decoder_info.decoder_flags & LIBRAW_DECODER_FLATFIELD)
1177            {
1178                if(decoder_info.decoder_flags & LIBRAW_DECODER_USEBAYER2)
1179                    {
1180                        for(int row = 0; row < S.height; row++)
1181                            for(int col = 0; col < S.width; col++)
1182                                imgdata.image[(row >> IO.shrink)*S.iwidth + (col>>IO.shrink)][fc(row,col)]
1183                                = imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_width
1184                                                                           +(col+S.left_margin)];
1185                    }
1186                else
1187                    {
1188                        for(int row = 0; row < S.height; row++)
1189                            {
1190                                int colors[4];
1191                                for (int xx=0;xx<4;xx++)
1192                                    colors[xx] = COLOR(row,xx);
1193                                for(int col = 0; col < S.width; col++)
1194                                    {
1195                                        int cc = colors[col&3];
1196                                        imgdata.image[(row >> IO.shrink)*S.iwidth + (col>>IO.shrink)][cc] =
1197                                            imgdata.rawdata.raw_image[(row+S.top_margin)*S.raw_width+(col
1198                                                                                                      +S.left_margin)];
1199                                    }
1200                            }
1201                    }
1202            }
1203        else if (decoder_info.decoder_flags & LIBRAW_DECODER_4COMPONENT)
1204            {
1205                if(IO.shrink)
1206                    {
1207                        for(int row = 0; row < S.height; row++)
1208                            for(int col = 0; col < S.width; col++)
1209                                {
1210                                    int cc = FC(row,col);
1211                                    imgdata.image[(row >> IO.shrink)*S.iwidth + (col>>IO.shrink)][cc] 
1212                                        = imgdata.rawdata.color_image[(row+S.top_margin)*S.raw_width
1213                                                                      +S.left_margin+col][cc];
1214                                }
1215                    }
1216                else
1217                    for(int row = 0; row < S.height; row++)
1218                        memmove(&imgdata.image[row*S.width],
1219                                &imgdata.rawdata.color_image[(row+S.top_margin)*S.raw_width+S.left_margin],
1220                                S.width*sizeof(*imgdata.image));
1221            }
1222        else if(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY)
1223            {
1224                // legacy is always 4channel and not shrinked!
1225                memmove(imgdata.image,imgdata.rawdata.color_image,S.width*S.height*sizeof(*imgdata.image));
1226            }
1227
1228        if(imgdata.rawdata.use_ph1_correct) // Phase one unpacked!
1229            phase_one_correct();
1230
1231        // hack - clear later flags!
1232        imgdata.progress_flags 
1233            = LIBRAW_PROGRESS_START|LIBRAW_PROGRESS_OPEN
1234            |LIBRAW_PROGRESS_IDENTIFY|LIBRAW_PROGRESS_SIZE_ADJUST|LIBRAW_PROGRESS_LOAD_RAW;
1235        return 0;
1236    }
1237    catch ( LibRaw_exceptions err) {
1238        EXCEPTION_HANDLER(err);
1239    }
1240}
1241    
1242
1243int LibRaw::dcraw_document_mode_processing(void)
1244{
1245//    CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
1246    CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
1247
1248    try {
1249
1250        int no_crop = 1;
1251
1252        if (~O.cropbox[2] && ~O.cropbox[3])
1253            no_crop=0;
1254
1255        raw2image_ex(); // raw2image+crop+rotate_fuji_raw
1256
1257        if (IO.zero_is_bad)
1258            {
1259                remove_zeroes();
1260                SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
1261            }
1262
1263        if(!IO.fuji_width)
1264            subtract_black();
1265        
1266        O.document_mode = 2;
1267        
1268        if(P1.is_foveon)
1269            {
1270                // filter image data for foveon document mode
1271                short *iptr = (short *)imgdata.image;
1272                for (int i=0; i < S.height*S.width*4; i++)
1273                    {
1274                        if ((short) iptr[i] < 0) 
1275                            iptr[i] = 0;
1276                    }
1277                SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE);
1278            }
1279
1280        O.use_fuji_rotate = 0;
1281
1282        if(O.bad_pixels && no_crop) 
1283            {
1284                bad_pixels(O.bad_pixels);
1285                SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
1286            }
1287        if (O.dark_frame && no_crop)
1288            {
1289                subtract (O.dark_frame);
1290                SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
1291            }
1292
1293
1294        adjust_maximum();
1295
1296        if (O.user_sat > 0) 
1297            C.maximum = O.user_sat;
1298
1299        pre_interpolate();
1300        SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);
1301
1302        if (libraw_internal_data.internal_output_params.mix_green)
1303            {
1304                int i;
1305                for (P1.colors=3, i=0; i < S.height*S.width; i++)
1306                    imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
1307            }
1308        SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
1309
1310        if (!P1.is_foveon && P1.colors == 3) 
1311            median_filter();
1312        SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
1313
1314        if (!P1.is_foveon && O.highlight == 2) 
1315            blend_highlights();
1316
1317        if (!P1.is_foveon && O.highlight > 2) 
1318            recover_highlights();
1319        SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
1320
1321        if (O.use_fuji_rotate) 
1322            fuji_rotate();
1323        SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
1324#ifndef NO_LCMS
1325	if(O.camera_profile)
1326            {
1327                apply_profile(O.camera_profile,O.output_profile);
1328                SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
1329            }
1330#endif
1331        if(!libraw_internal_data.output_data.histogram)
1332            {
1333                libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
1334                merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_document_mode_processing()");
1335            }
1336        convert_to_rgb();
1337        SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);
1338
1339        if (O.use_fuji_rotate)
1340            stretch();
1341        SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
1342
1343        return 0;
1344    }
1345    catch ( LibRaw_exceptions err) {
1346        EXCEPTION_HANDLER(err);
1347    }
1348
1349}
1350
1351#if 1
1352
1353libraw_processed_image_t * LibRaw::dcraw_make_mem_thumb(int *errcode)
1354{
1355    if(!T.thumb)
1356        {
1357            if ( !ID.toffset) 
1358                {
1359                    if(errcode) *errcode= LIBRAW_NO_THUMBNAIL;
1360                }
1361            else
1362                {
1363                    if(errcode) *errcode= LIBRAW_OUT_OF_ORDER_CALL;
1364                }
1365            return NULL;
1366        }
1367
1368    if (T.tformat == LIBRAW_THUMBNAIL_BITMAP)
1369        {
1370            libraw_processed_image_t * ret = 
1371                (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+T.tlength);
1372
1373            if(!ret)
1374                {
1375                    if(errcode) *errcode= ENOMEM;
1376                    return NULL;
1377                }
1378
1379            memset(ret,0,sizeof(libraw_processed_image_t));
1380            ret->type   = LIBRAW_IMAGE_BITMAP;
1381            ret->height = T.theight;
1382            ret->width  = T.twidth;
1383            ret->colors = 3; 
1384            ret->bits   = 8;
1385            ret->data_size = T.tlength;
1386            memmove(ret->data,T.thumb,T.tlength);
1387            if(errcode) *errcode= 0;
1388            return ret;
1389        }
1390    else if (T.tformat == LIBRAW_THUMBNAIL_JPEG)
1391        {
1392            ushort exif[5];
1393            int mk_exif = 0;
1394            if(strcmp(T.thumb+6,"Exif")) mk_exif = 1;
1395            
1396            int dsize = T.tlength + mk_exif * (sizeof(exif)+sizeof(tiff_hdr));
1397
1398            libraw_processed_image_t * ret = 
1399                (libraw_processed_image_t *)::malloc(sizeof(libraw_processed_image_t)+dsize);
1400
1401            if(!ret)
1402                {
1403                    if(errcode) *errcode= ENOMEM;
1404                    return NULL;
1405                }
1406
1407            memset(ret,0,sizeof(libraw_processed_image_t));
1408
1409            ret->type = LIBRAW_IMAGE_JPEG;
1410            ret->data_size = dsize;
1411            
1412            ret->data[0] = 0xff;
1413            ret->data[1] = 0xd8;
1414            if(mk_exif)
1415                {
1416                    struct tiff_hdr th;
1417                    memcpy (exif, "\xff\xe1  Exif\0\0", 10);
1418                    exif[1] = htons (8 + sizeof th);
1419                    memmove(ret->data+2,exif,sizeof(exif));
1420                    tiff_head (&th, 0);
1421                    memmove(ret->data+(2+sizeof(exif)),&th,sizeof(th));
1422                    memmove(ret->data+(2+sizeof(exif)+sizeof(th)),T.thumb+2,T.tlength-2);
1423                }
1424            else
1425                {
1426                    memmove(ret->data+2,T.thumb+2,T.tlength-2);
1427                }
1428            if(errcode) *errcode= 0;
1429            return ret;
1430            
1431        }
1432    else
1433        {
1434            if(errcode) *errcode= LIBRAW_UNSUPPORTED_THUMBNAIL;
1435            return NULL;
1436
1437        }
1438}
1439
1440
1441
1442// jlb
1443// macros for copying pixels to either BGR or RGB formats
1444#define FORBGR for(c=P1.colors-1; c >=0 ; c--)
1445#define FORRGB for(c=0; c < P1.colors ; c++)
1446
1447void LibRaw::get_mem_image_format(int* width, int* height, int* colors, int* bps) const
1448
1449{
1450    if (S.flip & 4) {
1451        *width = S.height;
1452        *height = S.width;
1453    }
1454    else {
1455        *width = S.width;
1456        *height = S.height;
1457    }
1458    *colors = P1.colors;
1459    *bps = O.output_bps;
1460}
1461
1462int LibRaw::copy_mem_image(void* scan0, int stride, int bgr)
1463
1464{
1465    // the image memory pointed to by scan0 is assumed to be in the format returned by get_mem_image_format
1466    if((imgdata.progress_flags & LIBRAW_PROGRESS_THUMB_MASK) < LIBRAW_PROGRESS_PRE_INTERPOLATE)
1467        return LIBRAW_OUT_OF_ORDER_CALL;
1468
1469    if(libraw_internal_data.output_data.histogram)
1470        {
1471            int perc, val, total, t_white=0x2000,c;
1472            perc = S.width * S.height * 0.01;        /* 99th percentile white level */
1473            if (IO.fuji_width) perc /= 2;
1474            if (!((O.highlight & ~2) || O.no_auto_bright))
1475                for (t_white=c=0; c < P1.colors; c++) {
1476                    for (val=0x2000, total=0; --val > 32; )
1477                        if ((total += libraw_internal_data.output_data.histogram[c][val]) > perc) break;
1478                    if (t_white < val) t_white = val;
1479                }
1480             gamma_curve (O.gamm[0], O.gamm[1], 2, (t_white << 3)/O.bright);
1481        }
1482
1483    int s_iheight = S.iheight;
1484    int s_iwidth = S.iwidth;
1485    int s_width = S.width;
1486    int s_hwight = S.height;
1487
1488    S.iheight = S.height;
1489    S.iwidth  = S.width;
1490
1491    if (S.flip & 4) SWAP(S.height,S.width);
1492    uchar *ppm;
1493    ushort *ppm2;
1494    int c, row, col, soff, rstep, cstep;
1495
1496    soff  = flip_index (0, 0);
1497    cstep = flip_index (0, 1) - soff;
1498    rstep = flip_index (1, 0) - flip_index (0, S.width);
1499
1500    for (row=0; row < S.height; row++, soff += rstep) 
1501        {
1502            uchar *bufp = ((uchar*)scan0)+row*stride;
1503            ppm2 = (ushort*) (ppm = bufp);
1504            // keep trivial decisions in the outer loop for speed
1505            if (bgr) {
1506                if (O.output_bps == 8) {
1507                    for (col=0; col < S.width; col++, soff += cstep) 
1508                        FORBGR *ppm++ = imgdata.color.curve[imgdata.image[soff][c]]>>8;
1509                }
1510                else {
1511                    for (col=0; col < S.width; col++, soff += cstep) 
1512                        FORBGR *ppm2++ = imgdata.color.curve[imgdata.image[soff][c]];
1513                }
1514            }
1515            else {
1516                if (O.output_bps == 8) {
1517                    for (col=0; col < S.width; col++, soff += cstep) 
1518                        FORRGB *ppm++ = imgdata.color.curve[imgdata.image[soff][c]]>>8;
1519                }
1520                else {
1521                    for (col=0; col < S.width; col++, soff += cstep) 
1522                        FORRGB *ppm2++ = imgdata.color.curve[imgdata.image[soff][c]];
1523                }
1524            }
1525
1526//            bufp += stride;           // go to the next line
1527        }
1528 
1529    S.iheight = s_iheight;
1530    S.iwidth = s_iwidth;
1531    S.width = s_width;
1532    S.height = s_hwight;
1533
1534    return 0;
1535
1536
1537}
1538#undef FORBGR
1539#undef FORRGB
1540
1541 
1542
1543libraw_processed_image_t *LibRaw::dcraw_make_mem_image(int *errcode)
1544
1545{
1546    int width, height, colors, bps;
1547    get_mem_image_format(&width, &height, &colors, &bps);
1548    int stride = width * (bps/8) * colors;
1549    unsigned ds = height * stride;
1550    libraw_processed_image_t *ret = (libraw_processed_image_t*)::malloc(sizeof(libraw_processed_image_t)+ds);
1551    if(!ret)
1552        {
1553                if(errcode) *errcode= ENOMEM;
1554                return NULL;
1555        }
1556    memset(ret,0,sizeof(libraw_processed_image_t));
1557
1558    // metadata init
1559    ret->type   = LIBRAW_IMAGE_BITMAP;
1560    ret->height = height;
1561    ret->width  = width;
1562    ret->colors = colors;
1563    ret->bits   = bps;
1564    ret->data_size = ds;
1565    copy_mem_image(ret->data, stride, 0); 
1566
1567    return ret;
1568}
1569
1570#undef FORC
1571#undef FORCC
1572#undef SWAP
1573#endif
1574
1575
1576int LibRaw::dcraw_ppm_tiff_writer(const char *filename)
1577{
1578    CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
1579
1580    if(!imgdata.image) 
1581        return LIBRAW_OUT_OF_ORDER_CALL;
1582
1583    if(!filename) 
1584        return ENOENT;
1585    FILE *f = fopen(filename,"wb");
1586
1587    if(!f) 
1588        return errno;
1589
1590    try {
1591        if(!libraw_internal_data.output_data.histogram)
1592            {
1593                libraw_internal_data.output_data.histogram = 
1594                    (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
1595                merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_ppm_tiff_writer()");
1596            }
1597        libraw_internal_data.internal_data.output = f;
1598        write_ppm_tiff();
1599        SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
1600        libraw_internal_data.internal_data.output = NULL;
1601        fclose(f);
1602        return 0;
1603    }
1604    catch ( LibRaw_exceptions err) {
1605        fclose(f);
1606        EXCEPTION_HANDLER(err);
1607    }
1608}
1609
1610void LibRaw::kodak_thumb_loader()
1611{
1612    // some kodak cameras
1613    ushort s_height = S.height, s_width = S.width,s_iwidth = S.iwidth,s_iheight=S.iheight;
1614    int s_colors = P1.colors;
1615    unsigned s_filters = P1.filters;
1616    ushort (*s_image)[4] = imgdata.image;
1617
1618    
1619    S.height = T.theight;
1620    S.width  = T.twidth;
1621    P1.filters = 0;
1622
1623    if (thumb_load_raw == &CLASS kodak_ycbcr_load_thumb) 
1624        {
1625            S.height += S.height & 1;
1626            S.width  += S.width  & 1;
1627        }
1628    
1629    imgdata.image = (ushort (*)[4]) calloc (S.iheight*S.iwidth, sizeof (*imgdata.image));
1630    merror (imgdata.image, "LibRaw::kodak_thumb_loader()");
1631
1632    ID.input->seek(ID.toffset, SEEK_SET);
1633    // read kodak thumbnail into T.image[]
1634    (this->*thumb_load_raw)();
1635
1636    // copy-n-paste from image pipe
1637#define MIN(a,b) ((a) < (b) ? (a) : (b))
1638#define MAX(a,b) ((a) > (b) ? (a) : (b))
1639#define LIM(x,min,max) MAX(min,MIN(x,max))
1640#define CLIP(x) LIM(x,0,65535)
1641#define SWAP(a,b) { a ^= b; a ^= (b ^= a); }
1642
1643    // from scale_colors
1644    {
1645        double   dmax;
1646        float scale_mul[4];
1647        int c,val;
1648        for (dmax=DBL_MAX, c=0; c < 3; c++) 
1649                if (dmax > C.pre_mul[c])
1650                    dmax = C.pre_mul[c];
1651
1652        for( c=0; c< 3; c++)
1653                scale_mul[c] = (C.pre_mul[c] / dmax) * 65535.0 / C.maximum;
1654        scale_mul[3] = scale_mul[1];
1655
1656        size_t size = S.height * S.width;
1657        for (unsigned i=0; i < size*4 ; i++) 
1658            {
1659                val = imgdata.image[0][i];
1660                if(!val) continue;
1661                val *= scale_mul[i & 3];
1662                imgdata.image[0][i] = CLIP(val);
1663            }
1664    }
1665
1666    // from convert_to_rgb
1667    ushort *img;
1668    int row,col;
1669    
1670    int  (*t_hist)[LIBRAW_HISTOGRAM_SIZE] =  (int (*)[LIBRAW_HISTOGRAM_SIZE]) calloc(sizeof(*t_hist),4);
1671    merror (t_hist, "LibRaw::kodak_thumb_loader()");
1672    
1673    float out[3], 
1674        out_cam[3][4] = 
1675        {
1676            {2.81761312, -1.98369181, 0.166078627, 0}, 
1677            {-0.111855984, 1.73688626, -0.625030339, 0}, 
1678            {-0.0379119813, -0.891268849, 1.92918086, 0}
1679        };
1680
1681    for (img=imgdata.image[0], row=0; row < S.height; row++)
1682        for (col=0; col < S.width; col++, img+=4)
1683            {
1684                out[0] = out[1] = out[2] = 0;
1685                int c;
1686                for(c=0;c<3;c++) 
1687                    {
1688                        out[0] += out_cam[0][c] * img[c];
1689                        out[1] += out_cam[1][c] * img[c];
1690                        out[2] += out_cam[2][c] * img[c];
1691                    }
1692                for(c=0; c<3; c++)
1693                    img[c] = CLIP((int) out[c]);
1694                for(c=0; c<P1.colors;c++)
1695                    t_hist[c][img[c] >> 3]++;
1696                    
1697            }
1698
1699    // from gamma_lut
1700    int  (*save_hist)[LIBRAW_HISTOGRAM_SIZE] = libraw_internal_data.output_data.histogram;
1701    libraw_internal_data.output_data.histogram = t_hist;
1702
1703    // make curve output curve!
1704    ushort (*t_curve) = (ushort*) calloc(sizeof(C.curve),1);
1705    merror (t_curve, "LibRaw::kodak_thumb_loader()");
1706    memmove(t_curve,C.curve,sizeof(C.curve));
1707    memset(C.curve,0,sizeof(C.curve));
1708        {
1709            int perc, val, total, t_white=0x2000,c;
1710
1711            perc = S.width * S.height * 0.01;		/* 99th percentile white level */
1712            if (IO.fuji_width) perc /= 2;
1713            if (!((O.highlight & ~2) || O.no_auto_bright))
1714                for (t_white=c=0; c < P1.colors; c++) {
1715                    for (val=0x2000, total=0; --val > 32; )
1716                        if ((total += libraw_internal_data.output_data.histogram[c][val]) > perc) break;
1717                    if (t_white < val) t_white = val;
1718                }
1719            gamma_curve (O.gamm[0], O.gamm[1], 2, (t_white << 3)/O.bright);
1720        }
1721    
1722    libraw_internal_data.output_data.histogram = save_hist;
1723    free(t_hist);
1724    
1725    // from write_ppm_tiff - copy pixels into bitmap
1726    
1727    S.iheight = S.height;
1728    S.iwidth  = S.width;
1729    if (S.flip & 4) SWAP(S.height,S.width);
1730
1731    if(T.thumb) free(T.thumb);
1732    T.thumb = (char*) calloc (S.width * S.height, P1.colors);
1733    merror (T.thumb, "LibRaw::kodak_thumb_loader()");
1734    T.tlength = S.width * S.height * P1.colors;
1735
1736    // from write_tiff_ppm
1737    {
1738        int soff  = flip_index (0, 0);
1739        int cstep = flip_index (0, 1) - soff;
1740        int rstep = flip_index (1, 0) - flip_index (0, S.width);
1741        
1742        for (int row=0; row < S.height; row++, soff += rstep) 
1743            {
1744                char *ppm = T.thumb + row*S.width*P1.colors;
1745                for (int col=0; col < S.width; col++, soff += cstep)
1746                    for(int c = 0; c < P1.colors; c++)
1747                        ppm [col*P1.colors+c] = imgdata.color.curve[imgdata.image[soff][c]]>>8;
1748            }
1749    }
1750
1751    memmove(C.curve,t_curve,sizeof(C.curve));
1752    free(t_curve);
1753
1754    // restore variables
1755    free(imgdata.image);
1756    imgdata.image  = s_image;
1757    
1758    T.twidth = S.width;
1759    S.width = s_width;
1760
1761    S.iwidth = s_iwidth;
1762    S.iheight = s_iheight;
1763
1764    T.theight = S.height;
1765    S.height = s_height;
1766
1767    T.tcolors = P1.colors;
1768    P1.colors = s_colors;
1769
1770    P1.filters = s_filters;
1771}
1772#undef MIN
1773#undef MAX
1774#undef LIM
1775#undef CLIP
1776#undef SWAP
1777
1778
1779
1780
1781// Достает thumbnail из файла, ставит thumb_format в соответствии с форматом
1782int LibRaw::unpack_thumb(void)
1783{
1784    CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
1785    CHECK_ORDER_BIT(LIBRAW_PROGRESS_THUMB_LOAD);
1786
1787    try {
1788        if ( !ID.toffset) 
1789            {
1790                return LIBRAW_NO_THUMBNAIL;
1791            } 
1792        else if (thumb_load_raw) 
1793            {
1794                kodak_thumb_loader();
1795                T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1796                SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1797                return 0;
1798            } 
1799        else 
1800            {
1801                ID.input->seek(ID.toffset, SEEK_SET);
1802                if ( write_thumb == &LibRaw::jpeg_thumb)
1803                    {
1804                        if(T.thumb) free(T.thumb);
1805                        T.thumb = (char *) malloc (T.tlength);
1806                        merror (T.thumb, "jpeg_thumb()");
1807                        ID.input->read (T.thumb, 1, T.tlength);
1808                        T.tcolors = 3;
1809                        T.tformat = LIBRAW_THUMBNAIL_JPEG;
1810                        SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1811                        return 0;
1812                    }
1813                else if (write_thumb == &LibRaw::ppm_thumb)
1814                    {
1815                        T.tlength = T.twidth * T.theight*3;
1816                        if(T.thumb) free(T.thumb);
1817
1818                        T.thumb = (char *) malloc (T.tlength);
1819                        merror (T.thumb, "ppm_thumb()");
1820
1821                        ID.input->read(T.thumb, 1, T.tlength);
1822
1823                        T.tformat = LIBRAW_THUMBNAIL_BITMAP;
1824                        SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1825                        return 0;
1826
1827                    }
1828                else if (write_thumb == &LibRaw::foveon_thumb)
1829                    {
1830                        foveon_thumb_loader();
1831                        // may return with error, so format is set in
1832                        // foveon thumb loader itself
1833                        SET_PROC_FLAG(LIBRAW_PROGRESS_THUMB_LOAD);
1834                        return 0;
1835                    }
1836                // else if -- all other write_thumb cases!
1837                else
1838                    {
1839                        return LIBRAW_UNSUPPORTED_THUMBNAIL;
1840                    }
1841            }
1842        // last resort
1843        return LIBRAW_UNSUPPORTED_THUMBNAIL;
1844    }
1845    catch ( LibRaw_exceptions err) {
1846        EXCEPTION_HANDLER(err);
1847    }
1848
1849}
1850
1851int LibRaw::dcraw_thumb_writer(const char *fname)
1852{
1853//    CHECK_ORDER_LOW(LIBRAW_PROGRESS_THUMB_LOAD);
1854
1855    if(!fname) 
1856        return ENOENT;
1857        
1858    FILE *tfp = fopen(fname,"wb");
1859    
1860    if(!tfp) 
1861        return errno;
1862
1863    if(!T.thumb)
1864	{
1865		fclose(tfp);
1866        	return LIBRAW_OUT_OF_ORDER_CALL;
1867	}
1868
1869    try {
1870        switch (T.tformat)
1871            {
1872            case LIBRAW_THUMBNAIL_JPEG:
1873                jpeg_thumb_writer (tfp,T.thumb,T.tlength);
1874                break;
1875            case LIBRAW_THUMBNAIL_BITMAP:
1876                fprintf (tfp, "P6\n%d %d\n255\n", T.twidth, T.theight);
1877                fwrite (T.thumb, 1, T.tlength, tfp);
1878                break;
1879            default:
1880                fclose(tfp);
1881                return LIBRAW_UNSUPPORTED_THUMBNAIL;
1882           }
1883        fclose(tfp);
1884        return 0;
1885    }
1886    catch ( LibRaw_exceptions err) {
1887        fclose(tfp);
1888        EXCEPTION_HANDLER(err);
1889    }
1890}
1891
1892int LibRaw::adjust_sizes_info_only(void)
1893{
1894    CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY);
1895
1896    raw2image_start();
1897    if (O.use_fuji_rotate)
1898        {
1899            if (IO.fuji_width) 
1900                {
1901                    // restore saved values
1902                    if(IO.fheight)
1903                        {
1904                            S.height = IO.fheight;
1905                            S.width = IO.fwidth;
1906                            S.iheight = (S.height + IO.shrink) >> IO.shrink;
1907                            S.iwidth  = (S.width  + IO.shrink) >> IO.shrink;
1908                            S.raw_height -= 2*S.top_margin;
1909                            IO.fheight = IO.fwidth = 0; // prevent repeated calls
1910                        }
1911                    // dcraw code
1912                    IO.fuji_width = (IO.fuji_width - 1 + IO.shrink) >> IO.shrink;
1913                    S.iwidth = (ushort)(IO.fuji_width / sqrt(0.5));
1914                    S.iheight = (ushort)( (S.iheight - IO.fuji_width) / sqrt(0.5));
1915                } 
1916            else 
1917                {
1918                    if (S.pixel_aspect < 1) S.iheight = (ushort)( S.iheight / S.pixel_aspect + 0.5);
1919                    if (S.pixel_aspect > 1) S.iwidth  = (ushort) (S.iwidth  * S.pixel_aspect + 0.5);
1920                }
1921        }
1922    SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
1923    if ( S.flip & 4)
1924        {
1925            unsigned short t = S.iheight;
1926            S.iheight=S.iwidth;
1927            S.iwidth = t;
1928            SET_PROC_FLAG(LIBRAW_PROGRESS_FLIP);
1929        }
1930    return 0;
1931}
1932
1933
1934void LibRaw::subtract_black()
1935{
1936
1937#define BAYERC(row,col,c) imgdata.image[((row) >> IO.shrink)*S.iwidth + ((col) >> IO.shrink)][c] 
1938
1939    if(C.ph1_black)
1940        {
1941            // Phase One compressed format
1942            int row,col,val,cc;
1943            for(row=0;row<S.height;row++)
1944                for(col=0;col<S.width;col++)
1945                    {
1946                        cc=FC(row,col);
1947                        val = BAYERC(row,col,cc) 
1948                            - C.phase_one_data.t_black 
1949                            + C.ph1_black[row+S.top_margin][(col + S.left_margin) 
1950                                                                                >=C.phase_one_data.split_col];
1951                        if(val<0) val = 0;
1952                        BAYERC(row,col,cc) = val;
1953                    }
1954            C.maximum -= C.black;
1955            phase_one_correct();
1956            // recalculate channel maximum
1957            ZERO(C.channel_maximum);
1958            for(row=0;row<S.height;row++)
1959                for(col=0;col<S.width;col++)
1960                    {
1961                        cc=FC(row,col);
1962                        val = BAYERC(row,col,cc);
1963                        if(C.channel_maximum[cc] > val) C.channel_maximum[cc] = val;
1964                    }
1965            // clear P1 black level data
1966            imgdata.color.phase_one_data.t_black = 0;
1967            C.ph1_black = 0;
1968            ZERO(C.cblack);
1969            C.black = 0;
1970        }
1971    else if((C.black || C.cblack[0] || C.cblack[1] || C.cblack[2] || C.cblack[3]))
1972        {
1973            int cblk[4],i,row,col,val,cc;
1974            for(i=0;i<4;i++)
1975                cblk[i] = C.cblack[i]+C.black;
1976            ZERO(C.channel_maximum);
1977
1978            for(row=0;row<S.height;row++)
1979                for(col=0;col<S.width;col++)
1980                    {
1981                        cc=COLOR(row,col);
1982                        val = BAYERC(row,col,cc);
1983                        if(val > cblk[cc])
1984                            val -= cblk[cc];
1985                        else
1986                            val = 0;
1987                        if(C.channel_maximum[cc] < val) C.channel_maximum[cc] = val;
1988                        BAYERC(row,col,cc) = val;
1989                    }
1990            C.maximum -= C.black;
1991            ZERO(C.cblack);
1992            C.black = 0;
1993        }
1994    else
1995        {
1996            // only calculate channel maximum;
1997            int row,col,cc,val;
1998            ZERO(C.channel_maximum);
1999            for(row=0;row<S.height;row++)
2000                for(col=0;col<S.width;col++)
2001                    for(cc = 0; cc< 4; cc++)
2002                        {
2003                            int val = BAYERC(row,col,cc);
2004                            if(C.channel_maximum[cc] < val) C.channel_maximum[cc] = val;
2005                        }
2006            
2007        }
2008}
2009
2010#define TBLN 65535
2011
2012void LibRaw::exp_bef(float shift, float smooth)
2013{
2014    // params limits
2015    if(shift>8) shift = 8;
2016    if(shift<0.25) shift = 0.25;
2017    if(smooth < 0.0) smooth = 0.0;
2018    if(smooth > 1.0) smooth = 1.0;
2019    
2020    unsigned short *lut = (ushort*)malloc((TBLN+1)*sizeof(unsigned short));
2021
2022    if(shift <=1.0)
2023        {
2024            for(int i=0;i<=TBLN;i++)
2025                lut[i] = (unsigned short)((float)i*shift);
2026        }
2027    else
2028        {
2029            float x1,x2,y1,y2;
2030
2031            float cstops = log(shift)/log(2.0f);
2032            float room = cstops*2;
2033            float roomlin = powf(2.0f,room);
2034            x2 = (float)TBLN;
2035            x1 = (x2+1)/roomlin-1;
2036            y1 = x1*shift;
2037            y2 = x2*(1+(1-smooth)*(shift-1));
2038            float sq3x=powf(x1*x1*x2,1.0f/3.0f);
2039            float B = (y2-y1+shift*(3*x1-3.0f*sq3x)) / (x2+2.0f*x1-3.0f*sq3x);
2040            float A = (shift - B)*3.0f*powf(x1*x1,1.0f/3.0f);
2041            float CC = y2 - A*powf(x2,1.0f/3.0f)-B*x2;
2042            for(int i=0;i<=TBLN;i++)
2043                {
2044                    float X = (float)i;
2045                    float Y = A*powf(X,1.0f/3.0f)+B*X+CC;
2046                    if(i<x1)
2047                        lut[i] = (unsigned short)((float)i*shift);
2048                    else
2049                        lut[i] = Y<0?0:(Y>TBLN?TBLN:(unsigned short)(Y));
2050                }
2051        }
2052    for(int i=0; i< S.height*S.width; i++)
2053        {
2054            imgdata.image[i][0] = lut[imgdata.image[i][0]];
2055            imgdata.image[i][1] = lut[imgdata.image[i][1]];
2056            imgdata.image[i][2] = lut[imgdata.image[i][2]];
2057            imgdata.image[i][3] = lut[imgdata.image[i][3]];
2058        }
2059    for(int i=0;i<4;i++)
2060        C.channel_maximum[i] = lut[C.channel_maximum[i]];
2061    C.maximum = lut[C.maximum];
2062    // no need to adjust the minumum, black is already subtracted
2063    free(lut);
2064}
2065int LibRaw::dcraw_process(void)
2066{
2067    int quality,i;
2068
2069    int iterations=-1, dcb_enhance=1, noiserd=0;
2070    int eeci_refine_fl=0, es_med_passes_fl=0;
2071    float cared=0,cablue=0;
2072    float linenoise=0; 
2073    float lclean=0,cclean=0;
2074    float thresh=0;
2075    float preser=0;
2076    float expos=1.0;
2077
2078
2079    CHECK_ORDER_LOW(LIBRAW_PROGRESS_LOAD_RAW);
2080//    CHECK_ORDER_HIGH(LIBRAW_PROGRESS_PRE_INTERPOLATE);
2081
2082    try {
2083
2084        int no_crop = 1;
2085
2086        if (~O.cropbox[2] && ~O.cropbox[3])
2087            no_crop=0;
2088
2089        raw2image_ex(); // raw2image+crop+rotate_fuji_raw + subtract_black for fuji
2090
2091        int save_4color = O.four_color_rgb;
2092
2093        if (IO.zero_is_bad) 
2094            {
2095                remove_zeroes();
2096                SET_PROC_FLAG(LIBRAW_PROGRESS_REMOVE_ZEROES);
2097            }
2098
2099        if(!IO.fuji_width) // PhaseOne only, all other cases handled at raw2image_ex()
2100            subtract_black();
2101
2102        if(O.half_size) 
2103            O.four_color_rgb = 1;
2104
2105        if(O.bad_pixels && no_crop) 
2106            {
2107                bad_pixels(O.bad_pixels);
2108                SET_PROC_FLAG(LIBRAW_PROGRESS_BAD_PIXELS);
2109            }
2110
2111        if (O.dark_frame && no_crop)
2112            {
2113                subtract (O.dark_frame);
2114                SET_PROC_FLAG(LIBRAW_PROGRESS_DARK_FRAME);
2115            }
2116
2117
2118        quality = 2 + !IO.fuji_width;
2119
2120        if (O.user_qual >= 0) quality = O.user_qual;
2121
2122        adjust_maximum();
2123
2124        if (O.user_sat > 0) C.maximum = O.user_sat;
2125
2126        if (P1.is_foveon && !O.document_mode) 
2127            {
2128                foveon_interpolate();
2129                SET_PROC_FLAG(LIBRAW_PROGRESS_FOVEON_INTERPOLATE);
2130            }
2131
2132        if (O.green_matching && !O.half_size)
2133            {
2134                green_matching();
2135            }
2136
2137        if (!P1.is_foveon &&  O.document_mode < 2)
2138            {
2139                scale_colors();
2140                SET_PROC_FLAG(LIBRAW_PROGRESS_SCALE_COLORS);
2141            }
2142
2143        pre_interpolate();
2144
2145        SET_PROC_FLAG(LIBRAW_PROGRESS_PRE_INTERPOLATE);
2146
2147        if (O.dcb_iterations >= 0) iterations = O.dcb_iterations;
2148        if (O.dcb_enhance_fl >=0 ) dcb_enhance = O.dcb_enhance_fl;
2149        if (O.fbdd_noiserd >=0 ) noiserd = O.fbdd_noiserd;
2150        if (O.eeci_refine >=0 ) eeci_refine_fl = O.eeci_refine;
2151        if (O.es_med_passes >0 ) es_med_passes_fl = O.es_med_passes;
2152
2153// LIBRAW_DEMOSAIC_PACK_GPL3
2154
2155        if (!O.half_size && O.cfa_green >0) {thresh=O.green_thresh ;green_equilibrate(thresh);} 
2156        if (O.exp_correc >0) {expos=O.exp_shift ; preser=O.exp_preser; exp_bef(expos,preser);} 
2157        if (O.ca_correc >0 ) {cablue=O.cablue; cared=O.cared; CA_correct_RT(cablue, cared);}
2158        if (O.cfaline >0 ) {linenoise=O.linenoise; cfa_linedn(linenoise);}
2159        if (O.cfa_clean >0 ) {lclean=O.lclean; cclean=O.cclean; cfa_impulse_gauss(lclean,cclean);}
2160
2161        if (P1.filters && !O.document_mode) 
2162            {
2163                if (noiserd>0 && P1.colors==3 && P1.filters) fbdd(noiserd);
2164
2165                if (quality == 0)
2166                    lin_interpolate();
2167                else if (quality == 1 || P1.colors > 3)
2168                    vng_interpolate();
2169                else if (quality == 2)
2170                    ppg_interpolate();
2171
2172                else if (quality == 3) 
2173                    ahd_interpolate(); // really don't need it here due to fallback op
2174
2175                else if (quality == 4)
2176                    dcb(iterations, dcb_enhance);
2177
2178//  LIBRAW_DEMOSAIC_PACK_GPL2                
2179                else if (quality == 5)
2180                    ahd_interpolate_mod();
2181                else if (quality == 6)
2182                    afd_interpolate_pl(2,1);
2183                else if (quality == 7)
2184                    vcd_interpolate(0);
2185                else if (quality == 8)
2186                    vcd_interpolate(12);
2187                else if (quality == 9)
2188                    lmmse_interpolate(1);
2189
2190// LIBRAW_DEMOSAIC_PACK_GPL3
2191                else if (quality == 10)
2192                    amaze_demosaic_RT();
2193 // fallback to AHD
2194                else
2195                    ahd_interpolate();
2196                
2197                SET_PROC_FLAG(LIBRAW_PROGRESS_INTERPOLATE);
2198            }
2199        if (IO.mix_green)
2200            {
2201                for (P1.colors=3, i=0; i < S.height * S.width; i++)
2202                    imgdata.image[i][1] = (imgdata.image[i][1] + imgdata.image[i][3]) >> 1;
2203                SET_PROC_FLAG(LIBRAW_PROGRESS_MIX_GREEN);
2204            }
2205
2206        if(!P1.is_foveon)
2207            {
2208                if (P1.colors == 3) 
2209                    {
2210                        
2211                        if (quality == 8) 
2212                            {
2213                                if (eeci_refine_fl == 1) refinement();
2214                                if (O.med_passes > 0)    median_filter_new();
2215                                if (es_med_passes_fl > 0) es_median_filter();
2216                            } 
2217                        else {
2218                            median_filter();
2219                        }
2220                        SET_PROC_FLAG(LIBRAW_PROGRESS_MEDIAN_FILTER);
2221                    }
2222            }
2223        
2224        if (O.highlight == 2) 
2225            {
2226                blend_highlights();
2227                SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
2228            }
2229        
2230        if (O.highlight > 2) 
2231            {
2232                recover_highlights();
2233                SET_PROC_FLAG(LIBRAW_PROGRESS_HIGHLIGHTS);
2234            }
2235        
2236        if (O.use_fuji_rotate) 
2237            {
2238                fuji_rotate();
2239                SET_PROC_FLAG(LIBRAW_PROGRESS_FUJI_ROTATE);
2240            }
2241    
2242        if(!libraw_internal_data.output_data.histogram)
2243            {
2244                libraw_internal_data.output_data.histogram = (int (*)[LIBRAW_HISTOGRAM_SIZE]) malloc(sizeof(*libraw_internal_data.output_data.histogram)*4);
2245                merror(libraw_internal_data.output_data.histogram,"LibRaw::dcraw_process()");
2246            }
2247#ifndef NO_LCMS
2248	if(O.camera_profile)
2249            {
2250                apply_profile(O.camera_profile,O.output_profile);
2251                SET_PROC_FLAG(LIBRAW_PROGRESS_APPLY_PROFILE);
2252            }
2253#endif
2254
2255        convert_to_rgb();
2256        SET_PROC_FLAG(LIBRAW_PROGRESS_CONVERT_RGB);
2257
2258        if (O.use_fuji_rotate) 
2259            {
2260                stretch();
2261                SET_PROC_FLAG(LIBRAW_PROGRESS_STRETCH);
2262            }
2263        O.four_color_rgb = save_4color; // also, restore
2264
2265        return 0;
2266    }
2267    catch ( LibRaw_exceptions err) {
2268        EXCEPTION_HANDLER(err);
2269    }
2270}
2271
2272// Supported cameras:
2273static const char  *static_camera_list[] = 
2274{
2275"Adobe Digital Negative (DNG)",
2276"AgfaPhoto DC-833m",
2277"Apple QuickTake 100",
2278"Apple QuickTake 150",
2279"Apple QuickTake 200",
2280"ARRIRAW format",
2281"AVT F-080C",
2282"AVT F-145C",
2283"AVT F-201C",
2284"AVT F-510C",
2285"AVT F-810C",
2286"Canon PowerShot 600",
2287"Canon PowerShot A5",
2288"Canon PowerShot A5 Zoom",
2289"Canon PowerShot A50",
2290"Canon PowerShot A460 (CHDK hack)",
2291"Canon PowerShot A470 (CHDK hack)",
2292"Canon PowerShot A530 (CHDK hack)",
2293"Canon PowerShot A570 (CHDK hack)",
2294"Canon PowerShot A590 (CHDK hack)",
2295"Canon PowerShot A610 (CHDK hack)",
2296"Canon PowerShot A620 (CHDK hack)",
2297"Canon PowerShot A630 (CHDK hack)",
2298"Canon PowerShot A640 (CHDK hack)",
2299"Canon PowerShot A650 (CHDK hack)",
2300"Canon PowerShot A710 IS (CHDK hack)",
2301"Canon PowerShot A720 IS (CHDK hack)",
2302"Canon PowerShot Pro70",
2303"Canon PowerShot Pro90 IS",
2304"Canon PowerShot Pro1",
2305"Canon PowerShot G1",
2306"Canon PowerShot G2",
2307"Canon PowerShot G3",
2308"Canon PowerShot G5",
2309"Canon PowerShot G6",
2310"Canon PowerShot G7 (CHDK hack)",
2311"Canon PowerShot G9",
2312"Canon PowerShot G10",
2313"Canon PowerShot G11",
2314"Canon PowerShot G12",
2315"Canon PowerShot S2 IS (CHDK hack)",
2316"Canon PowerShot S3 IS (CHDK hack)",
2317"Canon PowerShot S5 IS (CHDK hack)",
2318"Canon PowerShot SD300 (CHDK hack)",
2319"Canon PowerShot S30",
2320"Canon PowerShot S40",
2321"Canon PowerShot S45",
2322"Canon PowerShot S50",
2323"Canon PowerShot S60",
2324"Canon PowerShot S70",
2325"Canon PowerShot S90",
2326"Canon PowerShot S95",
2327"Canon PowerShot S100",
2328"Canon PowerShot SX1 IS",
2329"Canon PowerShot SX110 IS (CHDK hack)",
2330"Canon PowerShot SX120 IS (CHDK hack)",
2331"Canon PowerShot SX20 IS (CHDK hack)",
2332"Canon PowerShot SX30 IS (CHDK hack)",
2333"Canon EOS D30",
2334"Canon EOS D60",
2335"Canon EOS 5D",
2336"Canon EOS 5D Mark II",
2337"Canon EOS 7D",
2338"Canon EOS 10D",
2339"Canon EOS 20D",
2340"Canon EOS 30D",
2341"Canon EOS 40D",
2342"Canon EOS 50D",
2343"Canon EOS 60D",
2344"Canon EOS 300D / Digital Rebel / Kiss Digital",
2345"Canon EOS 350D / Digital Rebel XT / Kiss Digital N",
2346"Canon EOS 400D / Digital Rebel XTi / Kiss Digital X",
2347"Canon EOS 450D / Digital Rebel XSi / Kiss Digital X2",
2348"Canon EOS 500D / Digital Rebel T1i / Kiss Digital X3",
2349"Canon EOS 550D / Digital Rebel T2i / Kiss Digital X4",
2350"Canon EOS 600D / Digital Rebel T3i / Kiss Digital X5",
2351"Canon EOS 1000D / Digital Rebel XS / Kiss Digital F",
2352"Canon EOS 1100D / Digital Rebel T3 / Kiss Digital X50",
2353"Canon EOS D2000C",
2354"Canon EOS-1D",
2355"Canon EOS-1DS",
2356"Canon EOS-1D Mark II",
2357"Canon EOS-1D Mark II N",
2358"Canon EOS-1D Mark III",
2359"Canon EOS-1D Mark IV",
2360"Canon EOS-1Ds Mark II",
2361"Canon EOS-1Ds Mark III",
2362"Casio QV-2000UX",
2363"Casio QV-3000EX",
2364"Casio QV-3500EX",
2365"Casio QV-4000",
2366"Casio QV-5700",
2367"Casio QV-R41",
2368"Casio QV-R51",
2369"Casio QV-R61",
2370"Casio EX-S20",
2371"Casio EX-S100",
2372"Casio EX-Z4",
2373"Casio EX-Z50",
2374"Casio EX-Z55",
2375"Casio EX-Z60",
2376"Casio EX-Z75",
2377"Casio EX-Z750",
2378"Casio EX-Z850",
2379"Casio EX-Z1050",
2380"Casio EX-Z1080",
2381"Casio Exlim Pro 505",
2382"Casio Exlim Pro 600",
2383"Casio Exlim Pro 700",
2384"Contax N Digital",
2385"Creative PC-CAM 600",
2386"Epson R-D1",
2387"Foculus 531C",
2388"Fuji FinePix E550",
2389"Fuji FinePix E900",
2390"Fuji FinePix F700",
2391"Fuji FinePix F710",
2392"Fuji FinePix F800",
2393"Fuji FinePix F810",
2394"Fuji FinePix S2Pro",
2395"Fuji FinePix S3Pro",
2396"Fuji FinePix S5Pro",
2397"Fuji FinePix S20Pro",
2398"Fuji FinePix S100FS",
2399"Fuji FinePix S5000",
2400"Fuji FinePix S5100/S5500",
2401"Fuji FinePix S5200/S5600",
2402"Fuji FinePix S6000fd",
2403"Fuji FinePix S7000",
2404"Fuji FinePix S9000/S9500",
2405"Fuji FinePix S9100/S9600",
2406"Fuji FinePix S200EXR",
2407"Fuji FinePix HS10/HS11",
2408"Fuji FinePix HS20EXR",
2409"Fuji FinePix F550EXR",
2410"Fuji FinePix F600EXR",
2411"Fuji FinePix X100",
2412"Fuji FinePix X10",
2413"Fuji IS-1",
2414"Hasselblad CFV",
2415"Hasselblad H3D",
2416"Hasselblad H4D",
2417"Hasselblad V96C",
2418"Imacon Ixpress 16-megapixel",
2419"Imacon Ixpress 22-megapixel",
2420"Imacon Ixpress 39-megapixel",
2421"ISG 2020x1520",
2422"Kodak DC20",
2423"Kodak DC25",
2424"Kodak DC40",
2425"Kodak DC50",
2426"Kodak DC120 (also try kdc2tiff)",
2427"Kodak DCS200",
2428"Kodak DCS315C",
2429"Kodak DCS330C",
2430"Kodak DCS420",
2431"Kodak DCS460",
2432"Kodak DCS460A",
2433"Kodak DCS520C",
2434"Kodak DCS560C",
2435"Kodak DCS620C",
2436"Kodak DCS620X",
2437"Kodak DCS660C",
2438"Kodak DCS660M",
2439"Kodak DCS720X",
2440"Kodak DCS760C",
2441"Kodak DCS760M",
2442"Kodak EOSDCS1",
2443"Kodak EOSDCS3B",
2444"Kodak NC2000F",
2445"Kodak ProBack",
2446"Kodak PB645C",
2447"Kodak PB645H",
2448"Kodak PB645M",
2449"Kodak DCS Pro 14n",
2450"Kodak DCS Pro 14nx",
2451"Kodak DCS Pro SLR/c",
2452"Kodak DCS Pro SLR/n",
2453"Kodak C330",
2454"Kodak C603",
2455"Kodak P850",
2456"Kodak P880",
2457"Kodak Z980",
2458"Kodak Z981",
2459"Kodak Z990",
2460"Kodak Z1015",
2461"Kodak KAI-0340",
2462"Konica KD-400Z",
2463"Konica KD-510Z",
2464"Leaf AFi 7",
2465"Leaf AFi-II 5",
2466"Leaf AFi-II 6",
2467"Leaf AFi-II 7",
2468"Leaf AFi-II 8",
2469"Leaf AFi-II 10",
2470"Leaf AFi-II 10R",
2471"Leaf AFi-II 12",
2472"Leaf AFi-II 12R",
2473"Leaf Aptus 17",
2474"Leaf Aptus 22",
2475"Leaf Aptus 54S",
2476"Leaf Aptus 65",
2477"Leaf Aptus 75",
2478"Leaf Aptus 75S",
2479"Leaf Cantare",
2480"Leaf CatchLight",
2481"Leaf CMost",
2482"Leaf DCB2",
2483"Leaf Valeo 6",
2484"Leaf Valeo 11",
2485"Leaf Valeo 17",
2486"Leaf Valeo 22",
2487"Leaf Volare",
2488"Leica Digilux 2",
2489"Leica Digilux 3",
2490"Leica D-LUX2",
2491"Leica D-LUX3",
2492"Leica D-LUX4",
2493"Leica D-LUX5",
2494"Leica V-LUX1",
2495"Leica V-LUX2",
2496"Logitech Fotoman Pixtura",
2497"Mamiya ZD",
2498"Micron 2010",
2499"Minolta RD175",
2500"Minolta DiMAGE 5",
2501"Minolta DiMAGE 7",
2502"Minolta DiMAGE 7i",
2503"Minolta DiMAGE 7Hi",
2504"Minolta DiMAGE A1",
2505"Minolta DiMAGE A2",
2506"Minolta DiMAGE A200",
2507"Minolta DiMAGE G400",
2508"Minolta DiMAGE G500",
2509"Minolta DiMAGE G530",
2510"Minolta DiMAGE G600",
2511"Minolta DiMAGE Z2",
2512"Minolta Alpha/Dynax/Maxxum 5D",
2513"Minolta Alpha/Dynax/Maxxum 7D",
2514"Motorola PIXL",
2515"Nikon D1",
2516"Nikon D1H",
2517"Nikon D1X",
2518"Nikon D2H",
2519"Nikon D2Hs",
2520"Nikon D2X",
2521"Nikon D2Xs",
2522"Nikon D3",
2523"Nikon D3s",
2524"Nikon D3X",
2525"Nikon D40",
2526"Nikon D40X",
2527"Nikon D50",
2528"Nikon D60",
2529"Nikon D70",
2530"Nikon D70s",
2531"Nikon D80",
2532"Nikon D90",
2533"Nikon D100",
2534"Nikon D200",
2535"Nikon D300",
2536"Nikon D300s",
2537"Nikon D700",
2538"Nikon D3000",
2539"Nikon D3100",
2540"Nikon D5000",
2541"Nikon D5100",
2542"Nikon D7000",
2543"Nikon 1 J1",
2544"Nikon 1 V1",
2545"Nikon E700 (\"DIAG RAW\" hack)",
2546"Nikon E800 (\"DIAG RAW\" hack)",
2547"Nikon E880 (\"DIAG RAW\" hack)",
2548"Nikon E900 (\"DIAG RAW\" hack)",
2549"Nikon E950 (\"DIAG RAW\" hack)",
2550"Nikon E990 (\"DIAG RAW\" hack)",
2551"Nikon E995 (\"DIAG RAW\" hack)",
2552"Nikon E2100 (\"DIAG RAW\" hack)",
2553"Nikon E2500 (\"DIAG RAW\" hack)",
2554"Nikon E3200 (\"DIAG RAW\" hack)",
2555"Nikon E3700 (\"DIAG RAW\" hack)",
2556"Nikon E4300 (\"DIAG RAW\" hack)",
2557"Nikon E4500 (\"DIAG RAW\" hack)",
2558"Nikon E5000",
2559"Nikon E5400",
2560"Nikon E5700",
2561"Nikon E8400",
2562"Nikon E8700",
2563"Nikon E8800",
2564"Nikon Coolpix P6000",
2565"Nikon Coolpix P7000",
2566"Nikon Coolpix P7100",
2567"Nikon Coolpix S6 (\"DIAG RAW\" hack)",
2568"Nokia N95",
2569"Nokia X2",
2570"Olympus C3030Z",
2571"Olympus C5050Z",
2572"Olympus C5060WZ",
2573"Olympus C7070WZ",
2574"Olympus C70Z,C7000Z",
2575"Olympus C740UZ",
2576"Olympus C770UZ",
2577"Olympus C8080WZ",
2578"Olympus X200,D560Z,C350Z",
2579"Olympus E-1",
2580"Olympus E-3",
2581"Olympus E-5",
2582"Olympus E-10",
2583"Olympus E-20",
2584"Olympus E-30",
2585"Olympus E-300",
2586"Olympus E-330",
2587"Olympus E-400",
2588"Olympus E-410",
2589"Olympus E-420",
2590"Olympus E-500",
2591"Olympus E-510",
2592"Olympus E-520",
2593"Olympus E-620",
2594"Olympus E-P1",
2595"Olympus E-P2",
2596"Olympus E-P3",
2597"Olympus E-PL1",
2598"Olympus E-PL1s",
2599"Olympus E-PL2",
2600"Olympus E-PL3",
2601"Olympus E-PM1",
2602"Olympus SP310",
2603"Olympus SP320",
2604"Olympus SP350",
2605"Olympus SP500UZ",
2606"Olympus SP510UZ",
2607"Olympus SP550UZ",
2608"Olympus SP560UZ",
2609"Olympus SP570UZ",
2610"Olympus XZ-1",
2611"Panasonic DMC-FZ8",
2612"Panasonic DMC-FZ18",
2613"Panasonic DMC-FZ28",
2614"Panasonic DMC-FZ30",
2615"Panasonic DMC-FZ35/FZ38",
2616"Panasonic DMC-FZ40",
2617"Panasonic DMC-FZ50",
2618"Panasonic DMC-FZ100",
2619"Panasonic DMC-FZ150",
2620"Panasonic DMC-FX150",
2621"Panasonic DMC-G1",
2622"Panasonic DMC-G10",
2623"Panasonic DMC-G2",
2624"Panasonic DMC-G3",
2625"Panasonic DMC-GF1",
2626"Panasonic DMC-GF2",
2627"Panasonic DMC-GF3",
2628"Panasonic DMC-GH1",
2629"Panasonic DMC-GH2",
2630"Panasonic DMC-GX1",
2631"Panasonic DMC-L1",
2632"Panasonic DMC-L10",
2633"Panasonic DMC-LC1",
2634"Panasonic DMC-LX1",
2635"Panasonic DMC-LX2",
2636"Panasonic DMC-LX3",
2637"Panasonic DMC-LX5",
2638"Pentax *ist D",
2639"Pentax *ist DL",
2640"Pentax *ist DL2",
2641"Pentax *ist DS",
2642"Pentax *ist DS2",
2643"Pentax K10D",
2644"Pentax K20D",
2645"Pentax K100D",
2646"Pentax K100D Super",
2647"Pentax K200D",
2648"Pentax K2000/K-m",
2649"Pentax K-x",
2650"Pentax K-r",
2651"Pentax K-5",
2652"Pentax K-7",
2653"Pentax Optio S",
2654"Pentax Optio S4",
2655"Pentax Optio 33WR",
2656"Pentax Optio 750Z",
2657"Pentax 645D",
2658"Phase One LightPhase",
2659"Phase One H 10",
2660"Phase One H 20",
2661"Phase One H 25",
2662"Phase One P 20",
2663"Phase One P 25",
2664"Phase One P 30",
2665"Phase One P 45",
2666"Phase One P 45+",
2667"Phase One P 65",
2668"Pixelink A782",
2669#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
2670"Polaroid x530",
2671#endif
2672#ifndef NO_JASPER
2673"Redcode R3D format",
2674#endif
2675"Rollei d530flex",
2676"RoverShot 3320af",
2677"Samsung EX1",
2678"Samsung GX-1S",
2679"Samsung GX10",
2680"Samsung GX20",
2681"Samsung NX10",
2682"Samsung NX11",
2683"Samsung NX100",
2684"Samsung NX200",
2685"Samsung WB550",
2686"Samsung WB2000",
2687"Samsung S85 (hacked)",
2688"Samsung S850 (hacked)",
2689"Sarnoff 4096x5440",
2690#ifdef LIBRAW_DEMOSAIC_PACK_GPL2
2691"Sigma SD9",
2692"Sigma SD10",
2693"Sigma SD14",
2694#endif
2695"Sinar 3072x2048",
2696"Sinar 4080x4080",
2697"Sinar 4080x5440",
2698"Sinar STI format",
2699"SMaL Ultra-Pocket 3",
2700"SMaL Ultra-Pocket 4",
2701"SMaL Ultra-Pocket 5",
2702"Sony DSC-F828",
2703"Sony DSC-R1",
2704"Sony DSC-V3",
2705"Sony DSLR-A100",
2706"Sony DSLR-A200",
2707"Sony DSLR-A230",
2708"Sony DSLR-A290",
2709"Sony DSLR-A300",
2710"Sony DSLR-A330",
2711"Sony DSLR-A350",
2712"Sony DSLR-A380",
2713"Sony DSLR-A390",
2714"Sony DSLR-A450",
2715"Sony DSLR-A500",
2716"Sony DSLR-A550",
2717"Sony DSLR-A580",
2718"Sony DSLR-A700",
2719"Sony DSLR-A850",
2720"Sony DSLR-A900",
2721"Sony NEX-3",
2722"Sony NEX-5",
2723"Sony NEX-5N",
2724"Sony NEX-7",
2725"Sony NEX-C3",
2726"Sony SLT-A33",
2727"Sony SLT-A35",
2728"Sony SLT-A55V",
2729"Sony SLT-A65V",
2730"Sony SLT-A77V",
2731"Sony XCD-SX910CR",
2732"STV680 VGA",
2733   NULL
2734};
2735
2736const char** LibRaw::cameraList() { return static_camera_list;}
2737int LibRaw::cameraCount() { return (sizeof(static_camera_list)/sizeof(static_camera_list[0]))-1; }
2738
2739
2740const char * LibRaw::strprogress(enum LibRaw_progress p)
2741{
2742    switch(p)
2743        {
2744        case LIBRAW_PROGRESS_START:
2745            return "Starting";
2746        case LIBRAW_PROGRESS_OPEN :
2747            return "Opening file";
2748        case LIBRAW_PROGRESS_IDENTIFY :
2749            return "Reading metadata";
2750        case LIBRAW_PROGRESS_SIZE_ADJUST:
2751            return "Adjusting size";
2752        case LIBRAW_PROGRESS_LOAD_RAW:
2753            return "Reading RAW data";
2754        case LIBRAW_PROGRESS_REMOVE_ZEROES:
2755            return "Clearing zero values";
2756        case LIBRAW_PROGRESS_BAD_PIXELS :
2757            return "Removing dead pixels";
2758        case LIBRAW_PROGRESS_DARK_FRAME:
2759            return "Subtracting dark frame data";
2760        case LIBRAW_PROGRESS_FOVEON_INTERPOLATE:
2761            return "Interpolating Foveon sensor data";
2762        case LIBRAW_PROGRESS_SCALE_COLORS:
2763            return "Scaling colors";
2764        case LIBRAW_PROGRESS_PRE_INTERPOLATE:
2765            return "Pre-interpolating";
2766        case LIBRAW_PROGRESS_INTERPOLATE:
2767            return "Interpolating";
2768        case LIBRAW_PROGRESS_MIX_GREEN :
2769            return "Mixing green channels";
2770        case LIBRAW_PROGRESS_MEDIAN_FILTER   :
2771            return "Median filter";
2772        case LIBRAW_PROGRESS_HIGHLIGHTS:
2773            return "Highlight recovery";
2774        case LIBRAW_PROGRESS_FUJI_ROTATE :
2775            return "Rotating Fuji diagonal data";
2776        case LIBRAW_PROGRESS_FLIP :
2777            return "Flipping image";
2778        case LIBRAW_PROGRESS_APPLY_PROFILE:
2779            return "ICC conversion";
2780        case LIBRAW_PROGRESS_CONVERT_RGB:
2781            return "Converting to RGB";
2782        case LIBRAW_PROGRESS_STRETCH:
2783            return "Stretching image";
2784        case LIBRAW_PROGRESS_THUMB_LOAD:
2785            return "Loading thumbnail";
2786        default:
2787            return "Some strange things";
2788        }
2789}