#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_PNG_LIBPNGHELPERS_H #define NUCLEX_PIXELS_STORAGE_PNG_LIBPNGHELPERS_H #include "Nuclex/Pixels/Config.h" #if defined(NUCLEX_PIXELS_HAVE_LIBPNG) #include "Nuclex/Pixels/PixelFormat.h" #include "Nuclex/Pixels/Storage/VirtualFile.h" #include // LibPNG main header namespace Nuclex { namespace Pixels { namespace Storage { namespace Png { // ------------------------------------------------------------------------------------------- // /// Size of the smallest valid PNG file possible /// /// From https://garethrees.org/2007/11/14/pngcrush/ /// constexpr const std::size_t SmallestPossiblePngSize = 67; // bytes // ------------------------------------------------------------------------------------------- // /// Helper class for reading PNG files using libpng class Helpers { /// Checks if the specified file extension indicates a .png file /// File extension (can be with or without leading dot) /// True if the file extension indicates a .png public: static bool DoesFileExtensionSayPng(const std::string &extension); /// Checks if the specified file starts with a valid .png header /// File that will be checked for a valid .png header /// True if a valid .png header was found, false otherwise public: static bool CheckIfPngHeaderPresent(const VirtualFile &source); /// Selects the pixel format in which a .png file will be loaded /// /// PNG read structure from which the .png pixel format will be queried /// (will receive necessary adjustments if non-const reference) /// /// /// PNG information structure, required by some of the LibPNG query methods /// /// /// The pixel format that is closest/matches the .png file and if non-const, /// for which LibPNG has been configured to load the image as /// /// /// LibPNG can perform some pixel format adjustments on its own. We use these to adapt /// formats that would have no representation in Nuclex.Pixels (such as 1, 2 and 4 bits /// per channel which is space-saving for storage but useless on modern graphics hardware). /// public: static PixelFormat SelectPixelFormatForLoad( ::png_struct &pngRead, const ::png_info &pngInfo ); /// Finds the supported pixel format that is closest to the PNG's /// Main PNG structure storing libpng settings /// PNG info structure storing information about an image /// The pixel format that's most like the one of the PNG image public: static PixelFormat GetClosestPixelFormat( const ::png_struct &pngRead, const ::png_info &pngInfo ); }; // ------------------------------------------------------------------------------------------- // /// Data passed along to the custom read function for libpng struct PngReadEnvironment { /// Initializes a new libpng read environment /// Main PNG structure initialized for reading /// File from which libpng should be reading public: PngReadEnvironment( ::png_struct &pngRead, const Nuclex::Pixels::Storage::VirtualFile &file ) : IsReadOnly(true), File(file), Position(0) { SetupFunctionPointers(*this, pngRead); } /// Sets up the functions pointers used by libpng /// /// Environment on which the function pointers will be set up /// /// Main PNG structure initialized for reading protected: static void SetupFunctionPointers( PngReadEnvironment &pngReadEnvironment, ::png_struct &pngRead ); /// Whether the file is read-only, always true for this structure public: bool IsReadOnly; /// File from which the read method is reading data public: const Nuclex::Pixels::Storage::VirtualFile &File; /// Current position of the file pointer public: std::uint64_t Position; }; // ------------------------------------------------------------------------------------------- // /// Data passed along to the custom write function for libpng struct PngWriteEnvironment { /// Initializes a new libpng write environment /// Main PNG structure initialized for writing /// File to which libpng should be writing public: PngWriteEnvironment( ::png_struct &pngWrite, Nuclex::Pixels::Storage::VirtualFile &file ) : IsReadOnly(false), File(file), Position(0) { SetupFunctionPointers(*this, pngWrite); } /// Sets up the functions pointers used by libpng /// /// Environment on which the function pointers will be set up /// /// Main PNG structure initialized for writing protected: static void SetupFunctionPointers( PngWriteEnvironment &pngWriteEnvironment, ::png_struct &pngWrite ); /// Whether the file is read-only, always false for this structure public: bool IsReadOnly; /// File to which the write method is writing data public: Nuclex::Pixels::Storage::VirtualFile &File; /// Current position of the file pointer public: std::uint64_t Position; }; // ------------------------------------------------------------------------------------------- // }}}} // namespace Nuclex::Pixels::Storage::Png #endif // defined(NUCLEX_PIXELS_HAVE_LIBPNG) #endif // NUCLEX_PIXELS_STORAGE_PNG_LIBPNGHELPERS_H