void JPEGWriter::Create( const String& filePath, int count ) { if ( IsOpen() ) throw InvalidWriteOperation( path ); if ( filePath.IsEmpty() ) throw InvalidFilePath( filePath ); if ( count <= 0 ) throw NotImplemented( *this, "Write empty JPEG files" ); if ( count > 1 ) throw NotImplemented( *this, "Write multiple images to a single JPEG file" ); Reset(); if ( fileData == nullptr ) fileData = new JPEGFileData; #ifdef __PCL_WINDOWS path = File::WindowsPathToUnix( filePath ); #else path = filePath; #endif }
Node* Win32Driver::mount(const FilePath& path, const String& nativePath) { if (nativePath.find('?') != NPOS || nativePath.find('*') != NPOS || nativePath.size() == 0) { throw InvalidFilePath(nativePath.c_str()); } FileName name = path.fileName(); WideString wpath; UTF8ToUCS2(wpath, nativePath); wpath.subst('/', '\\'); while (wpath.back() == '\\') wpath.pop(); Win32Node* node = new Win32Node(name, wpath); return node; }
void JPEGReader::Open( const String& _path ) { if ( IsOpen() ) throw InvalidReadOperation( path ); if ( _path.IsEmpty() ) throw InvalidFilePath( _path ); if ( options.lowerRange >= options.upperRange ) throw InvalidNormalizationRange( _path ); info.Reset(); try { fileData = new JPEGFileData; #ifdef __PCL_WINDOWS path = File::WindowsPathToUnix( _path ); #else path = _path; #endif // Keep critical parameters secured in private data. fileData->lowerRange = options.lowerRange; fileData->upperRange = options.upperRange; IsoString path8 = #ifdef __PCL_WINDOWS File::UnixPathToWindows( path ).ToMBS(); #else path.ToUTF8(); #endif fileData->handle = ::fopen( path8.c_str(), "rb" ); if ( fileData->handle == 0 ) throw UnableToOpenFile( path ); // Allocate and initialize a JPEG decompression object. // This struct contains the JPEG decompression parameters and pointers to // working space, which is allocated as needed by the IJG library. fileData->decompressor = new ::jpeg_decompress_struct; // Set up normal JPEG error routines, passing a pointer to our custom // error handler structure. jpeg_decompressor->err = ::jpeg_std_error( (::jpeg_error_mgr*) (fileData->errorManager = new JPEGErrorManager( path )) ); // Override error_exit. JPEG library errors will be handled by throwing // exceptions from the JPEGErrorExit() routine. ((JPEGErrorManager*)fileData->errorManager)->error.error_exit = JPEGErrorExit; // Initialize the JPEG decompression object. ::jpeg_create_decompress( jpeg_decompressor ); // Specify data source (e.g., a file). ::jpeg_stdio_src( jpeg_decompressor, fileData->handle ); // Read file parameters with ::jpeg_read_header(). ::jpeg_save_markers( jpeg_decompressor, JPEG_COM, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+ 0, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+ 1, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+ 2, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+ 3, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+ 4, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+ 5, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+ 6, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+ 7, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+ 8, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+ 9, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+10, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+11, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+12, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+13, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+14, 0xFFFF ); ::jpeg_save_markers( jpeg_decompressor, JPEG_APP0+15, 0xFFFF ); ::jpeg_read_header( jpeg_decompressor, boolean( true ) ); // Deal with the JFIF marker and associated resolution data. if ( (jpegOptions.JFIFMarker = jpeg_decompressor->saw_JFIF_marker) != false ) { jpegOptions.JFIFMajorVersion = jpeg_decompressor->JFIF_major_version; jpegOptions.JFIFMinorVersion = jpeg_decompressor->JFIF_minor_version; options.metricResolution = jpeg_decompressor->density_unit == 2; options.xResolution = jpeg_decompressor->X_density; options.yResolution = jpeg_decompressor->Y_density; } else { // Set default JFIF version and resolution data if a JFIF marker is // not present in this JPEG file. jpegOptions.JFIFMajorVersion = 1; jpegOptions.JFIFMinorVersion = 2; options.metricResolution = false; options.xResolution = options.yResolution = 72; } // Set sample format options. options.bitsPerSample = 8; options.signedIntegers = options.complexSample = options.ieeefpSampleFormat = false; // Extract JPEG quality from dedicated JPEG marker jpegOptions.quality = JPEGQuality::Unknown; if ( jpeg_decompressor->marker_list != nullptr ) { const jpeg_marker_struct* m = jpeg_decompressor->marker_list; do { if ( !STRNCASECMP( (const char*)m->data, "JPEGQuality", 11 ) ) { // Skip marker header + null char jpegOptions.quality = Range( int( *(m->data + 12) ), 1, 100 ); break; } else if ( !STRNCASECMP( (const char*)m->data, "JPEG Quality", 12 ) || !STRNCASECMP( (const char*)m->data, "JPEG_Quality", 12 ) ) { // Skip marker header + null char jpegOptions.quality = Range( int( *(m->data + 13) ), 1, 100 ); break; } } while ( (m = m->next) != nullptr ); } jpegOptions.progressive = jpeg_decompressor->progressive_mode; jpegOptions.arithmeticCoding = jpeg_decompressor->arith_code; // Fill in ImageInfo and JPEGFileData fields. ::jpeg_calc_output_dimensions( jpeg_decompressor ); info.width = jpeg_decompressor->output_width; info.height = jpeg_decompressor->output_height; info.numberOfChannels = jpeg_decompressor->out_color_components; info.colorSpace = (jpeg_decompressor->out_color_space == JCS_GRAYSCALE) ? ColorSpace::Gray : ColorSpace::RGB; info.supported = true; } catch ( ... ) { Close(); throw; } }