//============================================================================ // // SSSS tt lll lll // SS SS tt ll ll // SS tttttt eeee ll ll aaaa // SSSS tt ee ee ll ll aa // SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" // SS SS tt ee ll ll aa aa // SSSS ttt eeeee llll llll aaaaa // // Copyright (c) 1995-2017 by Bradford W. Mott, Stephen Anthony // and the Stella Team // // See the file "License.txt" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ #ifndef PNGLIBRARY_HXX #define PNGLIBRARY_HXX #include class FrameBuffer; class FBSurface; class Properties; #include #include "bspf.hxx" /** This class implements a thin wrapper around the libpng library, and abstracts all the irrelevant details other loading and saving an actual image. @author Stephen Anthony */ class PNGLibrary { public: PNGLibrary(const FrameBuffer& fb); /** Read a PNG image from the specified file into a FBSurface structure, scaling the image to the surface bounds. @param filename The filename to load the PNG image @param surface The FBSurface into which to place the PNG data @return On success, the FBSurface containing image data, otherwise a runtime_error is thrown containing a more detailed error message. */ void loadImage(const string& filename, FBSurface& surface); /** Save the current FrameBuffer image to a PNG file. Note that in most cases this will be a TIA image, but it could actually be used for *any* mode. @param filename The filename to save the PNG image @param comments The text comments to add to the PNG image @return On success, the PNG file has been saved to 'filename', otherwise a runtime_error is thrown containing a more detailed error message. */ void saveImage(const string& filename, const VariantList& comments = EmptyVarList); /** Save the given surface to a PNG file. @param filename The filename to save the PNG image @param surface The surface data for the PNG image @param rect The area of the surface to use @param comments The text comments to add to the PNG image @return On success, the PNG file has been saved to 'filename', otherwise a runtime_error is thrown containing a more detailed error message. */ void saveImage(const string& filename, const FBSurface& surface, const GUI::Rect& rect = GUI::EmptyRect, const VariantList& comments = EmptyVarList); private: const FrameBuffer& myFB; // The following data remains between invocations of allocateStorage, // and is only changed when absolutely necessary. struct ReadInfoType { BytePtr buffer; unique_ptr row_pointers; png_uint_32 width, height, pitch; uInt32 buffer_size, row_size; }; static ReadInfoType ReadInfo; /** Allocate memory for PNG read operations. This is used to provide a basic memory manager, so that we don't constantly allocate and deallocate memory for each image loaded. The method fills the 'ReadInfo' struct with valid memory locations dependent on the given dimensions. If memory has been previously allocated and it can accommodate the given dimensions, it is used directly. @param iwidth The width of the PNG image @param iheight The height of the PNG image */ bool allocateStorage(png_uint_32 iwidth, png_uint_32 iheight); /** The actual method which saves a PNG image. @param out The output stream for writing PNG data @param rows Pointer into PNG RGB data for each row @param width The width of the PNG image @param height The height of the PNG image @param comments The text comments to add to the PNG image */ void saveImage(ofstream& out, const unique_ptr& rows, png_uint_32 width, png_uint_32 height, const VariantList& comments); /** Load the PNG data from 'ReadInfo' into the FBSurface. The surface is resized as necessary to accommodate the data. @param surface The FBSurface into which to place the PNG data */ void loadImagetoSurface(FBSurface& surface); /** Write PNG tEXt chunks to the image. */ void writeComments(png_structp png_ptr, png_infop info_ptr, const VariantList& comments); /** PNG library callback functions */ static void png_read_data(png_structp ctx, png_bytep area, png_size_t size); static void png_write_data(png_structp ctx, png_bytep area, png_size_t size); static void png_io_flush(png_structp ctx); [[noreturn]] static void png_user_warn(png_structp ctx, png_const_charp str); [[noreturn]] static void png_user_error(png_structp ctx, png_const_charp str); private: // Following constructors and assignment operators not supported PNGLibrary(const PNGLibrary&) = delete; PNGLibrary(PNGLibrary&&) = delete; PNGLibrary& operator=(const PNGLibrary&) = delete; PNGLibrary& operator=(PNGLibrary&&) = delete; }; #endif