File indexing completed on 2025-01-05 03:56:54
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 #include "../../internal/libraw_cameraids.h" 0015 #include "../../internal/libraw_cxx_defs.h" 0016 0017 #ifdef USE_RAWSPEED3 0018 #include "rawspeed3_capi.h" 0019 #include <array> 0020 #endif 0021 0022 int LibRaw::unpack(void) 0023 { 0024 CHECK_ORDER_HIGH(LIBRAW_PROGRESS_LOAD_RAW); 0025 CHECK_ORDER_LOW(LIBRAW_PROGRESS_IDENTIFY); 0026 try 0027 { 0028 0029 if (!libraw_internal_data.internal_data.input) 0030 return LIBRAW_INPUT_CLOSED; 0031 0032 RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW, 0, 2); 0033 if (imgdata.rawparams.shot_select >= P1.raw_count) 0034 return LIBRAW_REQUEST_FOR_NONEXISTENT_IMAGE; 0035 0036 if (!load_raw) 0037 return LIBRAW_UNSPECIFIED_ERROR; 0038 0039 // already allocated ? 0040 if (imgdata.image) 0041 { 0042 free(imgdata.image); 0043 imgdata.image = 0; 0044 } 0045 if (imgdata.rawdata.raw_alloc) 0046 { 0047 free(imgdata.rawdata.raw_alloc); 0048 imgdata.rawdata.raw_alloc = 0; 0049 } 0050 if (libraw_internal_data.unpacker_data.meta_length) 0051 { 0052 if (libraw_internal_data.unpacker_data.meta_length > 0053 INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) 0054 throw LIBRAW_EXCEPTION_TOOBIG; 0055 0056 libraw_internal_data.internal_data.meta_data = 0057 (char *)malloc(libraw_internal_data.unpacker_data.meta_length); 0058 } 0059 0060 libraw_decoder_info_t decoder_info; 0061 get_decoder_info(&decoder_info); 0062 0063 int save_iwidth = S.iwidth, save_iheight = S.iheight, 0064 save_shrink = IO.shrink; 0065 0066 int rwidth = S.raw_width, rheight = S.raw_height; 0067 if (!IO.fuji_width) 0068 { 0069 // adjust non-Fuji allocation 0070 if (rwidth < S.width + S.left_margin) 0071 rwidth = S.width + S.left_margin; 0072 if (rheight < S.height + S.top_margin) 0073 rheight = S.height + S.top_margin; 0074 } 0075 if (rwidth > 65535 || 0076 rheight > 65535) // No way to make image larger than 64k pix 0077 throw LIBRAW_EXCEPTION_IO_CORRUPT; 0078 0079 imgdata.rawdata.raw_image = 0; 0080 imgdata.rawdata.color4_image = 0; 0081 imgdata.rawdata.color3_image = 0; 0082 imgdata.rawdata.float_image = 0; 0083 imgdata.rawdata.float3_image = 0; 0084 0085 #ifdef USE_DNGSDK 0086 if (imgdata.idata.dng_version && dnghost 0087 && libraw_internal_data.unpacker_data.tiff_samples != 2 // Fuji SuperCCD; it is better to detect is more rigid way 0088 && valid_for_dngsdk() && load_raw != &LibRaw::pentax_4shot_load_raw) 0089 { 0090 // Data size check 0091 INT64 pixcount = 0092 INT64(MAX(S.width, S.raw_width)) * INT64(MAX(S.height, S.raw_height)); 0093 INT64 planecount = 0094 (imgdata.idata.filters || P1.colors == 1) ? 1 : LIM(P1.colors, 3, 4); 0095 INT64 samplesize = is_floating_point() ? 4 : 2; 0096 INT64 bytes = pixcount * planecount * samplesize; 0097 if (bytes + INT64(libraw_internal_data.unpacker_data.meta_length ) 0098 > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) 0099 throw LIBRAW_EXCEPTION_TOOBIG; 0100 0101 // find ifd to check sample 0102 try_dngsdk(); 0103 if (raw_was_read()) 0104 imgdata.process_warnings |= LIBRAW_WARN_DNGSDK_PROCESSED; 0105 } 0106 #endif 0107 #ifdef USE_RAWSPEED3 0108 if (!raw_was_read() 0109 && (!IO.fuji_width) // Do not use for fuji rotated 0110 && ((imgdata.idata.raw_count == 1) 0111 // Canon dual pixel, 1st frame 0112 || (makeIs(LIBRAW_CAMERAMAKER_Canon) && imgdata.idata.raw_count == 2 && imgdata.rawparams.shot_select==0) 0113 ) 0114 #ifdef USE_RAWSPEED_BITS 0115 && (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV3_USE) 0116 #else 0117 && imgdata.rawparams.use_rawspeed 0118 #endif 0119 && (decoder_info.decoder_flags & LIBRAW_DECODER_TRYRAWSPEED3) 0120 ) 0121 { 0122 INT64 pixcount = INT64(MAX(S.width, S.raw_width)) * INT64(MAX(S.height, S.raw_height)); 0123 INT64 planecount = (imgdata.idata.filters || P1.colors == 1) ? 1 : LIM(P1.colors, 3, 4); 0124 INT64 bytes = pixcount * planecount * 2; // sample size is always 2 for rawspeed 0125 if (bytes + INT64(libraw_internal_data.unpacker_data.meta_length) 0126 > INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) 0127 throw LIBRAW_EXCEPTION_TOOBIG; 0128 0129 if (!_rawspeed3_handle) 0130 _rawspeed3_handle = rawspeed3_initdefault(); 0131 0132 if (_rawspeed3_handle && ID.input->size() > 0) // large bound is checked at identify 0133 { 0134 void *_rawspeed_buffer = 0; 0135 try { 0136 ID.input->seek(0, SEEK_SET); 0137 INT64 _rawspeed_buffer_sz = ID.input->size() + 32; 0138 _rawspeed_buffer = malloc(_rawspeed_buffer_sz); 0139 if (!_rawspeed_buffer) 0140 throw LIBRAW_EXCEPTION_ALLOC; 0141 ID.input->read(_rawspeed_buffer, ID.input->size(), 1); 0142 0143 rawspeed3_ret_t rs3ret; 0144 rawspeed3_clearresult(&rs3ret); 0145 int status = rawspeed3_decodefile(_rawspeed3_handle, &rs3ret, _rawspeed_buffer, ID.input->size(), 0146 #ifdef USE_RAWSPEED_BITS 0147 !(imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV3_FAILONUNKNOWN) 0148 #else 0149 false 0150 #endif 0151 ); 0152 if (status != rawspeed3_ok) 0153 imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED_UNSUPPORTED; 0154 0155 if (status == rawspeed3_not_supported) 0156 imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED3_NOTLISTED; 0157 0158 if (status == rawspeed3_ok 0159 #ifdef USE_RAWSPEED_BITS 0160 || 0161 (status == rawspeed3_ok_warnings && (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV3_IGNOREERRORS)) 0162 #endif 0163 ) 0164 { 0165 0166 if ((S.raw_width != rs3ret.width) || (S.raw_height != rs3ret.height)) 0167 throw "Size mismatch"; 0168 0169 // DECODED w/ success 0170 if (rs3ret.filters>1) // Fuji or bayer 0171 imgdata.rawdata.raw_image = (ushort*)rs3ret.pixeldata; 0172 else if (rs3ret.cpp == 4) 0173 { 0174 imgdata.rawdata.color4_image = (ushort(*)[4])rs3ret.pixeldata; 0175 //if (r->whitePoint > 0 && r->whitePoint < 65536) 0176 // C.maximum = r->whitePoint; 0177 } 0178 else if (rs3ret.cpp == 3) 0179 { 0180 imgdata.rawdata.color3_image = (ushort(*)[3])rs3ret.pixeldata; 0181 //if (r->whitePoint > 0 && r->whitePoint < 65536) 0182 // C.maximum = r->whitePoint; 0183 } 0184 0185 if (raw_was_read()) // buffers are assigned above 0186 { 0187 // set sizes 0188 S.raw_pitch = rs3ret.pitch; 0189 S.raw_width = rs3ret.width; 0190 S.raw_height = rs3ret.height; 0191 imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED3_PROCESSED; 0192 // if (r->whitePoint > 0 && r->whitePoint < 65536) 0193 // C.maximum = r->whitePoint; 0194 } 0195 } 0196 free(_rawspeed_buffer); 0197 } 0198 catch (...) 0199 { 0200 imgdata.process_warnings |= LIBRAW_WARN_RAWSPEED3_PROBLEM; 0201 if (_rawspeed_buffer) 0202 free(_rawspeed_buffer); 0203 } 0204 } 0205 } 0206 #endif 0207 #ifdef USE_RAWSPEED 0208 if (!raw_was_read()) 0209 { 0210 int rawspeed_enabled = 1; 0211 0212 if (imgdata.idata.dng_version && (libraw_internal_data.unpacker_data.tiff_samples == 2 || imgdata.idata.raw_count > 1)) 0213 rawspeed_enabled = 0; 0214 0215 if (libraw_internal_data.unpacker_data.is_NikonTransfer) 0216 rawspeed_enabled = 0; 0217 0218 if (libraw_internal_data.unpacker_data.pana_encoding == 5) 0219 rawspeed_enabled = 0; 0220 0221 if (imgdata.idata.raw_count > 1) 0222 rawspeed_enabled = 0; 0223 if (!strncasecmp(imgdata.idata.software, "Magic", 5)) 0224 rawspeed_enabled = 0; 0225 // Disable rawspeed for double-sized Oly files 0226 if (makeIs(LIBRAW_CAMERAMAKER_Olympus) && 0227 ((imgdata.sizes.raw_width > 6000) || 0228 !strncasecmp(imgdata.idata.model, "SH-", 3) || 0229 !strncasecmp(imgdata.idata.model, "TG-", 3) )) 0230 rawspeed_enabled = 0; 0231 0232 if (makeIs(LIBRAW_CAMERAMAKER_Canon) && 0233 (libraw_internal_data.identify_data.unique_id == CanonID_EOS_6D_Mark_II)) 0234 rawspeed_enabled = 0; 0235 0236 if (imgdata.idata.dng_version && imgdata.idata.filters == 0 && 0237 libraw_internal_data.unpacker_data.tiff_bps == 8) // Disable for 8 bit 0238 rawspeed_enabled = 0; 0239 0240 if (load_raw == &LibRaw::packed_load_raw && 0241 makeIs(LIBRAW_CAMERAMAKER_Nikon) && 0242 (!strncasecmp(imgdata.idata.model, "E", 1) || 0243 !strncasecmp(imgdata.idata.model, "COOLPIX B", 9) || 0244 !strncasecmp(imgdata.idata.model, "COOLPIX P9", 10) || 0245 !strncasecmp(imgdata.idata.model, "COOLPIX P1000", 13))) 0246 rawspeed_enabled = 0; 0247 0248 if (load_raw == &LibRaw::nikon_load_raw && makeIs(LIBRAW_CAMERAMAKER_Nikon) && 0249 !strcasecmp(imgdata.idata.model, "D6")) 0250 rawspeed_enabled = 0; 0251 0252 if (load_raw == &LibRaw::lossless_jpeg_load_raw && 0253 MN.canon.RecordMode && makeIs(LIBRAW_CAMERAMAKER_Kodak) && 0254 /* Not normalized models here, it is intentional */ 0255 (!strncasecmp(imgdata.idata.model, "EOS D2000", 9) || 0256 !strncasecmp(imgdata.idata.model, "EOS D6000", 9))) 0257 rawspeed_enabled = 0; 0258 0259 if (load_raw == &LibRaw::nikon_load_raw && 0260 makeIs(LIBRAW_CAMERAMAKER_Nikon) && 0261 (!strncasecmp(imgdata.idata.model, "Z", 1) || !strncasecmp(imgdata.idata.model,"D780",4))) 0262 rawspeed_enabled = 0; 0263 0264 if (load_raw == &LibRaw::panasonic_load_raw && 0265 libraw_internal_data.unpacker_data.pana_encoding > 4) 0266 rawspeed_enabled = 0; 0267 0268 // RawSpeed Supported, 0269 if ( 0270 #ifdef USE_RAWSPEED_BITS 0271 (imgdata.rawparams.use_rawspeed & LIBRAW_RAWSPEEDV1_USE) 0272 #else 0273 imgdata.rawparams.use_rawspeed 0274 #endif 0275 && rawspeed_enabled && 0276 !(is_sraw() && (imgdata.rawparams.specials & 0277 (LIBRAW_RAWSPECIAL_SRAW_NO_RGB | 0278 LIBRAW_RAWSPECIAL_SRAW_NO_INTERPOLATE))) && 0279 (decoder_info.decoder_flags & LIBRAW_DECODER_TRYRAWSPEED) && 0280 _rawspeed_camerameta) 0281 { 0282 INT64 pixcount = INT64(MAX(S.width, S.raw_width)) * 0283 INT64(MAX(S.height, S.raw_height)); 0284 INT64 planecount = (imgdata.idata.filters || P1.colors == 1) 0285 ? 1 0286 : LIM(P1.colors, 3, 4); 0287 INT64 bytes = 0288 pixcount * planecount * 2; // sample size is always 2 for rawspeed 0289 if (bytes + +INT64(libraw_internal_data.unpacker_data.meta_length) > 0290 INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) 0291 throw LIBRAW_EXCEPTION_TOOBIG; 0292 0293 /*int rr = */ try_rawspeed(); 0294 0295 } 0296 } 0297 #endif 0298 if (!raw_was_read()) // RawSpeed failed or not run 0299 { 0300 // Not allocated on RawSpeed call, try call LibRaow 0301 int zero_rawimage = 0; 0302 if (decoder_info.decoder_flags & LIBRAW_DECODER_OWNALLOC) 0303 { 0304 // x3f foveon decoder and DNG float 0305 // Do nothing! Decoder will allocate data internally 0306 } 0307 if (decoder_info.decoder_flags & LIBRAW_DECODER_SINAR4SHOT) 0308 { 0309 if (imgdata.rawparams.shot_select) // single image extract 0310 { 0311 if (INT64(rwidth) * INT64(rheight + 8) * 0312 INT64(sizeof(imgdata.rawdata.raw_image[0])) 0313 + +INT64(libraw_internal_data.unpacker_data.meta_length) > 0314 INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) 0315 throw LIBRAW_EXCEPTION_TOOBIG; 0316 imgdata.rawdata.raw_alloc = malloc( 0317 rwidth * (rheight + 8) * sizeof(imgdata.rawdata.raw_image[0])); 0318 imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc; 0319 if (!S.raw_pitch) 0320 S.raw_pitch = S.raw_width * 2; // Bayer case, not set before 0321 } 0322 else // Full image extract 0323 { 0324 if (INT64(rwidth) * INT64(rheight + 8) * 0325 INT64(sizeof(imgdata.rawdata.raw_image[0])) * 4 0326 +INT64(libraw_internal_data.unpacker_data.meta_length) > 0327 INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) 0328 throw LIBRAW_EXCEPTION_TOOBIG; 0329 S.raw_pitch = S.raw_width * 8; 0330 imgdata.rawdata.raw_alloc = 0; 0331 imgdata.image = (ushort(*)[4])calloc( 0332 unsigned(MAX(S.width, S.raw_width)) * 0333 unsigned(MAX(S.height, S.raw_height) + 8), 0334 sizeof(*imgdata.image)); 0335 } 0336 } 0337 else if (decoder_info.decoder_flags & LIBRAW_DECODER_3CHANNEL) 0338 { 0339 if (INT64(rwidth) * INT64(rheight + 8) * 0340 INT64(sizeof(imgdata.rawdata.raw_image[0])) * 3 0341 + INT64(libraw_internal_data.unpacker_data.meta_length) > 0342 INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) 0343 throw LIBRAW_EXCEPTION_TOOBIG; 0344 0345 imgdata.rawdata.raw_alloc = malloc( 0346 rwidth * (rheight + 8) * sizeof(imgdata.rawdata.raw_image[0]) * 3); 0347 imgdata.rawdata.color3_image = (ushort(*)[3])imgdata.rawdata.raw_alloc; 0348 if (!S.raw_pitch) 0349 S.raw_pitch = S.raw_width * 6; 0350 } 0351 else if (imgdata.idata.filters || 0352 P1.colors == 0353 1) // Bayer image or single color -> decode to raw_image 0354 { 0355 if (INT64(rwidth) * INT64(rheight + 8) * 0356 INT64(sizeof(imgdata.rawdata.raw_image[0])) 0357 + INT64(libraw_internal_data.unpacker_data.meta_length) > 0358 INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) 0359 throw LIBRAW_EXCEPTION_TOOBIG; 0360 imgdata.rawdata.raw_alloc = malloc( 0361 rwidth * (rheight + 8) * sizeof(imgdata.rawdata.raw_image[0])); 0362 imgdata.rawdata.raw_image = (ushort *)imgdata.rawdata.raw_alloc; 0363 if (!S.raw_pitch) 0364 S.raw_pitch = S.raw_width * 2; // Bayer case, not set before 0365 } 0366 else // NO LEGACY FLAG if (decoder_info.decoder_flags & 0367 // LIBRAW_DECODER_LEGACY) 0368 { 0369 if (decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL) 0370 { 0371 S.raw_pitch = S.raw_width * 8; 0372 } 0373 else 0374 { 0375 S.iwidth = S.width; 0376 S.iheight = S.height; 0377 IO.shrink = 0; 0378 if (!S.raw_pitch) 0379 S.raw_pitch = (decoder_info.decoder_flags & 0380 LIBRAW_DECODER_LEGACY_WITH_MARGINS) 0381 ? S.raw_width * 8 0382 : S.width * 8; 0383 } 0384 // sRAW and old Foveon decoders only, so extra buffer size is just 1/4 0385 // allocate image as temporary buffer, size 0386 if (INT64(MAX(S.width, S.raw_width)) * 0387 INT64(MAX(S.height, S.raw_height) + 8) * 0388 INT64(sizeof(*imgdata.image)) 0389 + INT64(libraw_internal_data.unpacker_data.meta_length) > 0390 INT64(imgdata.rawparams.max_raw_memory_mb) * INT64(1024 * 1024)) 0391 throw LIBRAW_EXCEPTION_TOOBIG; 0392 0393 imgdata.rawdata.raw_alloc = 0; 0394 imgdata.image = 0395 (ushort(*)[4])calloc(unsigned(MAX(S.width, S.raw_width)) * 0396 unsigned(MAX(S.height, S.raw_height) + 8), 0397 sizeof(*imgdata.image)); 0398 if (!(decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL)) 0399 { 0400 imgdata.rawdata.raw_image = (ushort *)imgdata.image; 0401 zero_rawimage = 1; 0402 } 0403 } 0404 ID.input->seek(libraw_internal_data.unpacker_data.data_offset, SEEK_SET); 0405 0406 unsigned m_save = C.maximum; 0407 if (load_raw == &LibRaw::unpacked_load_raw && 0408 (!strcasecmp(imgdata.idata.make, "Nikon") || !strcasecmp(imgdata.idata.make, "Hasselblad")) 0409 ) 0410 C.maximum = 65535; 0411 (this->*load_raw)(); 0412 if (zero_rawimage) 0413 imgdata.rawdata.raw_image = 0; 0414 if (load_raw == &LibRaw::unpacked_load_raw && 0415 (!strcasecmp(imgdata.idata.make, "Nikon") || !strcasecmp(imgdata.idata.make, "Hasselblad")) 0416 ) 0417 C.maximum = m_save; 0418 if (decoder_info.decoder_flags & LIBRAW_DECODER_OWNALLOC) 0419 { 0420 // x3f foveon decoder only: do nothing 0421 } 0422 else if (decoder_info.decoder_flags & LIBRAW_DECODER_SINAR4SHOT && 0423 imgdata.rawparams.shot_select == 0) 0424 { 0425 imgdata.rawdata.raw_alloc = imgdata.image; 0426 imgdata.rawdata.color4_image = (ushort(*)[4])imgdata.rawdata.raw_alloc; 0427 imgdata.image = 0; 0428 } 0429 else if (!(imgdata.idata.filters || 0430 P1.colors == 1)) // legacy decoder, ownalloc handled above 0431 { 0432 // successfully decoded legacy image, attach image to raw_alloc 0433 imgdata.rawdata.raw_alloc = imgdata.image; 0434 imgdata.rawdata.color4_image = (ushort(*)[4])imgdata.rawdata.raw_alloc; 0435 imgdata.image = 0; 0436 // Restore saved values. Note: Foveon have masked frame 0437 // Other 4-color legacy data: no borders 0438 if (!(libraw_internal_data.unpacker_data.load_flags & 256) && 0439 !(decoder_info.decoder_flags & LIBRAW_DECODER_ADOBECOPYPIXEL) && 0440 !(decoder_info.decoder_flags & LIBRAW_DECODER_LEGACY_WITH_MARGINS)) 0441 { 0442 S.raw_width = S.width; 0443 S.left_margin = 0; 0444 S.raw_height = S.height; 0445 S.top_margin = 0; 0446 } 0447 } 0448 } 0449 0450 if (imgdata.rawdata.raw_image) 0451 crop_masked_pixels(); // calculate black levels 0452 0453 // recover image sizes 0454 S.iwidth = save_iwidth; 0455 S.iheight = save_iheight; 0456 IO.shrink = save_shrink; 0457 0458 // adjust black to possible maximum 0459 unsigned int i = C.cblack[3]; 0460 unsigned int c; 0461 for (c = 0; c < 3; c++) 0462 if (i > C.cblack[c]) 0463 i = C.cblack[c]; 0464 for (c = 0; c < 4; c++) 0465 C.cblack[c] -= i; 0466 C.black += i; 0467 0468 // Save color,sizes and internal data into raw_image fields 0469 memmove(&imgdata.rawdata.color, &imgdata.color, sizeof(imgdata.color)); 0470 memmove(&imgdata.rawdata.sizes, &imgdata.sizes, sizeof(imgdata.sizes)); 0471 memmove(&imgdata.rawdata.iparams, &imgdata.idata, sizeof(imgdata.idata)); 0472 memmove(&imgdata.rawdata.ioparams, 0473 &libraw_internal_data.internal_output_params, 0474 sizeof(libraw_internal_data.internal_output_params)); 0475 0476 SET_PROC_FLAG(LIBRAW_PROGRESS_LOAD_RAW); 0477 RUN_CALLBACK(LIBRAW_PROGRESS_LOAD_RAW, 1, 2); 0478 0479 return 0; 0480 } 0481 catch (const std::bad_alloc&) 0482 { 0483 EXCEPTION_HANDLER(LIBRAW_EXCEPTION_ALLOC); 0484 } 0485 catch (const LibRaw_exceptions& err) 0486 { 0487 EXCEPTION_HANDLER(err); 0488 } 0489 catch (const std::exception& ) 0490 { 0491 EXCEPTION_HANDLER(LIBRAW_EXCEPTION_IO_CORRUPT); 0492 } 0493 }