diff options
author | Lode <lvandeve@gmail.com> | 2014-08-24 20:09:39 +0200 |
---|---|---|
committer | Lode <lvandeve@gmail.com> | 2014-08-24 20:09:39 +0200 |
commit | ad8aab2a14a7b4dc01e33312d151b6f535f3c41e (patch) | |
tree | 0af431f67446a8e102263787a26a1b90ca5e9b1b /example_png2bmp.cpp | |
parent | 148987254da889a317e2d249c5f7f68849267de5 (diff) |
add example and dev files to LodePNG repository
Diffstat (limited to 'example_png2bmp.cpp')
-rw-r--r-- | example_png2bmp.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/example_png2bmp.cpp b/example_png2bmp.cpp new file mode 100644 index 0000000..3fd8328 --- /dev/null +++ b/example_png2bmp.cpp @@ -0,0 +1,132 @@ +/* +LodePNG Examples + +Copyright (c) 2005-2012 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. +*/ + +#include "lodepng.h" +#include <iostream> + +/* +This example converts a PNG file to a BMP file. +NOTE: it overwrites the output file without warning if it exists! +Give the PNG and the BMP file names as command line arguments. +*/ + +/* +g++ lodepng.cpp example_png2bmp.cpp -Wall -Wextra -pedantic -ansi -lSDL -O3 +*/ + + + +//Input image must be RGB buffer (3 bytes per pixel), but you can easily make it +//support RGBA input and output by changing the inputChannels and/or outputChannels +//in the function to 4. +void encodeBMP(std::vector<unsigned char>& bmp, const unsigned char* image, int w, int h) +{ + //3 bytes per pixel used for both input and output. + int inputChannels = 3; + int outputChannels = 3; + + //bytes 0-13 + bmp.push_back('B'); bmp.push_back('M'); //0: bfType + bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //2: bfSize; size not yet known for now, filled in later. + bmp.push_back(0); bmp.push_back(0); //6: bfReserved1 + bmp.push_back(0); bmp.push_back(0); //8: bfReserved2 + bmp.push_back(54 % 256); bmp.push_back(54 / 256); bmp.push_back(0); bmp.push_back(0); //10: bfOffBits (54 header bytes) + + //bytes 14-53 + bmp.push_back(40); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //14: biSize + bmp.push_back(w % 256); bmp.push_back(w / 256); bmp.push_back(0); bmp.push_back(0); //18: biWidth + bmp.push_back(h % 256); bmp.push_back(h / 256); bmp.push_back(0); bmp.push_back(0); //22: biHeight + bmp.push_back(1); bmp.push_back(0); //26: biPlanes + bmp.push_back(outputChannels * 8); bmp.push_back(0); //28: biBitCount + bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //30: biCompression + bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //34: biSizeImage + bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //38: biXPelsPerMeter + bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //42: biYPelsPerMeter + bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //46: biClrUsed + bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); bmp.push_back(0); //50: biClrImportant + + /* + Convert the input RGBRGBRGB pixel buffer to the BMP pixel buffer format. There are 3 differences with the input buffer: + -BMP stores the rows inversed, from bottom to top + -BMP stores the color channels in BGR instead of RGB order + -BMP requires each row to have a multiple of 4 bytes, so sometimes padding bytes are added between rows + */ + + int imagerowbytes = outputChannels * w; + imagerowbytes = imagerowbytes % 4 == 0 ? imagerowbytes : imagerowbytes + (4 - imagerowbytes % 4); //must be multiple of 4 + + for(int y = h - 1; y >= 0; y--) //the rows are stored inversed in bmp + { + int c = 0; + for(int x = 0; x < imagerowbytes; x++) + { + if(x < w * outputChannels) + { + int inc = c; + //Convert RGB(A) into BGR(A) + if(c == 0) inc = 2; + else if(c == 2) inc = 0; + bmp.push_back(image[inputChannels * (w * y + x / outputChannels) + inc]); + } + else bmp.push_back(0); + c++; + if(c >= outputChannels) c = 0; + } + } + + // Fill in the size + bmp[2] = bmp.size() % 256; + bmp[3] = (bmp.size() / 256) % 256; + bmp[4] = (bmp.size() / 65536) % 256; + bmp[5] = bmp.size() / 16777216; +} + +int main(int argc, char *argv[]) +{ + if(argc < 3) + { + std::cout << "Please provice input PNG and output BMP file names" << std::endl; + return 0; + } + const char* infile = argv[1]; + const char* outfile = argv[2]; + + + std::vector<unsigned char> image; //the raw pixels + unsigned width, height; + + unsigned error = lodepng::decode(image, width, height, infile, LCT_RGB, 8); + + if(error) + { + std::cout << "error " << error << ": " << lodepng_error_text(error) << std::endl; + return 0; + } + + std::vector<unsigned char> bmp; + encodeBMP(bmp, &image[0], width, height); + + lodepng::save_file(bmp, outfile); +} |