#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2021 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_PIXELS_STORAGE_JPEG_LIBJPEGHELPERS_H #define NUCLEX_PIXELS_STORAGE_JPEG_LIBJPEGHELPERS_H #include "Nuclex/Pixels/Config.h" #if defined(NUCLEX_PIXELS_HAVE_LIBJPEG) #include "Nuclex/Pixels/PixelFormat.h" #include "Nuclex/Pixels/Storage/VirtualFile.h" #include // for std::uint8_t, std::uint64_t #include // main jpeglib header namespace Nuclex { namespace Pixels { namespace Storage { namespace Jpeg { // ------------------------------------------------------------------------------------------- // /// Size of the input buffer for reading file data into libjpeg /// /// This is the same size as used by the (FILE *) implementation set up by /// the init_source() function in jdatasrc.c. /// constexpr const std::size_t JpegInputBufferSize = 4096; /// Size of the smallest valid JPEG file possible /// /// From https://stackoverflow.com/questions/2253404 /// From https://github.com/mathiasbynens/small/blob/master/jpeg.jpg /// constexpr const std::size_t SmallestPossibleJpegSize = 107; // byte // ------------------------------------------------------------------------------------------- // /// Helper class for reading JPEG files using libjpeg class Helpers { /// /// Checks whether the first 13 bytes in a file are a valid JPEG file header /// /// File header that will be checked /// True if the file header is a valid JPEG file header /// /// The file header must contain at least the first 13 bytes of the file, /// otherwise this will segfault. /// public: static bool IsValidJpegHeader(const std::uint8_t *fileHeader); /// Finds the supported pixel format that is closest to the JPEG's /// JPEG decompression structure with image information /// The pixel format that's most like the one of the JPEG image public: static PixelFormat GetClosestPixelFormat( const ::jpeg_decompress_struct &commonInfo ); }; // ------------------------------------------------------------------------------------------- // /// Data required by the libjpeg IO functions to read from virtual files struct JpegReadEnvironment : public ::jpeg_source_mgr { /// Initializes a new libjpeg read environment /// Virtual file from which data will be read public: JpegReadEnvironment(const Nuclex::Pixels::Storage::VirtualFile &file) : IsReadOnly(true), File(file), Position(0) { this->Length = file.GetSize(); SetupFunctionPointers(*this); } /// Sets up the functions pointers used by libjpeg /// /// Environment on which the function pointers will be set up /// protected: static void SetupFunctionPointers(JpegReadEnvironment &jpegReadEnvironment); /// Whether the virtual file is opened in read-only mode public: bool IsReadOnly; /// Virtual file the read environment is taking data from public: const VirtualFile &File; /// Current position of the file cursor public: std::uint64_t Position; /// Total length of the file in bytes public: std::uint64_t Length; /// Buffer in which read data will be stored for libjpeg public: std::uint8_t Buffer[JpegInputBufferSize]; }; // ------------------------------------------------------------------------------------------- // /// Data required by the libjpeg IO functions to write to virtual files struct JpegWriteEnvironment : public ::jpeg_destination_mgr { /// Initializes a new libjpeg write environment /// Virtual file into which data will be written public: JpegWriteEnvironment(Nuclex::Pixels::Storage::VirtualFile &file) : IsReadOnly(false), File(file), Position(0) { SetupFunctionPointers(*this); } /// Sets up the functions pointers used by libjpeg /// /// Environment on which the function pointers will be set up /// protected: static void SetupFunctionPointers(JpegWriteEnvironment &jpegWriteEnvironment); /// Whether the virtual file is opened in read-only mode public: bool IsReadOnly; /// Virtual file the read environment is taking data from public: VirtualFile &File; /// Current position of the file cursor public: std::uint64_t Position; }; // ------------------------------------------------------------------------------------------- // }}}} // namespace Nuclex::Pixels::Storage::Jpeg #endif // defined(NUCLEX_PIXELS_HAVE_LIBJPEG) #endif // NUCLEX_PIXELS_STORAGE_JPEG_LIBJPEGHELPERS_H