From bf2aa0a46fc8c1d398604cd384bc2c583774cc1f Mon Sep 17 00:00:00 2001 From: Lode Date: Mon, 16 Feb 2015 22:55:55 +0100 Subject: move examples to examples directory --- examples/example_bmp2png.cpp | 134 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 examples/example_bmp2png.cpp (limited to 'examples/example_bmp2png.cpp') diff --git a/examples/example_bmp2png.cpp b/examples/example_bmp2png.cpp new file mode 100644 index 0000000..c6bdd24 --- /dev/null +++ b/examples/example_bmp2png.cpp @@ -0,0 +1,134 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2010 Lode Vandevenne + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. +*/ + +/* +Load a BMP image and convert it to a PNG image. This example also shows how +to use other data with the same memory structure as BMP, such as the image +format native to win32, GDI (HBITMAP, BITMAPINFO, ...) often encountered if +you're programming for Windows in Visual Studio. + +This example only supports uncompressed 24-bit RGB or 32-bit RGBA bitmaps. +For other types of BMP's, use a full fledged BMP decoder, or convert the +bitmap to 24-bit or 32-bit format. + +NOTE: it overwrites the output file without warning if it exists! +*/ + +//g++ lodepng.cpp example_bmp2png.cpp -ansi -pedantic -Wall -Wextra -O3 + +#include "lodepng.h" + +#include + +//returns 0 if all went ok, non-0 if error +//output image is always given in RGBA (with alpha channel), even if it's a BMP without alpha channel +unsigned decodeBMP(std::vector& image, unsigned& w, unsigned& h, const std::vector& bmp) +{ + static const unsigned MINHEADER = 54; //minimum BMP header size + + if(bmp.size() < MINHEADER) return -1; + if(bmp[0] != 'B' || bmp[1] != 'M') return 1; //It's not a BMP file if it doesn't start with marker 'BM' + unsigned pixeloffset = bmp[10] + 256 * bmp[11]; //where the pixel data starts + //read width and height from BMP header + w = bmp[18] + bmp[19] * 256; + h = bmp[22] + bmp[23] * 256; + //read number of channels from BMP header + if(bmp[28] != 24 && bmp[28] != 32) return 2; //only 24-bit and 32-bit BMPs are supported. + unsigned numChannels = bmp[28] / 8; + + //The amount of scanline bytes is width of image times channels, with extra bytes added if needed + //to make it a multiple of 4 bytes. + unsigned scanlineBytes = w * numChannels; + if(scanlineBytes % 4 != 0) scanlineBytes = (scanlineBytes / 4) * 4 + 4; + + unsigned dataSize = scanlineBytes * h; + if(bmp.size() < dataSize + pixeloffset) return 3; //BMP file too small to contain all pixels + + image.resize(w * h * 4); + + /* + There are 3 differences between BMP and the raw image buffer for LodePNG: + -it's upside down + -it's in BGR instead of RGB format (or BRGA instead of RGBA) + -each scanline has padding bytes to make it a multiple of 4 if needed + The 2D for loop below does all these 3 conversions at once. + */ + for(unsigned y = 0; y < h; y++) + for(unsigned x = 0; x < w; x++) + { + //pixel start byte position in the BMP + unsigned bmpos = pixeloffset + (h - y - 1) * scanlineBytes + numChannels * x; + //pixel start byte position in the new raw image + unsigned newpos = 4 * y * w + 4 * x; + if(numChannels == 3) + { + image[newpos + 0] = bmp[bmpos + 2]; //R + image[newpos + 1] = bmp[bmpos + 1]; //G + image[newpos + 2] = bmp[bmpos + 0]; //B + image[newpos + 3] = 255; //A + } + else + { + image[newpos + 0] = bmp[bmpos + 3]; //R + image[newpos + 1] = bmp[bmpos + 2]; //G + image[newpos + 2] = bmp[bmpos + 1]; //B + image[newpos + 3] = bmp[bmpos + 0]; //A + } + } + return 0; +} + +int main(int argc, char *argv[]) +{ + if(argc < 3) + { + std::cout << "Please provice input PNG and output BMP file names" << std::endl; + return 0; + } + + std::vector bmp; + lodepng::load_file(bmp, argv[1]); + std::vector image; + unsigned w, h; + unsigned error = decodeBMP(image, w, h, bmp); + + if(error) + { + std::cout << "BMP decoding error " << error << std::endl; + return 0; + } + + std::vector png; + error = lodepng::encode(png, image, w, h); + + if(error) + { + std::cout << "PNG encoding error " << error << ": " << lodepng_error_text(error) << std::endl; + return 0; + } + + lodepng::save_file(png, argv[2]); + +} -- cgit v1.2.3