File indexing completed on 2025-01-05 03:56:57

0001 /* -*- C++ -*-
0002  * Copyright 2019-2021 LibRaw LLC (info@libraw.org)
0003  *
0004  LibRaw is free software; you can redistribute it and/or modify
0005  it under the terms of the one of two licenses as you choose:
0006 
0007 1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
0008    (See file LICENSE.LGPL provided in LibRaw distribution archive for details).
0009 
0010 2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
0011    (See file LICENSE.CDDL provided in LibRaw distribution archive for details).
0012 
0013  */
0014 
0015 #include "../../internal/libraw_cxx_defs.h"
0016 
0017 #ifdef USE_RAWSPEED
0018 using namespace RawSpeed;
0019 
0020 CameraMetaDataLR::CameraMetaDataLR(char *data, int sz) : CameraMetaData()
0021 {
0022   ctxt = xmlNewParserCtxt();
0023   if (ctxt == NULL)
0024   {
0025     ThrowCME("CameraMetaData:Could not initialize context.");
0026   }
0027 
0028   xmlResetLastError();
0029   doc = xmlCtxtReadMemory(ctxt, data, sz, "", NULL, XML_PARSE_DTDVALID);
0030 
0031   if (doc == NULL)
0032   {
0033     ThrowCME("CameraMetaData: XML Document could not be parsed successfully. "
0034              "Error was: %s",
0035              ctxt->lastError.message);
0036   }
0037 
0038   if (ctxt->valid == 0)
0039   {
0040     if (ctxt->lastError.code == 0x5e)
0041     {
0042       // ignore this error code
0043     }
0044     else
0045     {
0046       ThrowCME("CameraMetaData: XML file does not validate. DTD Error was: %s",
0047                ctxt->lastError.message);
0048     }
0049   }
0050 
0051   xmlNodePtr cur;
0052   cur = xmlDocGetRootElement(doc);
0053   if (xmlStrcmp(cur->name, (const xmlChar *)"Cameras"))
0054   {
0055     ThrowCME("CameraMetaData: XML document of the wrong type, root node is not "
0056              "cameras.");
0057     return;
0058   }
0059 
0060   cur = cur->xmlChildrenNode;
0061   while (cur != NULL)
0062   {
0063     if ((!xmlStrcmp(cur->name, (const xmlChar *)"Camera")))
0064     {
0065       Camera *camera = new Camera(doc, cur);
0066       addCamera(camera);
0067 
0068       // Create cameras for aliases.
0069       for (unsigned int i = 0; i < camera->aliases.size(); i++)
0070       {
0071         addCamera(new Camera(camera, i));
0072       }
0073     }
0074     cur = cur->next;
0075   }
0076   if (doc)
0077     xmlFreeDoc(doc);
0078   doc = 0;
0079   if (ctxt)
0080     xmlFreeParserCtxt(ctxt);
0081   ctxt = 0;
0082 }
0083 
0084 CameraMetaDataLR *make_camera_metadata()
0085 {
0086   int len = 0, i;
0087   for (i = 0; i < RAWSPEED_DATA_COUNT; i++)
0088     if (_rawspeed_data_xml[i])
0089     {
0090       len += int(strlen(_rawspeed_data_xml[i]));
0091     }
0092   char *rawspeed_xml =
0093       (char *)calloc(len + 1, sizeof(_rawspeed_data_xml[0][0]));
0094   if (!rawspeed_xml)
0095     return NULL;
0096   int offt = 0;
0097   for (i = 0; i < RAWSPEED_DATA_COUNT; i++)
0098     if (_rawspeed_data_xml[i])
0099     {
0100       int ll = int(strlen(_rawspeed_data_xml[i]));
0101       if (offt + ll > len)
0102         break;
0103       memmove(rawspeed_xml + offt, _rawspeed_data_xml[i], ll);
0104       offt += ll;
0105     }
0106   rawspeed_xml[offt] = 0;
0107   CameraMetaDataLR *ret = NULL;
0108   try
0109   {
0110     ret = new CameraMetaDataLR(rawspeed_xml, offt);
0111   }
0112   catch (...)
0113   {
0114     // Mask all exceptions
0115   }
0116   free(rawspeed_xml);
0117   return ret;
0118 }
0119 
0120 #endif
0121 
0122 int LibRaw::set_rawspeed_camerafile(char * filename)
0123 {
0124 #ifdef USE_RAWSPEED
0125   try
0126   {
0127     CameraMetaDataLR *camerameta = new CameraMetaDataLR(filename);
0128     if (_rawspeed_camerameta)
0129     {
0130       CameraMetaDataLR *d =
0131           static_cast<CameraMetaDataLR *>(_rawspeed_camerameta);
0132       delete d;
0133     }
0134     _rawspeed_camerameta = static_cast<void *>(camerameta);
0135   }
0136   catch (...)
0137   {
0138     // just return error code
0139     return -1;
0140   }
0141 #else
0142     (void)filename;
0143 #endif
0144   return 0;
0145 }
0146 #ifdef USE_RAWSPEED
0147 void LibRaw::fix_after_rawspeed(int /*bl*/)
0148 {
0149   if (load_raw == &LibRaw::lossy_dng_load_raw)
0150     C.maximum = 0xffff;
0151   else if (load_raw == &LibRaw::sony_load_raw)
0152     C.maximum = 0x3ff0;
0153 }
0154 #else
0155 void LibRaw::fix_after_rawspeed(int) {}
0156 #endif
0157 
0158 int LibRaw::try_rawspeed()
0159 {
0160 #ifdef USE_RAWSPEED
0161   int ret = LIBRAW_SUCCESS;
0162 
0163 #ifdef USE_RAWSPEED_BITS
0164   int rawspeed_ignore_errors = (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV1_IGNOREERRORS);
0165 #else
0166   int rawspeed_ignore_errors = 0;
0167 #endif
0168   if (imgdata.idata.dng_version && imgdata.idata.colors == 3 &&
0169       !strcasecmp(imgdata.idata.software,
0170                   "Adobe Photoshop Lightroom 6.1.1 (Windows)"))
0171     rawspeed_ignore_errors = 1;
0172 
0173   // RawSpeed Supported,
0174   INT64 spos = ID.input->tell();
0175   void *_rawspeed_buffer = 0;
0176   try
0177   {
0178     ID.input->seek(0, SEEK_SET);
0179     INT64 _rawspeed_buffer_sz = ID.input->size() + 32;
0180     _rawspeed_buffer = malloc(_rawspeed_buffer_sz);
0181     if (!_rawspeed_buffer)
0182       throw LIBRAW_EXCEPTION_ALLOC;
0183     ID.input->read(_rawspeed_buffer, _rawspeed_buffer_sz, 1);
0184     FileMap map((uchar8 *)_rawspeed_buffer, _rawspeed_buffer_sz);
0185     RawParser t(&map);
0186     RawDecoder *d = 0;
0187     CameraMetaDataLR *meta =
0188         static_cast<CameraMetaDataLR *>(_rawspeed_camerameta);
0189     d = t.getDecoder();
0190     if (!d)
0191       throw "Unable to find decoder";
0192 
0193 #ifdef USE_RAWSPEED_BITS
0194     if (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV1_FAILONUNKNOWN)
0195       d->failOnUnknown = TRUE;
0196     else
0197         d->failOnUnknown = FALSE;
0198 #endif
0199     d->interpolateBadPixels = FALSE;
0200     d->applyStage1DngOpcodes = FALSE;
0201 
0202     try
0203     {
0204       d->checkSupport(meta);
0205     }
0206     catch (const RawDecoderException &e)
0207     {
0208       imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_UNSUPPORTED;
0209       throw e;
0210     }
0211     _rawspeed_decoder = static_cast<void *>(d);
0212     d->decodeRaw();
0213     d->decodeMetaData(meta);
0214     RawImage r = d->mRaw;
0215     if (r->errors.size() > 0 && !rawspeed_ignore_errors)
0216     {
0217       delete d;
0218       _rawspeed_decoder = 0;
0219       throw 1;
0220     }
0221     if (r->isCFA)
0222     {
0223       imgdata.rawdata.raw_image = (ushort *)r->getDataUncropped(0, 0);
0224     }
0225     else if (r->getCpp() == 4)
0226     {
0227       imgdata.rawdata.color4_image = (ushort(*)[4])r->getDataUncropped(0, 0);
0228       if (r->whitePoint > 0 && r->whitePoint < 65536)
0229         C.maximum = r->whitePoint;
0230     }
0231     else if (r->getCpp() == 3)
0232     {
0233       imgdata.rawdata.color3_image = (ushort(*)[3])r->getDataUncropped(0, 0);
0234       if (r->whitePoint > 0 && r->whitePoint < 65536)
0235         C.maximum = r->whitePoint;
0236     }
0237     else
0238     {
0239       delete d;
0240       _rawspeed_decoder = 0;
0241       ret = LIBRAW_UNSPECIFIED_ERROR;
0242     }
0243     if (_rawspeed_decoder)
0244     {
0245       // set sizes
0246       iPoint2D rsdim = r->getUncroppedDim();
0247       S.raw_pitch = r->pitch;
0248       S.raw_width = rsdim.x;
0249       S.raw_height = rsdim.y;
0250       // C.maximum = r->whitePoint;
0251       fix_after_rawspeed(r->blackLevel);
0252     }
0253     free(_rawspeed_buffer);
0254     _rawspeed_buffer = 0;
0255     imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROCESSED;
0256   }
0257   catch (const RawDecoderException &RDE)
0258   {
0259     imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROBLEM;
0260     if (_rawspeed_buffer)
0261     {
0262       free(_rawspeed_buffer);
0263       _rawspeed_buffer = 0;
0264     }
0265     if (!strncmp(RDE.what(), "Decoder canceled", strlen("Decoder canceled")))
0266       throw LIBRAW_EXCEPTION_CANCELLED_BY_CALLBACK;
0267     ret = LIBRAW_UNSPECIFIED_ERROR;
0268   }
0269   catch (...)
0270   {
0271     // We may get here due to cancellation flag
0272     imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_PROBLEM;
0273     if (_rawspeed_buffer)
0274     {
0275       free(_rawspeed_buffer);
0276       _rawspeed_buffer = 0;
0277     }
0278     ret = LIBRAW_UNSPECIFIED_ERROR;
0279   }
0280   ID.input->seek(spos, SEEK_SET);
0281 
0282   return ret;
0283 #else
0284   return LIBRAW_NOT_IMPLEMENTED;
0285 #endif
0286 }