pngwriter.cc revision 12582
172SN/A/* 211274Sshingarov@labware.com * Copyright (c) 2017 ARM Limited 310597Sgabeblack@google.com * All rights reserved 41762SN/A * 572SN/A * The license below extends only to copyright in the software and shall 672SN/A * not be construed as granting a license to any other intellectual 772SN/A * property including but not limited to intellectual property relating 872SN/A * to a hardware implementation of the functionality of the software 972SN/A * licensed hereunder. You may use the software subject to the license 1072SN/A * terms below provided that you ensure that this notice is replicated 1172SN/A * unmodified and in its entirety in all distributions of the software, 1272SN/A * modified or unmodified, in source code or in binary form. 1372SN/A * 1472SN/A * Redistribution and use in source and binary forms, with or without 1572SN/A * modification, are permitted provided that the following conditions are 1672SN/A * met: redistributions of source code must retain the above copyright 1772SN/A * notice, this list of conditions and the following disclaimer; 1872SN/A * redistributions in binary form must reproduce the above copyright 1972SN/A * notice, this list of conditions and the following disclaimer in the 2072SN/A * documentation and/or other materials provided with the distribution; 2172SN/A * neither the name of the copyright holders nor the names of its 2272SN/A * contributors may be used to endorse or promote products derived from 2372SN/A * this software without specific prior written permission. 2472SN/A * 2572SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2672SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2772SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2872SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 292665Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 302665Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3111274Sshingarov@labware.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3272SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3372SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 342SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 358332Snate@binkert.org * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 368332Snate@binkert.org * 372SN/A * Authors: Giacomo Travaglini 382SN/A */ 392SN/A 402SN/A/** 412SN/A * @file Definition of a class that writes a frame buffer to a png 422SN/A */ 432SN/A 445543Ssaidi@eecs.umich.edu#include "base/pngwriter.hh" 455543Ssaidi@eecs.umich.edu 462SN/Aextern "C" 472SN/A{ 482SN/A#include <png.h> 492SN/A} 502SN/A 512SN/A#include <cstdio> 522SN/A#include <cstdlib> 532SN/A 542SN/A#include "base/logging.hh" 552SN/A 562SN/Aconst char* PngWriter::_imgExtension = "png"; 575543Ssaidi@eecs.umich.edu 585543Ssaidi@eecs.umich.edu/** 592SN/A * Write callback to use with libpng APIs 602SN/A * 612SN/A * @param pngPtr pointer to the png_struct structure 622SN/A * @param data pointer to the data being written 632SN/A * @param length number of bytes being written 642SN/A */ 652SN/Astatic void 662SN/AwritePng(png_structp pngPtr, png_bytep data, png_size_t length) 672SN/A{ 682SN/A // Here we get our IO pointer back from the write struct 692SN/A // and we cast it into a ostream* type. 702SN/A std::ostream* strmPtr = reinterpret_cast<std::ostream*>( 712SN/A png_get_io_ptr(pngPtr) 722SN/A ); 732SN/A 742SN/A // Write length bytes to data 755543Ssaidi@eecs.umich.edu strmPtr->write(reinterpret_cast<const char *>(data), length); 762SN/A} 772SN/A 782SN/Astruct PngWriter::PngStructHandle { 792SN/A private: 802SN/A // Make PngStructHandle uncopyable 812SN/A PngStructHandle(const PngStructHandle&) = delete; 822SN/A PngStructHandle& operator=(const PngStructHandle&) = delete; 832SN/A public: 842SN/A 852SN/A PngStructHandle() : 862SN/A pngWriteP(NULL), pngInfoP(NULL) 872SN/A { 882SN/A // Creating write structure 892SN/A pngWriteP = png_create_write_struct( 902SN/A PNG_LIBPNG_VER_STRING, NULL, NULL, NULL 912SN/A ); 922SN/A 932SN/A if (pngWriteP) { 942SN/A // Creating info structure 955543Ssaidi@eecs.umich.edu pngInfoP = png_create_info_struct(pngWriteP); 965543Ssaidi@eecs.umich.edu } 972SN/A } 982SN/A 992SN/A ~PngStructHandle() 1002SN/A { 1012SN/A if (pngWriteP) { 1022SN/A png_destroy_write_struct(&pngWriteP, &pngInfoP); 1032SN/A } 1042SN/A } 1052SN/A 1062SN/A /** Pointer to PNG Write struct */ 1072SN/A png_structp pngWriteP; 1082SN/A 1092SN/A /** Pointer to PNG Info struct */ 1102SN/A png_infop pngInfoP; 1112SN/A}; 1122SN/A 1132SN/Avoid 1142SN/APngWriter::write(std::ostream &png) const 1152SN/A{ 1162SN/A 1172SN/A // Height of the frame buffer 1182SN/A unsigned height = fb.height(); 1192SN/A unsigned width = fb.width(); 1202SN/A 1212SN/A // Do not write if frame buffer is empty 12211793Sbrandon.potter@amd.com if (!fb.area()) { 12311793Sbrandon.potter@amd.com png.flush(); 1242SN/A return; 1258229Snate@binkert.org } 1262SN/A 12711793Sbrandon.potter@amd.com // Initialize Png structures 12812019Sgabeblack@google.com PngStructHandle handle; 1296712Snate@binkert.org 1301717SN/A // Png info/write pointers. 1312SN/A png_structp pngPtr = handle.pngWriteP; 1322521SN/A png_infop infoPtr = handle.pngInfoP; 13356SN/A 13456SN/A if (!pngPtr) { 13556SN/A warn("Frame buffer dump aborted: Unable to create" 1366658Snate@binkert.org "Png Write Struct\n"); 13710597Sgabeblack@google.com return; 1388229Snate@binkert.org } 1392680Sktlim@umich.edu 1408232Snate@binkert.org if (!infoPtr) { 14111793Sbrandon.potter@amd.com warn("Frame buffer dump aborted: Unable to create" 1422521SN/A "Png Info Struct\n"); 1438706Sandreas.hansson@arm.com return; 1448784Sgblack@eecs.umich.edu } 1451717SN/A 1462SN/A // We cannot use default libpng write function since it requires 1472SN/A // a file pointer (FILE*), whereas we want to use the ostream. 1482107SN/A // The following function replaces the write function with a custom 1492SN/A // one provided by us (writePng) 15012031Sgabeblack@google.com png_set_write_fn(pngPtr, (png_voidp)&png, writePng, NULL); 15112031Sgabeblack@google.com 15212031Sgabeblack@google.com png_set_IHDR(pngPtr, infoPtr, width, height, 8, 15312031Sgabeblack@google.com PNG_COLOR_TYPE_RGB, 15412031Sgabeblack@google.com PNG_INTERLACE_NONE, 15512031Sgabeblack@google.com PNG_COMPRESSION_TYPE_DEFAULT, 15612031Sgabeblack@google.com PNG_FILTER_TYPE_DEFAULT); 1573536Sgblack@eecs.umich.edu 1582SN/A png_write_info(pngPtr, infoPtr); 15912449Sgabeblack@google.com 16012449Sgabeblack@google.com // libpng requires an array of pointers to the frame buffer's rows. 16112449Sgabeblack@google.com std::vector<PixelType> rowPacked(width); 16212449Sgabeblack@google.com for (unsigned y=0; y < height; ++y) { 16312449Sgabeblack@google.com for (unsigned x=0; x < width; ++x) { 16412449Sgabeblack@google.com rowPacked[x] = fb.pixel(x, y); 16512449Sgabeblack@google.com } 16612449Sgabeblack@google.com 16712449Sgabeblack@google.com png_write_row(pngPtr, 16812449Sgabeblack@google.com reinterpret_cast<png_bytep>(rowPacked.data()) 16912449Sgabeblack@google.com ); 17012449Sgabeblack@google.com } 17112449Sgabeblack@google.com 17212449Sgabeblack@google.com // End of write 17312449Sgabeblack@google.com png_write_end(pngPtr, NULL); 17412449Sgabeblack@google.com} 17512449Sgabeblack@google.com 17612449Sgabeblack@google.com