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 }