mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
basic example using sapi
This commit is contained in:
parent
8633f22185
commit
d63ada79cf
86
oss-internship-2020/sapi_lodepng/CMakeLists.txt
Normal file
86
oss-internship-2020/sapi_lodepng/CMakeLists.txt
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
# Copyright 2020 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
project(lodepng_sapi CXX)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED 17)
|
||||||
|
|
||||||
|
add_subdirectory(lodepng-master)
|
||||||
|
|
||||||
|
|
||||||
|
# unsandboxed main
|
||||||
|
add_executable(lodepng_normal main.cc)
|
||||||
|
target_link_libraries(lodepng_normal PRIVATE lodepng)
|
||||||
|
|
||||||
|
# sandboxed main
|
||||||
|
set(SAPI_ROOT "/usr/local/google/home/amedar/internship/sandboxed-api" CACHE PATH "Path to the Sandboxed API source tree")
|
||||||
|
|
||||||
|
#set(SAPI_ENABLE_EXAMPLES OFF CACHE BOOL "")
|
||||||
|
|
||||||
|
#set(SAPI_ENABLE_TESTS ON CACHE BOOL "")
|
||||||
|
|
||||||
|
add_subdirectory("${SAPI_ROOT}"
|
||||||
|
"${CMAKE_BINARY_DIR}/sandboxed-api-build"
|
||||||
|
# Omit this to have the full Sandboxed API in IDE
|
||||||
|
EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
add_sapi_library(
|
||||||
|
lodepng_sapi
|
||||||
|
FUNCTIONS lodepng_decode32_file lodepng_encode32_file
|
||||||
|
INPUTS lodepng-master/lodepng.h
|
||||||
|
LIBRARY lodepng
|
||||||
|
LIBRARY_NAME Lodepng
|
||||||
|
NAMESPACE ""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
target_include_directories(lodepng_sapi INTERFACE
|
||||||
|
"${PROJECT_BINARY_DIR}" # To find the generated SAPI header
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(lodepng_sandboxed main_sandboxed.cc sandbox.h)
|
||||||
|
|
||||||
|
target_link_libraries(lodepng_sandboxed PRIVATE
|
||||||
|
lodepng_sapi
|
||||||
|
sapi::sapi
|
||||||
|
sapi::vars
|
||||||
|
sapi::status
|
||||||
|
glog::glog
|
||||||
|
)
|
||||||
|
|
||||||
|
# gtest
|
||||||
|
|
||||||
|
include(GoogleTest)
|
||||||
|
enable_testing()
|
||||||
|
|
||||||
|
add_executable(main_unit_test
|
||||||
|
main_unit_test.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(main_unit_test PRIVATE
|
||||||
|
lodepng_sapi
|
||||||
|
absl::memory
|
||||||
|
absl::strings
|
||||||
|
absl::time
|
||||||
|
glog::glog
|
||||||
|
sapi::flags
|
||||||
|
sapi::sapi
|
||||||
|
sapi::status
|
||||||
|
sapi::test_main
|
||||||
|
sapi::vars
|
||||||
|
)
|
||||||
|
gtest_discover_tests(main_unit_test)
|
11
oss-internship-2020/sapi_lodepng/README.md
Normal file
11
oss-internship-2020/sapi_lodepng/README.md
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
TODO
|
||||||
|
|
||||||
|
- check return value of functions
|
||||||
|
- integrate unit testing
|
||||||
|
- add more functions
|
||||||
|
- this readme
|
||||||
|
- remove path from CMakeLists.txt
|
||||||
|
- include abseil flags for unit testing
|
||||||
|
- improve tests (images, generating images etc.)
|
||||||
|
- clear redundant includes
|
||||||
|
- check if security policy can be stricter
|
1
oss-internship-2020/sapi_lodepng/com_google_sandboxed_api
Symbolic link
1
oss-internship-2020/sapi_lodepng/com_google_sandboxed_api
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
/usr/local/google/home/amedar/internship/sandboxed-api/build
|
|
@ -0,0 +1,15 @@
|
||||||
|
# Copyright 2020 Google LLC
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
add_library(lodepng STATIC lodepng.cpp lodepng.h)
|
21
oss-internship-2020/sapi_lodepng/lodepng-master/LICENSE
Normal file
21
oss-internship-2020/sapi_lodepng/lodepng-master/LICENSE
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
Copyright (c) 2005-2018 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.
|
||||||
|
|
34
oss-internship-2020/sapi_lodepng/lodepng-master/Makefile
Normal file
34
oss-internship-2020/sapi_lodepng/lodepng-master/Makefile
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# This makefile only makes the unit test, benchmark and pngdetail and showpng
|
||||||
|
# utilities. It does not make the PNG codec itself as shared or static library.
|
||||||
|
# That is because:
|
||||||
|
# LodePNG itself has only 1 source file (lodepng.cpp, can be renamed to
|
||||||
|
# lodepng.c) and is intended to be included as source file in other projects and
|
||||||
|
# their build system directly.
|
||||||
|
|
||||||
|
|
||||||
|
CC ?= gcc
|
||||||
|
CXX ?= g++
|
||||||
|
|
||||||
|
override CFLAGS := -W -Wall -Wextra -ansi -pedantic -O3 -Wno-unused-function $(CFLAGS)
|
||||||
|
override CXXFLAGS := -W -Wall -Wextra -ansi -pedantic -O3 $(CXXFLAGS)
|
||||||
|
|
||||||
|
all: unittest benchmark pngdetail showpng
|
||||||
|
|
||||||
|
%.o: %.cpp
|
||||||
|
@mkdir -p `dirname $@`
|
||||||
|
$(CXX) -I ./ $(CXXFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
unittest: lodepng.o lodepng_util.o lodepng_unittest.o
|
||||||
|
$(CXX) $^ $(CXXFLAGS) -o $@
|
||||||
|
|
||||||
|
benchmark: lodepng.o lodepng_benchmark.o
|
||||||
|
$(CXX) $^ $(CXXFLAGS) -lSDL -o $@
|
||||||
|
|
||||||
|
pngdetail: lodepng.o lodepng_util.o pngdetail.o
|
||||||
|
$(CXX) $^ $(CXXFLAGS) -o $@
|
||||||
|
|
||||||
|
showpng: lodepng.o examples/example_sdl.o
|
||||||
|
$(CXX) -I ./ $^ $(CXXFLAGS) -lSDL -o $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f unittest benchmark pngdetail showpng lodepng_unittest.o lodepng_benchmark.o lodepng.o lodepng_util.o pngdetail.o examples/example_sdl.o
|
75
oss-internship-2020/sapi_lodepng/lodepng-master/README.md
Normal file
75
oss-internship-2020/sapi_lodepng/lodepng-master/README.md
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
LodePNG
|
||||||
|
-------
|
||||||
|
|
||||||
|
PNG encoder and decoder in C and C++, without dependencies
|
||||||
|
|
||||||
|
Home page: http://lodev.org/lodepng/
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
|
||||||
|
Detailed documentation is included in a large comment in the second half of the
|
||||||
|
header file `lodepng.h`.
|
||||||
|
|
||||||
|
Source code examples using LodePNG can be found in the examples directory.
|
||||||
|
|
||||||
|
An FAQ can be found on http://lodev.org/lodepng/
|
||||||
|
|
||||||
|
### Building
|
||||||
|
|
||||||
|
Only two files are needed to encode and decode PNGs:
|
||||||
|
|
||||||
|
* `lodepng.cpp` (or renamed to `lodepng.c`)
|
||||||
|
* `lodepng.h`
|
||||||
|
|
||||||
|
All other files are just source code examples, tests, misc utilities, etc...,
|
||||||
|
which are normally not needed in projects using this.
|
||||||
|
|
||||||
|
You can include the files directly in your project's source tree and its
|
||||||
|
makefile, IDE project file, or other build system. No library is necessary.
|
||||||
|
|
||||||
|
In addition to C++, LodePNG also supports ANSI C (C89), with all the same
|
||||||
|
functionality: C++ only adds extra convenience API.
|
||||||
|
|
||||||
|
For C, rename `lodepng.cpp` to `lodepng.c`.
|
||||||
|
|
||||||
|
Consider using git submodules to include LodePNG in your project.
|
||||||
|
|
||||||
|
### Compiling in C++
|
||||||
|
|
||||||
|
If you have a hypothetical `your_program.cpp` that #includes and uses `lodepng.h`,
|
||||||
|
you can build as follows:
|
||||||
|
|
||||||
|
`g++ your_program.cpp lodepng.cpp -Wall -Wextra -pedantic -ansi -O3`
|
||||||
|
|
||||||
|
or:
|
||||||
|
|
||||||
|
`clang++ your_program.cpp lodepng.cpp -Wall -Wextra -pedantic -ansi -O3`
|
||||||
|
|
||||||
|
This shows compiler flags it was designed for, but normally one would use the
|
||||||
|
compiler or build system of their project instead of those commands, and other
|
||||||
|
C++ compilers are supported.
|
||||||
|
|
||||||
|
### Compiling in C
|
||||||
|
|
||||||
|
Rename `lodepng.cpp` to `lodepng.c` for this.
|
||||||
|
|
||||||
|
If you have a hypothetical your_program.c that #includes and uses lodepng.h,
|
||||||
|
you can build as follows:
|
||||||
|
|
||||||
|
`gcc your_program.c lodepng.c -ansi -pedantic -Wall -Wextra -O3`
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
`clang your_program.c lodepng.c -ansi -pedantic -Wall -Wextra -O3`
|
||||||
|
|
||||||
|
This shows compiler flags it was designed for, but normally one would use the
|
||||||
|
compiler or build system of their project instead of those commands, and other
|
||||||
|
C compilers are supported.
|
||||||
|
|
||||||
|
### Makefile
|
||||||
|
|
||||||
|
There is a Makefile, but this is not intended for using LodePNG itself since the
|
||||||
|
way to use that one is to include its source files in your program. The Makefile
|
||||||
|
only builds development and testing utilities. It can be used as follows:
|
||||||
|
|
||||||
|
`make -j`
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//g++ lodepng.cpp example_4bit_palette.cpp -ansi -pedantic -Wall -Wextra -O3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
LodePNG 4-bit palette example.
|
||||||
|
This example encodes a 511x511 PNG with a 4-bit palette.
|
||||||
|
Both image and palette contain sine waves, resulting in a sort of plasma.
|
||||||
|
The 511 (rather than power of two 512) size is of course chosen on purpose to
|
||||||
|
confirm that scanlines not filling up an entire byte size are working.
|
||||||
|
|
||||||
|
NOTE: a PNG image with a translucent palette is perfectly valid. However there
|
||||||
|
exist some programs that cannot correctly read those, including, surprisingly,
|
||||||
|
Gimp 2.8 image editor (until you set mode to RGB).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "lodepng.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
//check if user gave a filename
|
||||||
|
if(argc < 2) {
|
||||||
|
std::cout << "please provide a filename to save to" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//create encoder and set settings and info (optional)
|
||||||
|
lodepng::State state;
|
||||||
|
|
||||||
|
//generate palette
|
||||||
|
for(int i = 0; i < 16; i++) {
|
||||||
|
unsigned char r = 127 * (1 + std::sin(5 * i * 6.28318531 / 16));
|
||||||
|
unsigned char g = 127 * (1 + std::sin(2 * i * 6.28318531 / 16));
|
||||||
|
unsigned char b = 127 * (1 + std::sin(3 * i * 6.28318531 / 16));
|
||||||
|
unsigned char a = 63 * (1 + std::sin(8 * i * 6.28318531 / 16)) + 128; /*alpha channel of the palette (tRNS chunk)*/
|
||||||
|
|
||||||
|
//palette must be added both to input and output color mode, because in this
|
||||||
|
//sample both the raw image and the expected PNG image use that palette.
|
||||||
|
lodepng_palette_add(&state.info_png.color, r, g, b, a);
|
||||||
|
lodepng_palette_add(&state.info_raw, r, g, b, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
//both the raw image and the encoded image must get colorType 3 (palette)
|
||||||
|
state.info_png.color.colortype = LCT_PALETTE; //if you comment this line, and create the above palette in info_raw instead, then you get the same image in a RGBA PNG.
|
||||||
|
state.info_png.color.bitdepth = 4;
|
||||||
|
state.info_raw.colortype = LCT_PALETTE;
|
||||||
|
state.info_raw.bitdepth = 4;
|
||||||
|
state.encoder.auto_convert = 0; //we specify ourselves exactly what output PNG color mode we want
|
||||||
|
|
||||||
|
//generate some image
|
||||||
|
const unsigned w = 511;
|
||||||
|
const unsigned h = 511;
|
||||||
|
std::vector<unsigned char> image;
|
||||||
|
image.resize((w * h * 4 + 7) / 8, 0);
|
||||||
|
for(unsigned y = 0; y < h; y++)
|
||||||
|
for(unsigned x = 0; x < w; x++) {
|
||||||
|
size_t byte_index = (y * w + x) / 2;
|
||||||
|
bool byte_half = (y * w + x) % 2 == 1;
|
||||||
|
|
||||||
|
int color = (int)(4 * ((1 + std::sin(2.0 * 6.28318531 * x / (double)w))
|
||||||
|
+ (1 + std::sin(2.0 * 6.28318531 * y / (double)h))) );
|
||||||
|
|
||||||
|
image[byte_index] |= (unsigned char)(color << (byte_half ? 0 : 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
//encode and save
|
||||||
|
std::vector<unsigned char> buffer;
|
||||||
|
unsigned error = lodepng::encode(buffer, image.empty() ? 0 : &image[0], w, h, state);
|
||||||
|
if(error) {
|
||||||
|
std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
lodepng::save_file(buffer, argv[1]);
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
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 <iostream>
|
||||||
|
|
||||||
|
//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<unsigned char>& image, unsigned& w, unsigned& h, const std::vector<unsigned char>& 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 + 2]; //R
|
||||||
|
image[newpos + 1] = bmp[bmpos + 1]; //G
|
||||||
|
image[newpos + 2] = bmp[bmpos + 0]; //B
|
||||||
|
image[newpos + 3] = bmp[bmpos + 3]; //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<unsigned char> bmp;
|
||||||
|
lodepng::load_file(bmp, argv[1]);
|
||||||
|
std::vector<unsigned char> 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<unsigned char> 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]);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
3 ways to decode a PNG from a file to RGBA pixel data (and 2 in-memory ways).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Example 1
|
||||||
|
Decode from disk to raw pixels with a single function call
|
||||||
|
*/
|
||||||
|
void decodeOneStep(const char* filename) {
|
||||||
|
unsigned error;
|
||||||
|
unsigned char* image = 0;
|
||||||
|
unsigned width, height;
|
||||||
|
|
||||||
|
error = lodepng_decode32_file(&image, &width, &height, filename);
|
||||||
|
if(error) printf("error %u: %s\n", error, lodepng_error_text(error));
|
||||||
|
|
||||||
|
/*use image here*/
|
||||||
|
|
||||||
|
free(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Example 2
|
||||||
|
Load PNG file from disk to memory first, then decode to raw pixels in memory.
|
||||||
|
*/
|
||||||
|
void decodeTwoSteps(const char* filename) {
|
||||||
|
unsigned error;
|
||||||
|
unsigned char* image = 0;
|
||||||
|
unsigned width, height;
|
||||||
|
unsigned char* png = 0;
|
||||||
|
size_t pngsize;
|
||||||
|
|
||||||
|
error = lodepng_load_file(&png, &pngsize, filename);
|
||||||
|
if(!error) error = lodepng_decode32(&image, &width, &height, png, pngsize);
|
||||||
|
if(error) printf("error %u: %s\n", error, lodepng_error_text(error));
|
||||||
|
|
||||||
|
free(png);
|
||||||
|
|
||||||
|
/*use image here*/
|
||||||
|
|
||||||
|
free(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Example 3
|
||||||
|
Load PNG file from disk using a State, normally needed for more advanced usage.
|
||||||
|
*/
|
||||||
|
void decodeWithState(const char* filename) {
|
||||||
|
unsigned error;
|
||||||
|
unsigned char* image = 0;
|
||||||
|
unsigned width, height;
|
||||||
|
unsigned char* png = 0;
|
||||||
|
size_t pngsize;
|
||||||
|
LodePNGState state;
|
||||||
|
|
||||||
|
lodepng_state_init(&state);
|
||||||
|
/*optionally customize the state*/
|
||||||
|
|
||||||
|
error = lodepng_load_file(&png, &pngsize, filename);
|
||||||
|
if(!error) error = lodepng_decode(&image, &width, &height, &state, png, pngsize);
|
||||||
|
if(error) printf("error %u: %s\n", error, lodepng_error_text(error));
|
||||||
|
|
||||||
|
free(png);
|
||||||
|
|
||||||
|
/*use image here*/
|
||||||
|
/*state contains extra information about the PNG such as text chunks, ...*/
|
||||||
|
|
||||||
|
lodepng_state_cleanup(&state);
|
||||||
|
free(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
const char* filename = argc > 1 ? argv[1] : "test.png";
|
||||||
|
|
||||||
|
decodeOneStep(filename);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
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>
|
||||||
|
|
||||||
|
/*
|
||||||
|
3 ways to decode a PNG from a file to RGBA pixel data (and 2 in-memory ways).
|
||||||
|
*/
|
||||||
|
|
||||||
|
//g++ lodepng.cpp example_decode.cpp -ansi -pedantic -Wall -Wextra -O3
|
||||||
|
|
||||||
|
|
||||||
|
//Example 1
|
||||||
|
//Decode from disk to raw pixels with a single function call
|
||||||
|
void decodeOneStep(const char* filename) {
|
||||||
|
std::vector<unsigned char> image; //the raw pixels
|
||||||
|
unsigned width, height;
|
||||||
|
|
||||||
|
//decode
|
||||||
|
unsigned error = lodepng::decode(image, width, height, filename);
|
||||||
|
|
||||||
|
//if there's an error, display it
|
||||||
|
if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
|
||||||
|
//the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ...
|
||||||
|
}
|
||||||
|
|
||||||
|
//Example 2
|
||||||
|
//Load PNG file from disk to memory first, then decode to raw pixels in memory.
|
||||||
|
void decodeTwoSteps(const char* filename) {
|
||||||
|
std::vector<unsigned char> png;
|
||||||
|
std::vector<unsigned char> image; //the raw pixels
|
||||||
|
unsigned width, height;
|
||||||
|
|
||||||
|
//load and decode
|
||||||
|
unsigned error = lodepng::load_file(png, filename);
|
||||||
|
if(!error) error = lodepng::decode(image, width, height, png);
|
||||||
|
|
||||||
|
//if there's an error, display it
|
||||||
|
if(error) std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
|
||||||
|
//the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ...
|
||||||
|
}
|
||||||
|
|
||||||
|
//Example 3
|
||||||
|
//Load PNG file from disk using a State, normally needed for more advanced usage.
|
||||||
|
void decodeWithState(const char* filename) {
|
||||||
|
std::vector<unsigned char> png;
|
||||||
|
std::vector<unsigned char> image; //the raw pixels
|
||||||
|
unsigned width, height;
|
||||||
|
lodepng::State state; //optionally customize this one
|
||||||
|
|
||||||
|
unsigned error = lodepng::load_file(png, filename); //load the image file with given filename
|
||||||
|
if(!error) error = lodepng::decode(image, width, height, state, png);
|
||||||
|
|
||||||
|
//if there's an error, display it
|
||||||
|
if(error) std::cout << "decoder error " << error << ": "<< lodepng_error_text(error) << std::endl;
|
||||||
|
|
||||||
|
//the pixels are now in the vector "image", 4 bytes per pixel, ordered RGBARGBA..., use it as texture, draw it, ...
|
||||||
|
//State state contains extra information about the PNG such as text chunks, ...
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
const char* filename = argc > 1 ? argv[1] : "test.png";
|
||||||
|
|
||||||
|
decodeOneStep(filename);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
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 <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
3 ways to encode a PNG from RGBA pixel data to a file (and 2 in-memory ways).
|
||||||
|
NOTE: this samples overwrite the file or test.png without warning!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Example 1
|
||||||
|
Encode from raw pixels to disk with a single function call
|
||||||
|
The image argument has width * height RGBA pixels or width * height * 4 bytes
|
||||||
|
*/
|
||||||
|
void encodeOneStep(const char* filename, const unsigned char* image, unsigned width, unsigned height) {
|
||||||
|
/*Encode the image*/
|
||||||
|
unsigned error = lodepng_encode32_file(filename, image, width, height);
|
||||||
|
|
||||||
|
/*if there's an error, display it*/
|
||||||
|
if(error) printf("error %u: %s\n", error, lodepng_error_text(error));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Example 2
|
||||||
|
Encode from raw pixels to an in-memory PNG file first, then write it to disk
|
||||||
|
The image argument has width * height RGBA pixels or width * height * 4 bytes
|
||||||
|
*/
|
||||||
|
void encodeTwoSteps(const char* filename, const unsigned char* image, unsigned width, unsigned height) {
|
||||||
|
unsigned char* png;
|
||||||
|
size_t pngsize;
|
||||||
|
|
||||||
|
unsigned error = lodepng_encode32(&png, &pngsize, image, width, height);
|
||||||
|
if(!error) lodepng_save_file(png, pngsize, filename);
|
||||||
|
|
||||||
|
/*if there's an error, display it*/
|
||||||
|
if(error) printf("error %u: %s\n", error, lodepng_error_text(error));
|
||||||
|
|
||||||
|
free(png);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Example 3
|
||||||
|
Save a PNG file to disk using a State, normally needed for more advanced usage.
|
||||||
|
The image argument has width * height RGBA pixels or width * height * 4 bytes
|
||||||
|
*/
|
||||||
|
void encodeWithState(const char* filename, const unsigned char* image, unsigned width, unsigned height) {
|
||||||
|
unsigned error;
|
||||||
|
unsigned char* png;
|
||||||
|
size_t pngsize;
|
||||||
|
LodePNGState state;
|
||||||
|
|
||||||
|
lodepng_state_init(&state);
|
||||||
|
/*optionally customize the state*/
|
||||||
|
|
||||||
|
error = lodepng_encode(&png, &pngsize, image, width, height, &state);
|
||||||
|
if(!error) lodepng_save_file(png, pngsize, filename);
|
||||||
|
|
||||||
|
/*if there's an error, display it*/
|
||||||
|
if(error) printf("error %u: %s\n", error, lodepng_error_text(error));
|
||||||
|
|
||||||
|
lodepng_state_cleanup(&state);
|
||||||
|
free(png);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
const char* filename = argc > 1 ? argv[1] : "test.png";
|
||||||
|
|
||||||
|
/*generate some image*/
|
||||||
|
unsigned width = 512, height = 512;
|
||||||
|
unsigned char* image = malloc(width * height * 4);
|
||||||
|
unsigned x, y;
|
||||||
|
for(y = 0; y < height; y++)
|
||||||
|
for(x = 0; x < width; x++) {
|
||||||
|
image[4 * width * y + 4 * x + 0] = 255 * !(x & y);
|
||||||
|
image[4 * width * y + 4 * x + 1] = x ^ y;
|
||||||
|
image[4 * width * y + 4 * x + 2] = x | y;
|
||||||
|
image[4 * width * y + 4 * x + 3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*run an example*/
|
||||||
|
encodeOneStep(filename, image, width, height);
|
||||||
|
|
||||||
|
free(image);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
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>
|
||||||
|
|
||||||
|
/*
|
||||||
|
3 ways to encode a PNG from RGBA pixel data to a file (and 2 in-memory ways).
|
||||||
|
NOTE: this samples overwrite the file or test.png without warning!
|
||||||
|
*/
|
||||||
|
|
||||||
|
//g++ lodepng.cpp examples/example_encode.cpp -I./ -ansi -pedantic -Wall -Wextra -O3
|
||||||
|
|
||||||
|
//Example 1
|
||||||
|
//Encode from raw pixels to disk with a single function call
|
||||||
|
//The image argument has width * height RGBA pixels or width * height * 4 bytes
|
||||||
|
void encodeOneStep(const char* filename, std::vector<unsigned char>& image, unsigned width, unsigned height) {
|
||||||
|
//Encode the image
|
||||||
|
unsigned error = lodepng::encode(filename, image, width, height);
|
||||||
|
|
||||||
|
//if there's an error, display it
|
||||||
|
if(error) std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Example 2
|
||||||
|
//Encode from raw pixels to an in-memory PNG file first, then write it to disk
|
||||||
|
//The image argument has width * height RGBA pixels or width * height * 4 bytes
|
||||||
|
void encodeTwoSteps(const char* filename, std::vector<unsigned char>& image, unsigned width, unsigned height) {
|
||||||
|
std::vector<unsigned char> png;
|
||||||
|
|
||||||
|
unsigned error = lodepng::encode(png, image, width, height);
|
||||||
|
if(!error) lodepng::save_file(png, filename);
|
||||||
|
|
||||||
|
//if there's an error, display it
|
||||||
|
if(error) std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Example 3
|
||||||
|
//Save a PNG file to disk using a State, normally needed for more advanced usage.
|
||||||
|
//The image argument has width * height RGBA pixels or width * height * 4 bytes
|
||||||
|
void encodeWithState(const char* filename, std::vector<unsigned char>& image, unsigned width, unsigned height) {
|
||||||
|
std::vector<unsigned char> png;
|
||||||
|
lodepng::State state; //optionally customize this one
|
||||||
|
|
||||||
|
unsigned error = lodepng::encode(png, image, width, height, state);
|
||||||
|
if(!error) lodepng::save_file(png, filename);
|
||||||
|
|
||||||
|
//if there's an error, display it
|
||||||
|
if(error) std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//saves image to filename given as argument. Warning, this overwrites the file without warning!
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
//NOTE: this sample will overwrite the file or test.png without warning!
|
||||||
|
const char* filename = argc > 1 ? argv[1] : "test.png";
|
||||||
|
|
||||||
|
//generate some image
|
||||||
|
unsigned width = 512, height = 512;
|
||||||
|
std::vector<unsigned char> image;
|
||||||
|
image.resize(width * height * 4);
|
||||||
|
for(unsigned y = 0; y < height; y++)
|
||||||
|
for(unsigned x = 0; x < width; x++) {
|
||||||
|
image[4 * width * y + 4 * x + 0] = 255 * !(x & y);
|
||||||
|
image[4 * width * y + 4 * x + 1] = x ^ y;
|
||||||
|
image[4 * width * y + 4 * x + 2] = x | y;
|
||||||
|
image[4 * width * y + 4 * x + 3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
encodeOneStep(filename, image, width, height);
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
LodePNG Examples
|
||||||
|
|
||||||
|
Copyright (c) 2005-2015 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//g++ -I ./ lodepng.cpp examples/example_encode_type.cpp -ansi -pedantic -Wall -Wextra -O3
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
This example shows how to enforce a certain color type of the PNG image when
|
||||||
|
encoding a PNG (because by default, LodePNG automatically chooses an optimal
|
||||||
|
color type, no matter what your raw data's color type is)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "lodepng.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
//check if user gave a filename
|
||||||
|
if(argc < 2) {
|
||||||
|
std::cout << "please provide a filename to save to" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//generate some image
|
||||||
|
const unsigned w = 256;
|
||||||
|
const unsigned h = 256;
|
||||||
|
std::vector<unsigned char> image(w * h * 4);
|
||||||
|
for(unsigned y = 0; y < h; y++)
|
||||||
|
for(unsigned x = 0; x < w; x++) {
|
||||||
|
int index = y * w * 4 + x * 4;
|
||||||
|
image[index + 0] = 0;
|
||||||
|
image[index + 1] = 0;
|
||||||
|
image[index + 2] = 0;
|
||||||
|
image[index + 3] = 255;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we're going to encode with a state rather than a convenient function, because enforcing a color type requires setting options
|
||||||
|
lodepng::State state;
|
||||||
|
// input color type
|
||||||
|
state.info_raw.colortype = LCT_RGBA;
|
||||||
|
state.info_raw.bitdepth = 8;
|
||||||
|
// output color type
|
||||||
|
state.info_png.color.colortype = LCT_RGBA;
|
||||||
|
state.info_png.color.bitdepth = 8;
|
||||||
|
state.encoder.auto_convert = 0; // without this, it would ignore the output color type specified above and choose an optimal one instead
|
||||||
|
|
||||||
|
//encode and save
|
||||||
|
std::vector<unsigned char> buffer;
|
||||||
|
unsigned error = lodepng::encode(buffer, &image[0], w, h, state);
|
||||||
|
if(error) std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl;
|
||||||
|
else lodepng::save_file(buffer, argv[1]);
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
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>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Encodes given file as a gzip file.
|
||||||
|
|
||||||
|
See also the gzip specification, RFC 1952: http://www.gzip.org/zlib/rfc-gzip.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
//g++ lodepng.cpp example_gzip.cpp -ansi -pedantic -Wall -Wextra -O3
|
||||||
|
|
||||||
|
//saves image to filename given as argument. Warning, this overwrites the file without warning!
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if(argc < 2) {
|
||||||
|
std::cout << "Please provide input filename (output is input with .gz)" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//NOTE: this sample will overwrite the output file without warning!
|
||||||
|
std::string infilename = argv[1];
|
||||||
|
std::string outfilename = infilename + ".gz";
|
||||||
|
|
||||||
|
std::vector<unsigned char> in;
|
||||||
|
lodepng::load_file(in, infilename);
|
||||||
|
|
||||||
|
size_t outsize = 10;
|
||||||
|
unsigned char* out = (unsigned char*)malloc(outsize);
|
||||||
|
out[0] = 31; //ID1
|
||||||
|
out[1] = 139; //ID2
|
||||||
|
out[2] = 8; //CM
|
||||||
|
out[3] = 0; //FLG
|
||||||
|
//MTIME
|
||||||
|
out[4] = 0;
|
||||||
|
out[5] = 0;
|
||||||
|
out[6] = 0;
|
||||||
|
out[7] = 0;
|
||||||
|
|
||||||
|
out[8] = 2; //2 = slow, 4 = fast compression
|
||||||
|
out[9] = 255; //OS unknown
|
||||||
|
|
||||||
|
lodepng_deflate(&out, &outsize, &in[0], in.size(), &lodepng_default_compress_settings);
|
||||||
|
|
||||||
|
unsigned crc = lodepng_crc32(&in[0], in.size());
|
||||||
|
|
||||||
|
size_t footer = outsize;
|
||||||
|
|
||||||
|
outsize += 8;
|
||||||
|
out = (unsigned char*)realloc(out, outsize);
|
||||||
|
|
||||||
|
//CRC
|
||||||
|
out[footer + 0] = crc % 256;
|
||||||
|
out[footer + 1] = (crc >> 8) % 256;
|
||||||
|
out[footer + 2] = (crc >> 16) % 256;
|
||||||
|
out[footer + 3] = (crc >> 24) % 256;
|
||||||
|
|
||||||
|
//ISIZE
|
||||||
|
out[footer + 4] = in.size() % 256;
|
||||||
|
out[footer + 5] = (in.size() >> 8) % 256;
|
||||||
|
out[footer + 6] = (in.size() >> 16) % 256;
|
||||||
|
out[footer + 7] = (in.size() >> 24) % 256;
|
||||||
|
|
||||||
|
lodepng_save_file(out, outsize, outfilename.c_str());
|
||||||
|
|
||||||
|
free(out);
|
||||||
|
}
|
|
@ -0,0 +1,153 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Compile command for Linux:
|
||||||
|
//g++ lodepng.cpp example_opengl.cpp -lSDL -lGL -O3
|
||||||
|
|
||||||
|
/*
|
||||||
|
LodePNG OpenGL example. Decodes a PNG and shows it in OpenGL. PNG filename
|
||||||
|
should be given as a command line parameter.
|
||||||
|
|
||||||
|
It's written for the most basic old OpenGL version, and a correction for non
|
||||||
|
power of two textures had to be added.
|
||||||
|
|
||||||
|
Only very few lines on the sample are about loading the PNG. Most of the
|
||||||
|
sample lines show a way to render a texture in 2D in OpenGL.
|
||||||
|
|
||||||
|
No fancy 3D graphics are shown, it only shows the image statically. The sample
|
||||||
|
shows LodePNG can be used to load PNG images as textures in OpenGL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lodepng.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <SDL/SDL.h>
|
||||||
|
#include <GL/gl.h>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
if(argc < 2) {
|
||||||
|
std::cout << "Please provide a filename." << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
const char* filename = argv[1];
|
||||||
|
|
||||||
|
// Load file and decode image.
|
||||||
|
std::vector<unsigned char> image;
|
||||||
|
unsigned width, height;
|
||||||
|
unsigned error = lodepng::decode(image, width, height, filename);
|
||||||
|
|
||||||
|
// If there's an error, display it.
|
||||||
|
if(error != 0) {
|
||||||
|
std::cout << "error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Here the PNG is loaded in "image". All the rest of the code is SDL and OpenGL stuff.
|
||||||
|
|
||||||
|
int screenw = width;
|
||||||
|
if(screenw > 1024) screenw = 1024;
|
||||||
|
int screenh = height;
|
||||||
|
if(screenh > 768) screenw = 768;
|
||||||
|
|
||||||
|
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||||
|
std::cout << "Error: Unable to init SDL: " << SDL_GetError() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Surface* scr = SDL_SetVideoMode(screenw, screenh, 32, SDL_OPENGL);
|
||||||
|
|
||||||
|
if(scr == 0) {
|
||||||
|
std::cout << "Error: Unable to set video. SDL error message: " << SDL_GetError() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// The official code for "Setting Your Raster Position to a Pixel Location" (i.e. set up a camera for 2D screen)
|
||||||
|
glViewport(0, 0, screenw, screenh);
|
||||||
|
glMatrixMode(GL_PROJECTION);
|
||||||
|
glLoadIdentity();
|
||||||
|
glOrtho(0, screenw, screenh, 0, -1, 1);
|
||||||
|
glMatrixMode(GL_MODELVIEW);
|
||||||
|
glLoadIdentity();
|
||||||
|
|
||||||
|
// Make some OpenGL properties better for 2D and enable alpha channel.
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glDisable(GL_ALPHA_TEST);
|
||||||
|
|
||||||
|
if(glGetError() != GL_NO_ERROR) {
|
||||||
|
std::cout << "Error initing GL" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Texture size must be power of two for the primitive OpenGL version this is written for. Find next power of two.
|
||||||
|
size_t u2 = 1; while(u2 < width) u2 *= 2;
|
||||||
|
size_t v2 = 1; while(v2 < height) v2 *= 2;
|
||||||
|
// Ratio for power of two version compared to actual version, to render the non power of two image with proper size.
|
||||||
|
double u3 = (double)width / u2;
|
||||||
|
double v3 = (double)height / v2;
|
||||||
|
|
||||||
|
// Make power of two version of the image.
|
||||||
|
std::vector<unsigned char> image2(u2 * v2 * 4);
|
||||||
|
for(size_t y = 0; y < height; y++)
|
||||||
|
for(size_t x = 0; x < width; x++)
|
||||||
|
for(size_t c = 0; c < 4; c++) {
|
||||||
|
image2[4 * u2 * y + 4 * x + c] = image[4 * width * y + 4 * x + c];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable the texture for OpenGL.
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //GL_NEAREST = no smoothing
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, 4, u2, v2, 0, GL_RGBA, GL_UNSIGNED_BYTE, &image2[0]);
|
||||||
|
|
||||||
|
bool done = false;
|
||||||
|
SDL_Event event = {0};
|
||||||
|
glColor4ub(255, 255, 255, 255);
|
||||||
|
|
||||||
|
while(!done) {
|
||||||
|
// Quit the loop when receiving quit event.
|
||||||
|
while(SDL_PollEvent(&event)) {
|
||||||
|
if(event.type == SDL_QUIT) done = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw the texture on a quad, using u3 and v3 to correct non power of two texture size.
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glTexCoord2d( 0, 0); glVertex2f( 0, 0);
|
||||||
|
glTexCoord2d(u3, 0); glVertex2f(width, 0);
|
||||||
|
glTexCoord2d(u3, v3); glVertex2f(width, height);
|
||||||
|
glTexCoord2d( 0, v3); glVertex2f( 0, height);
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
// Redraw and clear screen.
|
||||||
|
SDL_GL_SwapBuffers();
|
||||||
|
glClearColor(0, 0, 0, 0);
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
//Limit frames per second, to not heat up the CPU and GPU too much.
|
||||||
|
SDL_Delay(16);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This example saves the PNG with the best compression LodePNG can do, and with
|
||||||
|
unnecessary chunks removed. It tries out several combinations of settings and
|
||||||
|
keeps the smallest one.
|
||||||
|
|
||||||
|
NOTE: This is not as good as a true PNG optimizer like optipng or pngcrush.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//g++ lodepng.cpp example_optimize_png.cpp -ansi -pedantic -Wall -Wextra -O3
|
||||||
|
|
||||||
|
#include "lodepng.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
std::vector<unsigned char> image;
|
||||||
|
unsigned w, h;
|
||||||
|
std::vector<unsigned char> buffer;
|
||||||
|
unsigned error;
|
||||||
|
|
||||||
|
//check if user gave a filename
|
||||||
|
if(argc < 3) {
|
||||||
|
std::cout << "please provide in and out filename" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lodepng::load_file(buffer, argv[1]);
|
||||||
|
error = lodepng::decode(image, w, h, buffer);
|
||||||
|
|
||||||
|
if(error) {
|
||||||
|
std::cout << "decoding error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t origsize = buffer.size();
|
||||||
|
std::cout << "Original size: " << origsize << " (" << (origsize / 1024) << "K)" << std::endl;
|
||||||
|
buffer.clear();
|
||||||
|
|
||||||
|
//Now encode as hard as possible with several filter types and window sizes
|
||||||
|
|
||||||
|
lodepng::State state;
|
||||||
|
state.encoder.filter_palette_zero = 0; //We try several filter types, including zero, allow trying them all on palette images too.
|
||||||
|
state.encoder.add_id = false; //Don't add LodePNG version chunk to save more bytes
|
||||||
|
state.encoder.text_compression = 1; //Not needed because we don't add text chunks, but this demonstrates another optimization setting
|
||||||
|
state.encoder.zlibsettings.nicematch = 258; //Set this to the max possible, otherwise it can hurt compression
|
||||||
|
state.encoder.zlibsettings.lazymatching = 1; //Definitely use lazy matching for better compression
|
||||||
|
state.encoder.zlibsettings.windowsize = 32768; //Use maximum possible window size for best compression
|
||||||
|
|
||||||
|
size_t bestsize = 0;
|
||||||
|
bool inited = false;
|
||||||
|
|
||||||
|
int beststrategy = 0;
|
||||||
|
LodePNGFilterStrategy strategies[4] = { LFS_ZERO, LFS_MINSUM, LFS_ENTROPY, LFS_BRUTE_FORCE };
|
||||||
|
std::string strategynames[4] = { "LFS_ZERO", "LFS_MINSUM", "LFS_ENTROPY", "LFS_BRUTE_FORCE" };
|
||||||
|
|
||||||
|
// min match 3 allows all deflate lengths. min match 6 is similar to "Z_FILTERED" of zlib.
|
||||||
|
int minmatches[2] = { 3, 6 };
|
||||||
|
int bestminmatch = 0;
|
||||||
|
|
||||||
|
int autoconverts[2] = { 0, 1 };
|
||||||
|
std::string autoconvertnames[2] = { "0", "1" };
|
||||||
|
int bestautoconvert = 0;
|
||||||
|
|
||||||
|
int bestblocktype = 0;
|
||||||
|
|
||||||
|
// Try out all combinations of everything
|
||||||
|
for(int i = 0; i < 4; i++) //filter strategy
|
||||||
|
for(int j = 0; j < 2; j++) //min match
|
||||||
|
for(int k = 0; k < 2; k++) //block type (for small images only)
|
||||||
|
for(int l = 0; l < 2; l++) { //color convert strategy
|
||||||
|
if(bestsize > 3000 && (k > 0 || l > 0)) continue; /* these only make sense on small images */
|
||||||
|
std::vector<unsigned char> temp;
|
||||||
|
state.encoder.filter_strategy = strategies[i];
|
||||||
|
state.encoder.zlibsettings.minmatch = minmatches[j];
|
||||||
|
state.encoder.zlibsettings.btype = k == 0 ? 2 : 1;
|
||||||
|
state.encoder.auto_convert = autoconverts[l];
|
||||||
|
error = lodepng::encode(temp, image, w, h, state);
|
||||||
|
|
||||||
|
if(error)
|
||||||
|
{
|
||||||
|
std::cout << "encoding error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!inited || temp.size() < bestsize)
|
||||||
|
{
|
||||||
|
bestsize = temp.size();
|
||||||
|
beststrategy = i;
|
||||||
|
bestminmatch = state.encoder.zlibsettings.minmatch;
|
||||||
|
bestautoconvert = l;
|
||||||
|
bestblocktype = state.encoder.zlibsettings.btype;
|
||||||
|
temp.swap(buffer);
|
||||||
|
inited = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Chosen filter strategy: " << strategynames[beststrategy] << std::endl;
|
||||||
|
std::cout << "Chosen min match: " << bestminmatch << std::endl;
|
||||||
|
std::cout << "Chosen block type: " << bestblocktype << std::endl;
|
||||||
|
std::cout << "Chosen auto convert: " << autoconvertnames[bestautoconvert] << std::endl;
|
||||||
|
|
||||||
|
lodepng::save_file(buffer, argv[2]);
|
||||||
|
std::cout << "New size: " << buffer.size() << " (" << (buffer.size() / 1024) << "K)" << std::endl;
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
/*
|
||||||
|
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);
|
||||||
|
}
|
|
@ -0,0 +1,313 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//g++ lodepng.cpp example_png_info.cpp -ansi -pedantic -Wall -Wextra -lSDL -O3
|
||||||
|
|
||||||
|
/*
|
||||||
|
This sample shows a lot of information in the console about a PNG file,
|
||||||
|
including color type, text chunks, the names of all chunks in the image,
|
||||||
|
etc...
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "lodepng.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Display general info about the PNG.
|
||||||
|
*/
|
||||||
|
void displayPNGInfo(const LodePNGInfo& info) {
|
||||||
|
const LodePNGColorMode& color = info.color;
|
||||||
|
|
||||||
|
std::cout << "Compression method: " << info.compression_method << std::endl;
|
||||||
|
std::cout << "Filter method: " << info.filter_method << std::endl;
|
||||||
|
std::cout << "Interlace method: " << info.interlace_method << std::endl;
|
||||||
|
std::cout << "Color type: " << color.colortype << std::endl;
|
||||||
|
std::cout << "Bit depth: " << color.bitdepth << std::endl;
|
||||||
|
std::cout << "Bits per pixel: " << lodepng_get_bpp(&color) << std::endl;
|
||||||
|
std::cout << "Channels per pixel: " << lodepng_get_channels(&color) << std::endl;
|
||||||
|
std::cout << "Is greyscale type: " << lodepng_is_greyscale_type(&color) << std::endl;
|
||||||
|
std::cout << "Can have alpha: " << lodepng_can_have_alpha(&color) << std::endl;
|
||||||
|
std::cout << "Palette size: " << color.palettesize << std::endl;
|
||||||
|
std::cout << "Has color key: " << color.key_defined << std::endl;
|
||||||
|
if(color.key_defined) {
|
||||||
|
std::cout << "Color key r: " << color.key_r << std::endl;
|
||||||
|
std::cout << "Color key g: " << color.key_g << std::endl;
|
||||||
|
std::cout << "Color key b: " << color.key_b << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "Texts: " << info.text_num << std::endl;
|
||||||
|
for(size_t i = 0; i < info.text_num; i++) {
|
||||||
|
std::cout << "Text: " << info.text_keys[i] << ": " << info.text_strings[i] << std::endl << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "International texts: " << info.itext_num << std::endl;
|
||||||
|
for(size_t i = 0; i < info.itext_num; i++) {
|
||||||
|
std::cout << "Text: "
|
||||||
|
<< info.itext_keys[i] << ", "
|
||||||
|
<< info.itext_langtags[i] << ", "
|
||||||
|
<< info.itext_transkeys[i] << ": "
|
||||||
|
<< info.itext_strings[i] << std::endl << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "Time defined: " << info.time_defined << std::endl;
|
||||||
|
if(info.time_defined) {
|
||||||
|
const LodePNGTime& time = info.time;
|
||||||
|
std::cout << "year: " << time.year << std::endl;
|
||||||
|
std::cout << "month: " << time.month << std::endl;
|
||||||
|
std::cout << "day: " << time.day << std::endl;
|
||||||
|
std::cout << "hour: " << time.hour << std::endl;
|
||||||
|
std::cout << "minute: " << time.minute << std::endl;
|
||||||
|
std::cout << "second: " << time.second << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << "Physics defined: " << info.phys_defined << std::endl;
|
||||||
|
if(info.phys_defined) {
|
||||||
|
std::cout << "physics X: " << info.phys_x << std::endl;
|
||||||
|
std::cout << "physics Y: " << info.phys_y << std::endl;
|
||||||
|
std::cout << "physics unit: " << info.phys_unit << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Display the names and sizes of all chunks in the PNG file.
|
||||||
|
*/
|
||||||
|
void displayChunkNames(const std::vector<unsigned char>& buffer) {
|
||||||
|
// Listing chunks is based on the original file, not the decoded png info.
|
||||||
|
const unsigned char *chunk, *end;
|
||||||
|
end = &buffer.back() + 1;
|
||||||
|
chunk = &buffer.front() + 8;
|
||||||
|
|
||||||
|
std::cout << std::endl << "Chunks:" << std::endl;
|
||||||
|
std::cout << " type: length(s)";
|
||||||
|
std::string last_type;
|
||||||
|
while(chunk < end && end - chunk >= 8) {
|
||||||
|
char type[5];
|
||||||
|
lodepng_chunk_type(type, chunk);
|
||||||
|
if(std::string(type).size() != 4) {
|
||||||
|
std::cout << "this is probably not a PNG" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(last_type != type) {
|
||||||
|
std::cout << std::endl;
|
||||||
|
std::cout << " " << type << ": ";
|
||||||
|
}
|
||||||
|
last_type = type;
|
||||||
|
|
||||||
|
std::cout << lodepng_chunk_length(chunk) << ", ";
|
||||||
|
|
||||||
|
chunk = lodepng_chunk_next_const(chunk, end);
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Show ASCII art preview of the image
|
||||||
|
*/
|
||||||
|
void displayAsciiArt(const std::vector<unsigned char>& image, unsigned w, unsigned h) {
|
||||||
|
if(w > 0 && h > 0) {
|
||||||
|
std::cout << std::endl << "ASCII Art Preview: " << std::endl;
|
||||||
|
unsigned w2 = 48;
|
||||||
|
if(w < w2) w2 = w;
|
||||||
|
unsigned h2 = h * w2 / w;
|
||||||
|
h2 = (h2 * 2) / 3; //compensate for non-square characters in terminal
|
||||||
|
if(h2 > (w2 * 2)) h2 = w2 * 2; //avoid too large output
|
||||||
|
|
||||||
|
std::cout << '+';
|
||||||
|
for(unsigned x = 0; x < w2; x++) std::cout << '-';
|
||||||
|
std::cout << '+' << std::endl;
|
||||||
|
for(unsigned y = 0; y < h2; y++) {
|
||||||
|
std::cout << "|";
|
||||||
|
for(unsigned x = 0; x < w2; x++) {
|
||||||
|
unsigned x2 = x * w / w2;
|
||||||
|
unsigned y2 = y * h / h2;
|
||||||
|
int r = image[y2 * w * 4 + x2 * 4 + 0];
|
||||||
|
int g = image[y2 * w * 4 + x2 * 4 + 1];
|
||||||
|
int b = image[y2 * w * 4 + x2 * 4 + 2];
|
||||||
|
int a = image[y2 * w * 4 + x2 * 4 + 3];
|
||||||
|
int lightness = ((r + g + b) / 3) * a / 255;
|
||||||
|
int min = (r < g && r < b) ? r : (g < b ? g : b);
|
||||||
|
int max = (r > g && r > b) ? r : (g > b ? g : b);
|
||||||
|
int saturation = max - min;
|
||||||
|
int letter = 'i'; //i for grey, or r,y,g,c,b,m for colors
|
||||||
|
if(saturation > 32) {
|
||||||
|
int h = lightness >= (min + max) / 2;
|
||||||
|
if(h) letter = (min == r ? 'c' : (min == g ? 'm' : 'y'));
|
||||||
|
else letter = (max == r ? 'r' : (max == g ? 'g' : 'b'));
|
||||||
|
}
|
||||||
|
int symbol = ' ';
|
||||||
|
if(lightness > 224) symbol = '@';
|
||||||
|
else if(lightness > 128) symbol = letter - 32;
|
||||||
|
else if(lightness > 32) symbol = letter;
|
||||||
|
else if(lightness > 16) symbol = '.';
|
||||||
|
std::cout << (char)symbol;
|
||||||
|
}
|
||||||
|
std::cout << "|";
|
||||||
|
std::cout << std::endl;
|
||||||
|
}
|
||||||
|
std::cout << '+';
|
||||||
|
for(unsigned x = 0; x < w2; x++) std::cout << '-';
|
||||||
|
std::cout << '+' << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Show the filtertypes of each scanline in this PNG image.
|
||||||
|
*/
|
||||||
|
void displayFilterTypes(const std::vector<unsigned char>& buffer, bool ignore_checksums) {
|
||||||
|
//Get color type and interlace type
|
||||||
|
lodepng::State state;
|
||||||
|
if(ignore_checksums) {
|
||||||
|
state.decoder.ignore_crc = 1;
|
||||||
|
state.decoder.zlibsettings.ignore_adler32 = 1;
|
||||||
|
}
|
||||||
|
unsigned w, h;
|
||||||
|
unsigned error;
|
||||||
|
error = lodepng_inspect(&w, &h, &state, &buffer[0], buffer.size());
|
||||||
|
|
||||||
|
if(error) {
|
||||||
|
std::cout << "inspect error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(state.info_png.interlace_method == 1) {
|
||||||
|
std::cout << "showing filtertypes for interlaced PNG not supported by this example" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Read literal data from all IDAT chunks
|
||||||
|
const unsigned char *chunk, *begin, *end;
|
||||||
|
end = &buffer.back() + 1;
|
||||||
|
begin = chunk = &buffer.front() + 8;
|
||||||
|
|
||||||
|
std::vector<unsigned char> zdata;
|
||||||
|
|
||||||
|
while(chunk < end && end - chunk >= 8) {
|
||||||
|
char type[5];
|
||||||
|
lodepng_chunk_type(type, chunk);
|
||||||
|
if(std::string(type).size() != 4) {
|
||||||
|
std::cout << "this is probably not a PNG" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(std::string(type) == "IDAT") {
|
||||||
|
const unsigned char* cdata = lodepng_chunk_data_const(chunk);
|
||||||
|
unsigned clength = lodepng_chunk_length(chunk);
|
||||||
|
if(chunk + clength + 12 > end || clength > buffer.size() || chunk + clength + 12 < begin) {
|
||||||
|
std::cout << "invalid chunk length" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned i = 0; i < clength; i++) {
|
||||||
|
zdata.push_back(cdata[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
chunk = lodepng_chunk_next_const(chunk, end);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Decompress all IDAT data
|
||||||
|
std::vector<unsigned char> data;
|
||||||
|
error = lodepng::decompress(data, &zdata[0], zdata.size());
|
||||||
|
|
||||||
|
if(error) {
|
||||||
|
std::cout << "decompress error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//A line is 1 filter byte + all pixels
|
||||||
|
size_t linebytes = 1 + lodepng_get_raw_size(w, 1, &state.info_png.color);
|
||||||
|
|
||||||
|
if(linebytes == 0) {
|
||||||
|
std::cout << "error: linebytes is 0" << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Filter types: ";
|
||||||
|
for(size_t i = 0; i < data.size(); i += linebytes) {
|
||||||
|
std::cout << (int)(data[i]) << " ";
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Main
|
||||||
|
*/
|
||||||
|
int main(int argc, char *argv[]) /*list the chunks*/ {
|
||||||
|
bool ignore_checksums = false;
|
||||||
|
std::string filename = "";
|
||||||
|
for (int i = 1; i < argc; i++) {
|
||||||
|
if(std::string(argv[i]) == "--ignore_checksums") ignore_checksums = true;
|
||||||
|
else filename = argv[i];
|
||||||
|
}
|
||||||
|
if(filename == "") {
|
||||||
|
std::cout << "Please provide a filename to preview" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> buffer;
|
||||||
|
std::vector<unsigned char> image;
|
||||||
|
unsigned w, h;
|
||||||
|
|
||||||
|
lodepng::load_file(buffer, filename); //load the image file with given filename
|
||||||
|
|
||||||
|
lodepng::State state;
|
||||||
|
if(ignore_checksums) {
|
||||||
|
state.decoder.ignore_crc = 1;
|
||||||
|
state.decoder.zlibsettings.ignore_adler32 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned error = lodepng::decode(image, w, h, state, buffer);
|
||||||
|
|
||||||
|
if(error) {
|
||||||
|
std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::cout << "Filesize: " << buffer.size() << " (" << buffer.size() / 1024 << "K)" << std::endl;
|
||||||
|
std::cout << "Width: " << w << std::endl;
|
||||||
|
std::cout << "Height: " << h << std::endl;
|
||||||
|
std::cout << "Num pixels: " << w * h << std::endl;
|
||||||
|
|
||||||
|
if(w > 0 && h > 0) {
|
||||||
|
std::cout << "Top left pixel color:"
|
||||||
|
<< " r: " << (int)image[0]
|
||||||
|
<< " g: " << (int)image[1]
|
||||||
|
<< " b: " << (int)image[2]
|
||||||
|
<< " a: " << (int)image[3]
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
displayPNGInfo(state.info_png);
|
||||||
|
std::cout << std::endl;
|
||||||
|
displayChunkNames(buffer);
|
||||||
|
std::cout << std::endl;
|
||||||
|
displayFilterTypes(buffer, ignore_checksums);
|
||||||
|
std::cout << std::endl;
|
||||||
|
displayAsciiArt(image, w, h);
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
LodePNG decode-encode: decodes the image, then encodes it again, with all the
|
||||||
|
same information, chunks, color types, etc... as the original image had.
|
||||||
|
This sample shows how LodePNG can be used for a conforming PNG editor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//g++ lodepng.cpp example_reencode.cpp -ansi -pedantic -Wall -Wextra -lSDL -O3 -o reencode
|
||||||
|
|
||||||
|
#include "lodepng.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
std::vector<unsigned char> image;
|
||||||
|
unsigned w, h;
|
||||||
|
std::vector<unsigned char> buffer;
|
||||||
|
lodepng::State state;
|
||||||
|
unsigned error;
|
||||||
|
|
||||||
|
//check if user gave a filename
|
||||||
|
if(argc < 3) {
|
||||||
|
std::cout << "please provide in and out filename" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.decoder.color_convert = 0;
|
||||||
|
state.decoder.remember_unknown_chunks = 1; //make it reproduce even unknown chunks in the saved image
|
||||||
|
|
||||||
|
lodepng::load_file(buffer, argv[1]);
|
||||||
|
error = lodepng::decode(image, w, h, state, buffer);
|
||||||
|
if(error) {
|
||||||
|
std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.clear();
|
||||||
|
|
||||||
|
state.encoder.text_compression = 1;
|
||||||
|
|
||||||
|
error = lodepng::encode(buffer, image, w, h, state);
|
||||||
|
if(error) {
|
||||||
|
std::cout << "encoder error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lodepng::save_file(buffer, argv[2]);
|
||||||
|
}
|
|
@ -0,0 +1,133 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Compile command for Linux:
|
||||||
|
gcc lodepng.c example_sdl.c -ansi -pedantic -Wall -Wextra -lSDL -O3 -o showpng
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
LodePNG SDL example
|
||||||
|
This example displays a PNG with a checkerboard pattern to show tranparency.
|
||||||
|
It requires the SDL library to compile and run.
|
||||||
|
If multiple filenames are given to the command line, it shows all of them.
|
||||||
|
Press any key to see next image, or esc to quit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lodepng.h"
|
||||||
|
|
||||||
|
#include <SDL/SDL.h>
|
||||||
|
|
||||||
|
/*shows image with SDL. Returns 1 if user wants to fully quit, 0 if user wants to see next image.*/
|
||||||
|
int show(const char* filename) {
|
||||||
|
unsigned error;
|
||||||
|
unsigned char* image;
|
||||||
|
unsigned w, h, x, y;
|
||||||
|
SDL_Surface* scr;
|
||||||
|
SDL_Event event;
|
||||||
|
int done;
|
||||||
|
size_t jump = 1;
|
||||||
|
|
||||||
|
printf("showing %s\n", filename);
|
||||||
|
|
||||||
|
/*load the PNG in one function call*/
|
||||||
|
error = lodepng_decode32_file(&image, &w, &h, filename);
|
||||||
|
|
||||||
|
/*stop if there is an error*/
|
||||||
|
if(error) {
|
||||||
|
printf("decoder error %u: %s\n", error, lodepng_error_text(error));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*avoid too large window size by downscaling large image*/
|
||||||
|
|
||||||
|
if(w / 1024 >= jump) jump = w / 1024 + 1;
|
||||||
|
if(h / 1024 >= jump) jump = h / 1024 + 1;
|
||||||
|
|
||||||
|
/*init SDL*/
|
||||||
|
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||||
|
printf("Error, SDL video init failed\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
scr = SDL_SetVideoMode(w / jump, h / jump, 32, SDL_HWSURFACE);
|
||||||
|
if(!scr) {
|
||||||
|
printf("Error, no SDL screen\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SDL_WM_SetCaption(filename, NULL); /*set window caption*/
|
||||||
|
|
||||||
|
/*plot the pixels of the PNG file*/
|
||||||
|
for(y = 0; y + jump - 1 < h; y += jump)
|
||||||
|
for(x = 0; x + jump - 1 < w; x += jump) {
|
||||||
|
int checkerColor;
|
||||||
|
Uint32* bufp;
|
||||||
|
Uint32 r, g, b, a;
|
||||||
|
|
||||||
|
/*get RGBA components*/
|
||||||
|
r = image[4 * y * w + 4 * x + 0]; /*red*/
|
||||||
|
g = image[4 * y * w + 4 * x + 1]; /*green*/
|
||||||
|
b = image[4 * y * w + 4 * x + 2]; /*blue*/
|
||||||
|
a = image[4 * y * w + 4 * x + 3]; /*alpha*/
|
||||||
|
|
||||||
|
/*make translucency visible by placing checkerboard pattern behind image*/
|
||||||
|
checkerColor = 191 + 64 * (((x / 16) % 2) == ((y / 16) % 2));
|
||||||
|
r = (a * r + (255 - a) * checkerColor) / 255;
|
||||||
|
g = (a * g + (255 - a) * checkerColor) / 255;
|
||||||
|
b = (a * b + (255 - a) * checkerColor) / 255;
|
||||||
|
|
||||||
|
/*give the color value to the pixel of the screenbuffer*/
|
||||||
|
bufp = (Uint32 *)scr->pixels + (y * scr->pitch / 4) / jump + (x / jump);
|
||||||
|
*bufp = 65536 * r + 256 * g + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*pause until you press escape and meanwhile redraw screen*/
|
||||||
|
done = 0;
|
||||||
|
while(done == 0) {
|
||||||
|
while(SDL_PollEvent(&event)) {
|
||||||
|
if(event.type == SDL_QUIT) done = 2;
|
||||||
|
else if(SDL_GetKeyState(NULL)[SDLK_ESCAPE]) done = 2;
|
||||||
|
else if(event.type == SDL_KEYDOWN) done = 1; /*press any other key for next image*/
|
||||||
|
}
|
||||||
|
SDL_UpdateRect(scr, 0, 0, 0, 0); /*redraw screen*/
|
||||||
|
SDL_Delay(5); /*pause 5 ms so it consumes less processing power*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/*cleanup*/
|
||||||
|
free(image);
|
||||||
|
SDL_Quit();
|
||||||
|
return done == 2 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if(argc <= 1) printf("Please enter PNG file name(s) to display\n");;
|
||||||
|
|
||||||
|
for(i = 1; i < argc; i++) {
|
||||||
|
if(show(argv[i])) return 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//Compile command for Linux:
|
||||||
|
//g++ lodepng.cpp example_sdl.cpp -lSDL -O3 -o showpng
|
||||||
|
|
||||||
|
/*
|
||||||
|
LodePNG SDL example
|
||||||
|
This example displays a PNG with a checkerboard pattern to show tranparency.
|
||||||
|
It requires the SDL library to compile and run.
|
||||||
|
If multiple filenames are given to the command line, it shows all of them.
|
||||||
|
Press any key to see next image, or esc to quit.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lodepng.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <SDL/SDL.h>
|
||||||
|
|
||||||
|
int show(const std::string& caption, const unsigned char* rgba, unsigned w, unsigned h) {
|
||||||
|
//avoid too large window size by downscaling large image
|
||||||
|
unsigned jump = 1;
|
||||||
|
if(w / 1024 >= jump) jump = w / 1024 + 1;
|
||||||
|
if(h / 1024 >= jump) jump = h / 1024 + 1;
|
||||||
|
|
||||||
|
//init SDL
|
||||||
|
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||||
|
std::cout << "error, SDL video init failed" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SDL_Surface* scr = SDL_SetVideoMode(w / jump, h / jump, 32, SDL_HWSURFACE);
|
||||||
|
if(!scr) {
|
||||||
|
std::cout << "error, no SDL screen" << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
SDL_WM_SetCaption(caption.c_str(), NULL); //set window caption
|
||||||
|
|
||||||
|
//plot the pixels of the PNG file
|
||||||
|
for(unsigned y = 0; y + jump - 1 < h; y += jump)
|
||||||
|
for(unsigned x = 0; x + jump - 1 < w; x += jump) {
|
||||||
|
//get RGBA components
|
||||||
|
Uint32 r = rgba[4 * y * w + 4 * x + 0]; //red
|
||||||
|
Uint32 g = rgba[4 * y * w + 4 * x + 1]; //green
|
||||||
|
Uint32 b = rgba[4 * y * w + 4 * x + 2]; //blue
|
||||||
|
Uint32 a = rgba[4 * y * w + 4 * x + 3]; //alpha
|
||||||
|
|
||||||
|
//make translucency visible by placing checkerboard pattern behind image
|
||||||
|
int checkerColor = 191 + 64 * (((x / 16) % 2) == ((y / 16) % 2));
|
||||||
|
r = (a * r + (255 - a) * checkerColor) / 255;
|
||||||
|
g = (a * g + (255 - a) * checkerColor) / 255;
|
||||||
|
b = (a * b + (255 - a) * checkerColor) / 255;
|
||||||
|
|
||||||
|
//give the color value to the pixel of the screenbuffer
|
||||||
|
Uint32* bufp;
|
||||||
|
bufp = (Uint32 *)scr->pixels + (y * scr->pitch / 4) / jump + (x / jump);
|
||||||
|
*bufp = 65536 * r + 256 * g + b;
|
||||||
|
}
|
||||||
|
|
||||||
|
//pause until you press escape and meanwhile redraw screen
|
||||||
|
SDL_Event event;
|
||||||
|
int done = 0;
|
||||||
|
while(done == 0) {
|
||||||
|
while(SDL_PollEvent(&event)) {
|
||||||
|
if(event.type == SDL_QUIT) done = 2;
|
||||||
|
else if(SDL_GetKeyState(NULL)[SDLK_ESCAPE]) done = 2;
|
||||||
|
else if(event.type == SDL_KEYDOWN) done = 1; //press any other key for next image
|
||||||
|
}
|
||||||
|
SDL_UpdateRect(scr, 0, 0, 0, 0); //redraw screen
|
||||||
|
SDL_Delay(5); //pause 5 ms so it consumes less processing power
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Quit();
|
||||||
|
return done == 2 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*shows image with SDL. Returns 1 if user wants to fully quit, 0 if user wants to see next image.*/
|
||||||
|
int showfile(const char* filename) {
|
||||||
|
std::cout << "showing " << filename << std::endl;
|
||||||
|
|
||||||
|
std::vector<unsigned char> buffer, image;
|
||||||
|
lodepng::load_file(buffer, filename); //load the image file with given filename
|
||||||
|
unsigned w, h;
|
||||||
|
unsigned error = lodepng::decode(image, w, h, buffer); //decode the png
|
||||||
|
|
||||||
|
//stop if there is an error
|
||||||
|
if(error) {
|
||||||
|
std::cout << "decoder error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return show(filename, &image[0], w, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
if(argc <= 1) std::cout << "Please enter PNG file name(s) to display" << std::endl;
|
||||||
|
|
||||||
|
for(int i = 1; i < argc; i++) {
|
||||||
|
if(showfile(argv[i])) return 0;
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
6410
oss-internship-2020/sapi_lodepng/lodepng-master/lodepng.c
Normal file
6410
oss-internship-2020/sapi_lodepng/lodepng-master/lodepng.c
Normal file
File diff suppressed because it is too large
Load Diff
6410
oss-internship-2020/sapi_lodepng/lodepng-master/lodepng.cpp
Normal file
6410
oss-internship-2020/sapi_lodepng/lodepng-master/lodepng.cpp
Normal file
File diff suppressed because it is too large
Load Diff
1959
oss-internship-2020/sapi_lodepng/lodepng-master/lodepng.h
Normal file
1959
oss-internship-2020/sapi_lodepng/lodepng-master/lodepng.h
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,350 @@
|
||||||
|
/*
|
||||||
|
LodePNG Benchmark
|
||||||
|
|
||||||
|
Copyright (c) 2005-2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//g++ lodepng.cpp lodepng_benchmark.cpp -Wall -Wextra -pedantic -ansi -lSDL -O3
|
||||||
|
//g++ lodepng.cpp lodepng_benchmark.cpp -Wall -Wextra -pedantic -ansi -lSDL -O3 && ./a.out
|
||||||
|
|
||||||
|
#include "lodepng.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <SDL/SDL.h> //SDL is used for timing.
|
||||||
|
|
||||||
|
bool apply_mods = false;
|
||||||
|
|
||||||
|
#define NUM_DECODE 5 //decode multiple times to measure better. Must be at least 1.
|
||||||
|
|
||||||
|
size_t total_pixels = 0;
|
||||||
|
size_t total_png_orig_size = 0;
|
||||||
|
size_t total_raw_orig_size = 0; // This is the uncompressed data in the raw color format in the original input PNGs
|
||||||
|
|
||||||
|
double total_dec_time = 0;
|
||||||
|
size_t total_png_in_size = 0;
|
||||||
|
size_t total_raw_in_size = 0; // This is the uncompressed data in the raw color format in the input PNGs given to the decoder (not same as orig when using the encoded ones)
|
||||||
|
size_t total_raw_dec_size = 0; // This is the uncompressed data in the raw color format of raw image buffers output by the decoder
|
||||||
|
|
||||||
|
double total_enc_time = 0;
|
||||||
|
size_t total_raw_enc_size = 0; // This is the uncompressed data in the raw color format of the raw images given to the encoder
|
||||||
|
size_t total_png_out_size = 0;
|
||||||
|
size_t total_raw_out_size = 0; // This is the uncompressed data in the raw color format of the encoded PNGs
|
||||||
|
|
||||||
|
bool verbose = false;
|
||||||
|
bool do_decode = false;
|
||||||
|
bool do_encode = false;
|
||||||
|
bool decode_encoded = false; // do the decoding benchmark on the encoded images rather than the original inputs
|
||||||
|
|
||||||
|
std::string dumpdir;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
double getTime() {
|
||||||
|
return SDL_GetTicks() / 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
void assertEquals(const T& expected, const U& actual, const std::string& message = "") {
|
||||||
|
if(expected != (T)actual) {
|
||||||
|
std::cout << "Error: Not equal! Expected " << expected << " got " << actual << "." << std::endl;
|
||||||
|
std::cout << "Message: " << message << std::endl;
|
||||||
|
std::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void assertTrue(bool value, const std::string& message = "") {
|
||||||
|
if(!value) {
|
||||||
|
std::cout << "Error: expected true." << std::endl;
|
||||||
|
std::cout << "Message: " << message << std::endl;
|
||||||
|
std::exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Test image data
|
||||||
|
struct Image {
|
||||||
|
std::vector<unsigned char> data;
|
||||||
|
unsigned width;
|
||||||
|
unsigned height;
|
||||||
|
LodePNGColorType colorType;
|
||||||
|
unsigned bitDepth;
|
||||||
|
std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Utility for debug messages
|
||||||
|
template<typename T>
|
||||||
|
std::string valtostr(const T& val) {
|
||||||
|
std::ostringstream sstream;
|
||||||
|
sstream << val;
|
||||||
|
return sstream.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void printValue(const std::string& name, const T& value, const std::string& unit = "") {
|
||||||
|
std::cout << name << ": " << value << unit << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename U>
|
||||||
|
void printValue(const std::string& name, const T& value, const std::string& s2, const U& value2, const std::string& unit = "") {
|
||||||
|
std::cout << name << ": " << value << s2 << value2 << unit << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Test LodePNG encoding and decoding the encoded result, using the C interface
|
||||||
|
std::vector<unsigned char> testEncode(Image& image) {
|
||||||
|
unsigned char* encoded = 0;
|
||||||
|
size_t encoded_size = 0;
|
||||||
|
lodepng::State state;
|
||||||
|
state.info_raw.colortype = image.colorType;
|
||||||
|
state.info_raw.bitdepth = image.bitDepth;
|
||||||
|
|
||||||
|
// Try custom compression settings
|
||||||
|
if(apply_mods) {
|
||||||
|
//state.encoder.filter_strategy = LFS_ZERO;
|
||||||
|
state.encoder.filter_strategy = LFS_ENTROPY;
|
||||||
|
//state.encoder.zlibsettings.btype = 0;
|
||||||
|
//state.encoder.zlibsettings.btype = 1;
|
||||||
|
//state.encoder.auto_convert = 0;
|
||||||
|
//state.encoder.zlibsettings.use_lz77 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double t_enc0 = getTime();
|
||||||
|
|
||||||
|
unsigned error_enc = lodepng_encode(&encoded, &encoded_size, &image.data[0],
|
||||||
|
image.width, image.height, &state);
|
||||||
|
|
||||||
|
double t_enc1 = getTime();
|
||||||
|
|
||||||
|
assertEquals(0, error_enc, "encoder error");
|
||||||
|
|
||||||
|
total_raw_enc_size += lodepng_get_raw_size(image.width, image.height, &state.info_raw);
|
||||||
|
total_png_out_size += encoded_size;
|
||||||
|
total_enc_time += (t_enc1 - t_enc0);
|
||||||
|
|
||||||
|
if(verbose) {
|
||||||
|
printValue("encoding time", t_enc1 - t_enc0, "s");
|
||||||
|
std::cout << "compression: " << ((double)(encoded_size) / (double)(image.data.size())) * 100 << "%"
|
||||||
|
<< ", ratio: " << ((double)(image.data.size()) / (double)(encoded_size))
|
||||||
|
<< ", size: " << encoded_size
|
||||||
|
<< ", bpp: " << (8.0 * encoded_size / image.width / image.height) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!dumpdir.empty()) {
|
||||||
|
std::string dumpname = dumpdir;
|
||||||
|
if(dumpname[dumpname.size() - 1] != '/') dumpname += "/";
|
||||||
|
dumpname += image.name;
|
||||||
|
if(lodepng_save_file(encoded, encoded_size, dumpname.c_str())) {
|
||||||
|
std::cout << "WARNING: failed to dump " << dumpname << ". The dir must already exist." << std::endl;
|
||||||
|
} else if(verbose) {
|
||||||
|
std::cout << "saved to: " << dumpname << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// output image stats
|
||||||
|
{
|
||||||
|
lodepng::State inspect;
|
||||||
|
unsigned w, h;
|
||||||
|
lodepng_inspect(&w, &h, &inspect, encoded, encoded_size);
|
||||||
|
total_raw_out_size += lodepng_get_raw_size(w, h, &inspect.info_png.color);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> result(encoded, encoded + encoded_size);
|
||||||
|
free(encoded);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void testDecode(const std::vector<unsigned char>& png) {
|
||||||
|
lodepng::State state;
|
||||||
|
unsigned char* decoded = 0;
|
||||||
|
unsigned w, h;
|
||||||
|
|
||||||
|
// Try custom decompression settings
|
||||||
|
if(apply_mods) {
|
||||||
|
state.decoder.color_convert = 0;
|
||||||
|
//state.decoder.ignore_crc = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
double t_dec0 = getTime();
|
||||||
|
for(int i = 0; i < NUM_DECODE; i++) {
|
||||||
|
unsigned error_dec = lodepng_decode(&decoded, &w, &h, &state, png.data(), png.size());
|
||||||
|
assertEquals(0, error_dec, "decoder error");
|
||||||
|
}
|
||||||
|
double t_dec1 = getTime();
|
||||||
|
|
||||||
|
total_dec_time += (t_dec1 - t_dec0);
|
||||||
|
|
||||||
|
total_raw_dec_size += lodepng_get_raw_size(w, h, &state.info_raw);
|
||||||
|
|
||||||
|
if(verbose) {
|
||||||
|
printValue("decoding time", t_dec1 - t_dec0, "/", NUM_DECODE, " s");
|
||||||
|
}
|
||||||
|
free(decoded);
|
||||||
|
|
||||||
|
// input image stats
|
||||||
|
{
|
||||||
|
lodepng::State inspect;
|
||||||
|
unsigned w, h;
|
||||||
|
lodepng_inspect(&w, &h, &inspect, png.data(), png.size());
|
||||||
|
total_raw_in_size += lodepng_get_raw_size(w, h, &inspect.info_png.color);
|
||||||
|
total_png_in_size += png.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getFilePart(const std::string& path) {
|
||||||
|
if(path.empty()) return "";
|
||||||
|
int slash = path.size() - 1;
|
||||||
|
while(slash >= 0 && path[slash] != '/') slash--;
|
||||||
|
return path.substr(slash + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void testFile(const std::string& filename) {
|
||||||
|
if(verbose) std::cout << "file " << filename << std::endl;
|
||||||
|
|
||||||
|
std::vector<unsigned char> png;
|
||||||
|
if(lodepng::load_file(png, filename)) {
|
||||||
|
std::cout << "\nfailed to load file " << filename << std::endl << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// input image stats
|
||||||
|
{
|
||||||
|
lodepng::State inspect;
|
||||||
|
unsigned w, h;
|
||||||
|
lodepng_inspect(&w, &h, &inspect, png.data(), png.size());
|
||||||
|
total_pixels += (w * h);
|
||||||
|
total_png_orig_size += png.size();
|
||||||
|
size_t raw_size = lodepng_get_raw_size(w, h, &inspect.info_png.color);
|
||||||
|
total_raw_orig_size += raw_size;
|
||||||
|
if(verbose) std::cout << "orig compressed size: " << png.size() << ", pixels: " << (w * h) << ", raw size: " << raw_size << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(do_encode) {
|
||||||
|
Image image;
|
||||||
|
image.name = getFilePart(filename);
|
||||||
|
image.colorType = LCT_RGBA;
|
||||||
|
image.bitDepth = 8;
|
||||||
|
assertEquals(0, lodepng::decode(image.data, image.width, image.height, filename, image.colorType, image.bitDepth));
|
||||||
|
|
||||||
|
std::vector<unsigned char> temp = testEncode(image);
|
||||||
|
if(decode_encoded) png = temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(do_decode) {
|
||||||
|
testDecode(png);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(verbose) std::cout << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void showHelp(int argc, char *argv[]) {
|
||||||
|
(void)argc;
|
||||||
|
std::cout << "Usage: " << argv[0] << " png_filenames... [OPTIONS...] [--dumpdir directory]" << std::endl;
|
||||||
|
std::cout << "Options:" << std::endl;
|
||||||
|
std::cout << " -h: show this help" << std::endl;
|
||||||
|
std::cout << " -v: verbose" << std::endl;
|
||||||
|
std::cout << " -d: decode only" << std::endl;
|
||||||
|
std::cout << " -e: encode only" << std::endl;
|
||||||
|
std::cout << " -o: decode on original images rather than encoded ones (always true if -d without -e)" << std::endl;
|
||||||
|
std::cout << " -m: apply modifications to encoder and decoder settings, the modification itself must be implemented or changed in the benchmark source code (search for apply_mods in the code, for encode and for decode)" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
verbose = false;
|
||||||
|
do_decode = true;
|
||||||
|
do_encode = true;
|
||||||
|
decode_encoded = true;
|
||||||
|
|
||||||
|
std::vector<std::string> files;
|
||||||
|
|
||||||
|
for(int i = 1; i < argc; i++) {
|
||||||
|
std::string arg = argv[i];
|
||||||
|
if(arg == "-v") verbose = true;
|
||||||
|
else if(arg == "-h" || arg == "--help") { showHelp(argc, argv); return 0; }
|
||||||
|
else if(arg == "-d") do_decode ? (do_encode = false) : (do_decode = true);
|
||||||
|
else if(arg == "-e") do_encode ? (do_decode = false) : (do_encode = true);
|
||||||
|
else if(arg == "-o") decode_encoded = false;
|
||||||
|
else if(arg == "-m") apply_mods = true;
|
||||||
|
else if(arg == "--dumpdir" && i + 1 < argc) {
|
||||||
|
dumpdir = argv[++i];
|
||||||
|
}
|
||||||
|
else files.push_back(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!do_encode) decode_encoded = false;
|
||||||
|
|
||||||
|
if(files.empty()) {
|
||||||
|
std::cout << "must give .png filenames to benchamrk" << std::endl;
|
||||||
|
showHelp(argc, argv);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for(size_t i = 0; i < files.size(); i++) {
|
||||||
|
testFile(files[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// test images stats
|
||||||
|
if(verbose) {
|
||||||
|
std::cout << "Final Summary: " << std::endl;
|
||||||
|
std::cout << "input images: " << files.size() << std::endl;
|
||||||
|
std::cout << "total_pixels: " << total_pixels << std::endl;
|
||||||
|
// file size of original PNGs that were given as command line arguments to the tool
|
||||||
|
std::cout << "total_png_orig_size: " << total_png_orig_size << " (" << (8.0 * total_png_orig_size / total_pixels) << " bpp)" << std::endl;
|
||||||
|
// size of the data inside the original PNGs, dependent on color encoding (bit depth used in the PNG)
|
||||||
|
std::cout << "total_raw_orig_size: " << total_raw_orig_size << " (" << (8.0 * total_raw_orig_size / total_pixels) << " bpp)" << std::endl;
|
||||||
|
// size of the pixel data given to the benchmark encoder, dependent on color encoding (bit depth used in the image representation in the benchmark tool, probably 32 bits)
|
||||||
|
if(do_encode) std::cout << "total_raw_enc_size: " << total_raw_enc_size << " (" << (8.0 * total_raw_enc_size / total_pixels) << " bpp)" << std::endl;
|
||||||
|
// file size of PNGs created by the benchmark encoder
|
||||||
|
if(do_encode) std::cout << "total_png_out_size: " << total_png_out_size << " (" << (8.0 * total_png_out_size / total_pixels) << " bpp)" << std::endl;
|
||||||
|
// size of the data inside the PNGs created by the benchmark encoder, dependent on color encoding (bit depth used in the PNG), may differ from total_raw_orig_size since the encoder may choose to use a different color encoding
|
||||||
|
if(do_encode) std::cout << "total_raw_out_size: " << total_raw_out_size << " (" << (8.0 * total_raw_out_size / total_pixels) << " bpp)" << std::endl;
|
||||||
|
// size of file size of the PNGs given to the benchmark decoder, this could either be the original ones or the ones encoded by the benchmark encoder depending on user options
|
||||||
|
if(do_decode) std::cout << "total_png_in_size: " << total_png_in_size << " (" << (8.0 * total_png_in_size / total_pixels) << " bpp)" << std::endl;
|
||||||
|
// size of the data inside the PNGs mentioned at total_png_in_size, dependent on color encoding (bit depth used in the image representation in the benchmark tool, probably 32 bits)
|
||||||
|
if(do_decode) std::cout << "total_raw_in_size: " << total_raw_in_size << " (" << (8.0 * total_raw_in_size / total_pixels) << " bpp)" << std::endl;
|
||||||
|
// size of the pixel data requested from the benchmark decoder, dependent on color encoding requested (bit depth used in the image representation in the benchmark tool, probably 32 bits)
|
||||||
|
if(do_decode) std::cout << "total_raw_dec_size: " << total_raw_dec_size << " (" << (8.0 * total_raw_dec_size / total_pixels) << " bpp)" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// final encoding stats
|
||||||
|
if(do_encode) {
|
||||||
|
std::cout << "encoding time: " << total_enc_time << "s on " << total_pixels << " pixels and " << total_raw_out_size << " raw bytes ("
|
||||||
|
<< ((total_raw_enc_size/1024.0/1024.0)/(total_enc_time)) << " MB/s, " << ((total_pixels/1024.0/1024.0)/(total_enc_time)) << " MP/s)" << std::endl;
|
||||||
|
std::cout << "encoded size: " << total_png_out_size << " (" << (100.0 * total_png_out_size / total_raw_out_size) << "%), bpp: "
|
||||||
|
<< (8.0 * total_png_out_size / total_pixels) << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// final decoding stats
|
||||||
|
if(do_decode) {
|
||||||
|
if(verbose) std::cout << "decoding iterations: " << NUM_DECODE << std::endl;
|
||||||
|
std::cout << "decoding time: " << total_dec_time/NUM_DECODE << "s on " << total_pixels << " pixels and " << total_png_in_size
|
||||||
|
<< " compressed bytes (" << ((total_raw_in_size/1024.0/1024.0)/(total_dec_time/NUM_DECODE)) << " MB/s, "
|
||||||
|
<< ((total_pixels/1024.0/1024.0)/(total_dec_time/NUM_DECODE)) << " MP/s)" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
LodePNG Fuzzer
|
||||||
|
|
||||||
|
Copyright (c) 2005-2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// clang++ -fsanitize=fuzzer lodepng.cpp lodepng_fuzzer.cpp -O3 && ./a.out
|
||||||
|
|
||||||
|
#include "lodepng.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
// Amount of valid colortype/bidthdepth combinations in the PNG file format.
|
||||||
|
const size_t num_combinations = 15;
|
||||||
|
|
||||||
|
LodePNGColorType colortypes[num_combinations] = {
|
||||||
|
LCT_GREY, LCT_GREY, LCT_GREY, LCT_GREY, LCT_GREY, // 1, 2, 4, 8 or 16 bits
|
||||||
|
LCT_RGB, LCT_RGB, // 8 or 16 bits
|
||||||
|
LCT_PALETTE, LCT_PALETTE, LCT_PALETTE, LCT_PALETTE, // 1, 2, 4 or 8 bits
|
||||||
|
LCT_GREY_ALPHA, LCT_GREY_ALPHA, // 8 or 16 bits
|
||||||
|
LCT_RGBA, LCT_RGBA, // 8 or 16 bits
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned bitdepths[num_combinations] = {
|
||||||
|
1, 2, 4, 8, 16, // gray
|
||||||
|
8, 16, // rgb
|
||||||
|
1, 2, 4, 8, // palette
|
||||||
|
8, 16, // gray+alpha
|
||||||
|
8, 16, // rgb+alpha
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned testDecode(lodepng::State& state, const uint8_t* data, size_t size) {
|
||||||
|
unsigned w, h;
|
||||||
|
std::vector<unsigned char> image;
|
||||||
|
return lodepng::decode(image, w, h, state, (const unsigned char*)data, size);
|
||||||
|
}
|
||||||
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
|
||||||
|
if(size == 0) return 0;
|
||||||
|
|
||||||
|
// Setting last byte of input as random_color_type
|
||||||
|
// Fuzzer will still be able to mutate the data accordingly as
|
||||||
|
// last byte of png file can be changed and file will still remain valid.
|
||||||
|
size_t random_color_type = data[size-1] % num_combinations;
|
||||||
|
|
||||||
|
lodepng::State state;
|
||||||
|
|
||||||
|
// Make the decoder ignore three types of checksums the PNG/zlib format have
|
||||||
|
// built-in, because they are less likely to be correct in the random input
|
||||||
|
// data, and if invalid make the decoder return an error before much gets ran.
|
||||||
|
state.decoder.zlibsettings.ignore_adler32 = 1;
|
||||||
|
state.decoder.zlibsettings.ignore_nlen = 1;
|
||||||
|
state.decoder.ignore_crc = 1;
|
||||||
|
// Also make decoder attempt to support partial files with missing ending to
|
||||||
|
// go further with parsing.
|
||||||
|
state.decoder.ignore_end = 1;
|
||||||
|
|
||||||
|
// First test without color conversion (keep color type of the PNG)
|
||||||
|
state.decoder.color_convert = 0;
|
||||||
|
|
||||||
|
unsigned error = testDecode(state, data, size);
|
||||||
|
|
||||||
|
// If valid PNG found, try decoding with color conversion to the most common
|
||||||
|
// default color type, and to the randomly chosen type.
|
||||||
|
if(error == 0) {
|
||||||
|
state.decoder.color_convert = 1;
|
||||||
|
testDecode(state, data, size);
|
||||||
|
|
||||||
|
state.info_raw.colortype = colortypes[random_color_type];
|
||||||
|
state.info_raw.bitdepth = bitdepths[random_color_type];
|
||||||
|
testDecode(state, data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
3716
oss-internship-2020/sapi_lodepng/lodepng-master/lodepng_unittest.cpp
Normal file
3716
oss-internship-2020/sapi_lodepng/lodepng-master/lodepng_unittest.cpp
Normal file
File diff suppressed because one or more lines are too long
1765
oss-internship-2020/sapi_lodepng/lodepng-master/lodepng_util.cpp
Normal file
1765
oss-internship-2020/sapi_lodepng/lodepng-master/lodepng_util.cpp
Normal file
File diff suppressed because it is too large
Load Diff
290
oss-internship-2020/sapi_lodepng/lodepng-master/lodepng_util.h
Normal file
290
oss-internship-2020/sapi_lodepng/lodepng-master/lodepng_util.h
Normal file
|
@ -0,0 +1,290 @@
|
||||||
|
/*
|
||||||
|
LodePNG Utils
|
||||||
|
|
||||||
|
Copyright (c) 2005-2020 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Extra C++ utilities for LodePNG, for convenience.
|
||||||
|
Not part of the stable API of lodepng, more loose separate utils.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LODEPNG_UTIL_H
|
||||||
|
#define LODEPNG_UTIL_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include "lodepng.h"
|
||||||
|
|
||||||
|
namespace lodepng {
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns info from the header of the PNG by value, purely for convenience.
|
||||||
|
Does NOT check for errors. Returns bogus info if the PNG has an error.
|
||||||
|
Does not require cleanup of allocated memory because no palette or text chunk
|
||||||
|
info is in the LodePNGInfo object after checking only the header of the PNG.
|
||||||
|
*/
|
||||||
|
LodePNGInfo getPNGHeaderInfo(const std::vector<unsigned char>& png);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get the names and sizes of all chunks in the PNG file.
|
||||||
|
Returns 0 if ok, non-0 if error happened.
|
||||||
|
*/
|
||||||
|
unsigned getChunkInfo(std::vector<std::string>& names, std::vector<size_t>& sizes,
|
||||||
|
const std::vector<unsigned char>& png);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns the names and full chunks (including the name and everything else that
|
||||||
|
makes up the chunk) for all chunks except IHDR, PLTE, IDAT and IEND.
|
||||||
|
It separates the chunks into 3 separate lists, representing the chunks between
|
||||||
|
certain critical chunks: 0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND
|
||||||
|
Returns 0 if ok, non-0 if error happened.
|
||||||
|
*/
|
||||||
|
unsigned getChunks(std::vector<std::string> names[3],
|
||||||
|
std::vector<std::vector<unsigned char> > chunks[3],
|
||||||
|
const std::vector<unsigned char>& png);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Inserts chunks into the given png file. The chunks must be fully encoded,
|
||||||
|
including length, type, content and CRC.
|
||||||
|
The array index determines where it goes:
|
||||||
|
0: between IHDR and PLTE, 1: between PLTE and IDAT, 2: between IDAT and IEND.
|
||||||
|
They're appended at the end of those locations within the PNG.
|
||||||
|
Returns 0 if ok, non-0 if error happened.
|
||||||
|
*/
|
||||||
|
unsigned insertChunks(std::vector<unsigned char>& png,
|
||||||
|
const std::vector<std::vector<unsigned char> > chunks[3]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get the filtertypes of each scanline in this PNG file.
|
||||||
|
Returns 0 if ok, 1 if PNG decoding error happened.
|
||||||
|
|
||||||
|
For a non-interlaced PNG, it returns one filtertype per scanline, in order.
|
||||||
|
|
||||||
|
For interlaced PNGs, it returns a result as if it's not interlaced. It returns
|
||||||
|
one filtertype per scanline, in order. The values match pass 6 and 7 of the
|
||||||
|
Adam7 interlacing, alternating between the two, so that the values correspond
|
||||||
|
the most to their scanlines.
|
||||||
|
*/
|
||||||
|
unsigned getFilterTypes(std::vector<unsigned char>& filterTypes, const std::vector<unsigned char>& png);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get the filtertypes of each scanline in every interlace pass this PNG file.
|
||||||
|
Returns 0 if ok, 1 if PNG decoding error happened.
|
||||||
|
|
||||||
|
For a non-interlaced PNG, it returns one filtertype per scanline, in order, in
|
||||||
|
a single std::vector in filterTypes.
|
||||||
|
|
||||||
|
For an interlaced PNG, it returns 7 std::vectors in filterTypes, one for each
|
||||||
|
Adam7 pass. The amount of values per pass can be calculated as follows, where
|
||||||
|
w and h are the size of the image and all divisions are integer divisions:
|
||||||
|
pass 1: (h + 7) / 8
|
||||||
|
pass 2: w <= 4 ? 0 : (h + 7) / 8
|
||||||
|
pass 3: h <= 4 ? 0 : (h + 7) / 8
|
||||||
|
pass 4: w <= 2 ? 0 : (h + 3) / 4
|
||||||
|
pass 5: h <= 2 ? 0 : (h + 3) / 4
|
||||||
|
pass 6: w <= 1 ? 0 : (h + 1) / 2
|
||||||
|
pass 7: h <= 1 ? 0 : (h + 1) / 2
|
||||||
|
*/
|
||||||
|
unsigned getFilterTypesInterlaced(std::vector<std::vector<unsigned char> >& filterTypes,
|
||||||
|
const std::vector<unsigned char>& png);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Returns the value of the i-th pixel in an image with 1, 2, 4 or 8-bit color.
|
||||||
|
E.g. if bits is 4 and i is 5, it returns the 5th nibble (4-bit group), which
|
||||||
|
is the second half of the 3th byte, in big endian (PNG's endian order).
|
||||||
|
*/
|
||||||
|
int getPaletteValue(const unsigned char* data, size_t i, int bits);
|
||||||
|
|
||||||
|
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||||
|
|
||||||
|
/* Similar to convertRGBModel, but the 'to' model is sRGB. The pixel format
|
||||||
|
of in and out must be the same and is given by state_in->info_raw. An
|
||||||
|
error may occur if the pixel format cannot contain the new colors (e.g. palette) */
|
||||||
|
unsigned convertToSrgb(unsigned char* out, const unsigned char* in,
|
||||||
|
unsigned w, unsigned h,
|
||||||
|
const LodePNGState* state_in);
|
||||||
|
|
||||||
|
/* Similar to convertRGBModel, but the 'from' model is sRGB. The pixel format
|
||||||
|
of in and out must be the same and is given by state_out->info_raw. An
|
||||||
|
error may occur if the pixel format cannot contain the new colors (e.g. palette) */
|
||||||
|
unsigned convertFromSrgb(unsigned char* out, const unsigned char* in,
|
||||||
|
unsigned w, unsigned h,
|
||||||
|
const LodePNGState* state_out);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Converts from one RGB model to another RGB model.
|
||||||
|
Similar to calling convertToXYZ followed by convertFromXYZ, but may be
|
||||||
|
more efficient and more precise (e.g. no computation needed when both models
|
||||||
|
are the same). See their documentation for more info.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
*) out: output pixel data
|
||||||
|
*) in: input pixel data
|
||||||
|
*) w, h: image size
|
||||||
|
*) state_out: output RGB color model in state_out->info_png and byte format in state_out->info_raw.
|
||||||
|
*) state_in: output RGB color model in state_in->info_png and byte format in state_in->info_raw
|
||||||
|
*) return value: 0 if ok, positive value if error
|
||||||
|
*) rendering_intent: 1 for relative, 3 for absolute, should be relative for standard behavior.
|
||||||
|
See description at convertFromXYZ.
|
||||||
|
*/
|
||||||
|
unsigned convertRGBModel(unsigned char* out, const unsigned char* in,
|
||||||
|
unsigned w, unsigned h,
|
||||||
|
const LodePNGState* state_out,
|
||||||
|
const LodePNGState* state_in,
|
||||||
|
unsigned rendering_intent);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Converts the RGB color to the absolute XYZ color space given the RGB color profile
|
||||||
|
chunks in the PNG info.
|
||||||
|
|
||||||
|
Color space here refers to the different possible RGB spaces with different
|
||||||
|
possible chromaticities or whitepoint and XYZ color from colorimetry, not the
|
||||||
|
LodePNGColorType that describes the byte based encoding.
|
||||||
|
|
||||||
|
You need this function only if the PNG could contain data in an arbitrary RGB
|
||||||
|
color space and you wish to output to a display or format that does not provide
|
||||||
|
color management for you (so you need to convert rather than pass on the profile
|
||||||
|
to it) but expects a certain RGB format (e.g. sRGB). See the background info below.
|
||||||
|
|
||||||
|
Supports the gAMA, cHRM, sRGB and iCCP colorimetry chunks. If no colometry chunks are present
|
||||||
|
(that is, in state->info_png, the fields gama_defined, chrm_defined, srgb_defined and
|
||||||
|
iccp_defined are all 0), it assumes the format is sRGB.
|
||||||
|
For more information, see the chunk specifications in the PNG specification.
|
||||||
|
|
||||||
|
Some background:
|
||||||
|
|
||||||
|
A PNG image contains RGB data inside, but this data may use a specific RGB model (by default sRGB but
|
||||||
|
different if colorimetry chunks are given).
|
||||||
|
The computer display and/or operating system can have another RGB model (typically sRGB, or wider gamut
|
||||||
|
or HDR formats).
|
||||||
|
|
||||||
|
The PNG chunks describe what format the data inside has, not the format of the display. To correctly
|
||||||
|
display a PNG image on a display, a conversion is needed from the PNG model to the display model if their
|
||||||
|
models differ. Some options to achieve that are:
|
||||||
|
*) If your use case already supports color management on its own, you can give it the RGB values straight from
|
||||||
|
the PNG image and give it the information from the cHRM, gAMA, sRGB and iCCP chunks (which you can find
|
||||||
|
in the LodePNGInfo), and the color management should then handle it correctly for you. You don't need
|
||||||
|
this function here in that case.
|
||||||
|
*) If your use case does not support color management, you may instead want to give it the RGB values in a
|
||||||
|
consistent color model, such as sRGB, but the PNG does not necessarily have it in this desired model.
|
||||||
|
In that case, use the function below (or a similar one from a CMS library if you prefer) to convert it to
|
||||||
|
the absolute color space XYZ, and then you can convert it to the target RGB with the counterpart convertFromXYZ
|
||||||
|
further below.
|
||||||
|
|
||||||
|
Parameters:
|
||||||
|
|
||||||
|
*) out: 4 floats per pixel, X,Y,Z,alpha color format, in range 0-1 (normally, not clipped if beyond), must
|
||||||
|
be allocated to have 4 * w * h floats available.
|
||||||
|
*) whitepoint: output argument, the whitepoint the original RGB data used, given in absolute XYZ. Needed for
|
||||||
|
relative rendering intents: give these values to counterpart function convertFromXYZ.
|
||||||
|
*) in: input RGB color, in byte format given by state->info_raw and RGB color profile given by info->info_png
|
||||||
|
*) w, h: image size
|
||||||
|
*) state (when using a LodePNG decode function that takes a LodePNGState parameter, can directly use that one):
|
||||||
|
state->info_png: PNG info with possibly an RGB color model in cHRM,gAMA and/or sRGB chunks
|
||||||
|
state->info_raw: byte format of in (amount of channels, bit depth)
|
||||||
|
*) return value: 0 if ok, positive value if error
|
||||||
|
*/
|
||||||
|
unsigned convertToXYZ(float* out, float whitepoint[3],
|
||||||
|
const unsigned char* in, unsigned w, unsigned h,
|
||||||
|
const LodePNGState* state);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Same as convertToXYZ but takes floating point input. Slower.
|
||||||
|
The main black..white range in 0..1. Does not clip values that are outside that range.
|
||||||
|
*/
|
||||||
|
unsigned convertToXYZFloat(float* out, float whitepoint[3], const float* in,
|
||||||
|
unsigned w, unsigned h, const LodePNGState* state);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Converts XYZ to RGB in the RGB color model given by info and byte format by mode_out.
|
||||||
|
If info has no coloremtry chunks, converts to sRGB.
|
||||||
|
Parameters:
|
||||||
|
*) out: output color in byte format given by state->info_raw and RGB color profile given
|
||||||
|
by info->info_png. Must have enough bytes allocated to contain pixels in the given byte format.
|
||||||
|
*) in: 4 floats per pixel, X,Y,Z,alpha color format, in range 0-1 (normally).
|
||||||
|
*) whitepoint: input argument, the original whitepoint in absolute XYZ that the pixel data
|
||||||
|
in "in" had back when it was in a previous RGB space. Needed to preserve the whitepoint
|
||||||
|
in the new target RGB space for relative rendering intent.
|
||||||
|
*) rendering_intent: the desired rendering intent, with numeric meaning matching the
|
||||||
|
values used by ICC: 0=perceptual, 1=relative, 2=saturation, 3=absolute.
|
||||||
|
Should be 1 for normal use cases, it adapts white to match that of different RGB
|
||||||
|
models which is the best practice. Using 3 may change the color of white and may
|
||||||
|
turn grayscale into colors of a certain tone. Using 0 and 2 will have the same
|
||||||
|
effect as 1 because using those requires more data than the matrix-based RGB profiles
|
||||||
|
supporetd here have.
|
||||||
|
*) w, h: image size
|
||||||
|
*) state:
|
||||||
|
state->info_png: PNG info with possibly an RGB color profile in cHRM,gAMA and/or sRGB chunks
|
||||||
|
state->info_raw: byte format of out (amount of channels, bit depth)
|
||||||
|
*) return value: 0 if ok, positive value if error
|
||||||
|
*/
|
||||||
|
unsigned convertFromXYZ(unsigned char* out, const float* in, unsigned w, unsigned h,
|
||||||
|
const LodePNGState* state,
|
||||||
|
const float whitepoint[3], unsigned rendering_intent);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Same as convertFromXYZ but outputs the RGB colors in floating point.
|
||||||
|
The main black..white range in 0..1. Does not clip values that are outside that range.
|
||||||
|
*/
|
||||||
|
unsigned convertFromXYZFloat(float* out, const float* in, unsigned w, unsigned h,
|
||||||
|
const LodePNGState* state,
|
||||||
|
const float whitepoint[3], unsigned rendering_intent);
|
||||||
|
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
The information for extractZlibInfo.
|
||||||
|
*/
|
||||||
|
struct ZlibBlockInfo {
|
||||||
|
int btype; //block type (0-2)
|
||||||
|
size_t compressedbits; //size of compressed block in bits
|
||||||
|
size_t uncompressedbytes; //size of uncompressed block in bytes
|
||||||
|
|
||||||
|
// only filled in for block type 2
|
||||||
|
size_t treebits; //encoded tree size in bits
|
||||||
|
int hlit; //the HLIT value that was filled in for this tree
|
||||||
|
int hdist; //the HDIST value that was filled in for this tree
|
||||||
|
int hclen; //the HCLEN value that was filled in for this tree
|
||||||
|
std::vector<int> clcl; //19 code length code lengths (compressed tree's tree)
|
||||||
|
std::vector<int> treecodes; //N tree codes, with values 0-18. Values 17 or 18 are followed by the repetition value.
|
||||||
|
std::vector<int> litlenlengths; //288 code lengths for lit/len symbols
|
||||||
|
std::vector<int> distlengths; //32 code lengths for dist symbols
|
||||||
|
|
||||||
|
// only filled in for block types 1 or 2
|
||||||
|
std::vector<int> lz77_lcode; //LZ77 codes. 0-255: literals. 256: end symbol. 257-285: length code of length/dist pairs
|
||||||
|
// the next vectors have the same size as lz77_lcode, but an element only has meaningful value if lz77_lcode contains a length code.
|
||||||
|
std::vector<int> lz77_dcode;
|
||||||
|
std::vector<int> lz77_lbits;
|
||||||
|
std::vector<int> lz77_dbits;
|
||||||
|
std::vector<int> lz77_lvalue;
|
||||||
|
std::vector<int> lz77_dvalue;
|
||||||
|
size_t numlit; //number of lit codes in this block
|
||||||
|
size_t numlen; //number of len codes in this block
|
||||||
|
};
|
||||||
|
|
||||||
|
//Extracts all info needed from a PNG file to reconstruct the zlib compression exactly.
|
||||||
|
void extractZlibInfo(std::vector<ZlibBlockInfo>& zlibinfo, const std::vector<unsigned char>& in);
|
||||||
|
|
||||||
|
} // namespace lodepng
|
||||||
|
|
||||||
|
#endif /*LODEPNG_UTIL_H inclusion guard*/
|
1410
oss-internship-2020/sapi_lodepng/lodepng-master/pngdetail.cpp
Normal file
1410
oss-internship-2020/sapi_lodepng/lodepng-master/pngdetail.cpp
Normal file
File diff suppressed because it is too large
Load Diff
120
oss-internship-2020/sapi_lodepng/main.cc
Normal file
120
oss-internship-2020/sapi_lodepng/main.cc
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
// Copyright 2020 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "lodepng-master/lodepng.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
bool cmp_images32(const std::string &f1, const std::string &f2) {
|
||||||
|
std::cout << "COMPARING IMAGES " << basename(f1.c_str()) << " -> " << basename(f2.c_str()) << std::endl;
|
||||||
|
|
||||||
|
unsigned int error, width1, height1;
|
||||||
|
unsigned char* image1 = 0;
|
||||||
|
|
||||||
|
unsigned int width2, height2;
|
||||||
|
unsigned char* image2 = 0;
|
||||||
|
|
||||||
|
error = lodepng_decode32_file(&image1, &width1, &height1, f1.c_str());
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
std::cerr << "error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = lodepng_decode32_file(&image2, &width2, &height2, f2.c_str());
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
std::cerr << "error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width1 != width2 || height1 != height2) {
|
||||||
|
std::cerr << "DIMENSIONS DIFFER\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < width1 * height1; ++i) {
|
||||||
|
if (image1[i] != image2[i]) {
|
||||||
|
std::cerr << "PIXELS DIFFER AT i = " << i << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copies an image into another and compares them
|
||||||
|
void decode_and_encode32(const std::string &filename1, const std::string &filename2) {
|
||||||
|
|
||||||
|
unsigned int error, width, height;
|
||||||
|
unsigned char* image = 0;
|
||||||
|
|
||||||
|
error = lodepng_decode32_file(&image, &width, &height, filename1.c_str());
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
std::cerr << "error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = lodepng_encode32_file(filename2.c_str(), image, width, height);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
std::cerr << "error " << error << ": " << lodepng_error_text(error) << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test1(const std::string &images_path) {
|
||||||
|
std::cout << "test1" << std::endl;
|
||||||
|
|
||||||
|
std::string filename1 = images_path + "/test1.png";
|
||||||
|
std::string filename2 = images_path + "/out/test1_1out.png";
|
||||||
|
std::string filename3 = images_path + "/out/test1_2out.png";
|
||||||
|
|
||||||
|
|
||||||
|
decode_and_encode32(filename1, filename2);
|
||||||
|
decode_and_encode32(filename1, filename3);
|
||||||
|
|
||||||
|
if (!cmp_images32(filename1, filename2)) {
|
||||||
|
std::cout << "files are different" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "files are not different" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cmp_images32(filename3, filename2)) {
|
||||||
|
std::cout << "files are different" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "files are not different" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
std::cout << "usage: " << basename(argv[0]) << " images_folder_path"
|
||||||
|
<< std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string images_path(argv[1]);
|
||||||
|
|
||||||
|
test1(images_path);
|
||||||
|
return 0;
|
||||||
|
}
|
166
oss-internship-2020/sapi_lodepng/main_sandboxed.cc
Normal file
166
oss-internship-2020/sapi_lodepng/main_sandboxed.cc
Normal file
|
@ -0,0 +1,166 @@
|
||||||
|
// Copyright 2020 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "lodepng_sapi.sapi.h"
|
||||||
|
#include "sandbox.h"
|
||||||
|
#include "sandboxed_api/util/flag.h"
|
||||||
|
|
||||||
|
ABSL_DECLARE_FLAG(string, sandbox2_danger_danger_permit_all);
|
||||||
|
ABSL_DECLARE_FLAG(string, sandbox2_danger_danger_permit_all_and_log);
|
||||||
|
|
||||||
|
// takes a png image (f1), decodes it and ecodes it into f2.
|
||||||
|
// can be viewed as copying f1 into f2. This function has a basic usage
|
||||||
|
// of the decode and encode functions.
|
||||||
|
void decode_and_encode32(SapiLodepngSandbox &sandbox, LodepngApi &api,
|
||||||
|
const std::string &f1, const std::string &f2) {
|
||||||
|
sapi::v::UInt width(0), height(0);
|
||||||
|
sapi::v::ConstCStr filename1(f1.c_str()), filename2(f2.c_str());
|
||||||
|
|
||||||
|
// in order to pass unsigned char ** to the function, we pass a variable that
|
||||||
|
// contains the pointer.
|
||||||
|
sapi::v::IntBase<unsigned char *> image(0);
|
||||||
|
|
||||||
|
api.lodepng_decode32_file(image.PtrBoth(), width.PtrBoth(), height.PtrBoth(),
|
||||||
|
filename1.PtrBefore())
|
||||||
|
.IgnoreError();
|
||||||
|
|
||||||
|
// after the function is called, we need to access the data stored at the
|
||||||
|
// address to which the previous variable points. To do that, we have to
|
||||||
|
// transfer the data from the sandbox memory to this process's memory.
|
||||||
|
sapi::v::RemotePtr remote_out_ptr(reinterpret_cast<void *>(image.GetValue()));
|
||||||
|
sapi::v::Array<char> out_img(width.GetValue() * height.GetValue());
|
||||||
|
out_img.SetRemote(remote_out_ptr.GetValue());
|
||||||
|
sandbox.TransferFromSandboxee(&out_img).IgnoreError();
|
||||||
|
|
||||||
|
// now the pixels are available at out_img.GetData()
|
||||||
|
|
||||||
|
// when calling the encoding function, we need only an unsigned char *
|
||||||
|
// (instead of **) so we can simply use the sapi::v::Array defined before
|
||||||
|
// (PtrBefore will give us a pointer).
|
||||||
|
api.lodepng_encode32_file(filename2.PtrBefore(), out_img.PtrBefore(),
|
||||||
|
width.GetValue(), height.GetValue())
|
||||||
|
.IgnoreError();
|
||||||
|
|
||||||
|
// Since in this function we do not actually used the pixels, we could simply
|
||||||
|
// call the encode function with the pointer from before (the remote pointer,
|
||||||
|
// since the memory has already been allocated on the sandboxed process).
|
||||||
|
// However, most of the use cases of this library require accessing the pixels
|
||||||
|
// which is why the solution in which data is transferred around is used.
|
||||||
|
}
|
||||||
|
|
||||||
|
// compares the pixels of the f1 and f2 png files.
|
||||||
|
bool cmp_images32(SapiLodepngSandbox &sandbox, LodepngApi &api,
|
||||||
|
const std::string &f1, const std::string &f2) {
|
||||||
|
std::cout << "COMPARING IMAGES " << basename(f1.c_str()) << " --- "
|
||||||
|
<< basename(f2.c_str()) << std::endl;
|
||||||
|
|
||||||
|
sapi::v::UInt width1, height1, width2, height2;
|
||||||
|
sapi::v::ConstCStr filename1(f1.c_str()), filename2(f2.c_str());
|
||||||
|
sapi::v::IntBase<unsigned char *> image1_ptr(0), image2_ptr(0);
|
||||||
|
|
||||||
|
api.lodepng_decode32_file(image1_ptr.PtrBoth(), width1.PtrBoth(),
|
||||||
|
height1.PtrBoth(), filename1.PtrBefore())
|
||||||
|
.IgnoreError();
|
||||||
|
|
||||||
|
api.lodepng_decode32_file(image2_ptr.PtrBoth(), width2.PtrBoth(),
|
||||||
|
height2.PtrBoth(), filename2.PtrBefore())
|
||||||
|
.IgnoreError();
|
||||||
|
|
||||||
|
sapi::v::RemotePtr remote_out_ptr1(
|
||||||
|
reinterpret_cast<void *>(image1_ptr.GetValue()));
|
||||||
|
sapi::v::Array<char> pixels1(width1.GetValue() * height1.GetValue());
|
||||||
|
pixels1.SetRemote(remote_out_ptr1.GetValue());
|
||||||
|
sandbox.TransferFromSandboxee(&pixels1).IgnoreError();
|
||||||
|
|
||||||
|
sapi::v::RemotePtr remote_out_ptr2(
|
||||||
|
reinterpret_cast<void *>(image2_ptr.GetValue()));
|
||||||
|
sapi::v::Array<char> pixels2(width2.GetValue() * height2.GetValue());
|
||||||
|
pixels2.SetRemote(remote_out_ptr2.GetValue());
|
||||||
|
sandbox.TransferFromSandboxee(&pixels2).IgnoreError();
|
||||||
|
|
||||||
|
if (width1.GetValue() != width2.GetValue() ||
|
||||||
|
height1.GetValue() != height2.GetValue()) {
|
||||||
|
std::cerr << "DIMENSIONS DIFFER\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < width1.GetValue() * height1.GetValue(); ++i) {
|
||||||
|
if (pixels1.GetData()[i] != pixels2.GetData()[i]) {
|
||||||
|
std::cerr << "PIXELS DIFFER AT i = " << i << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this test simply copies the png from filename1 to filename2 and filename3
|
||||||
|
// and then decodes those 2 files and compares the pixels. If those pixels are
|
||||||
|
// equal, then encoding and decoding worked.
|
||||||
|
void test1(SapiLodepngSandbox &sandbox, LodepngApi &api,
|
||||||
|
const std::string &images_path) {
|
||||||
|
std::cout << "test1" << std::endl;
|
||||||
|
|
||||||
|
std::string filename1 = images_path + "/test1.png";
|
||||||
|
std::string filename2 = images_path + "/out/test1_1out.png";
|
||||||
|
std::string filename3 = images_path + "/out/test1_2out.png";
|
||||||
|
|
||||||
|
// const char *filename1 =
|
||||||
|
// "/usr/local/google/home/amedar/sapi_lodepng/test_images/test1.png"; const
|
||||||
|
// char *filename2 =
|
||||||
|
// "/usr/local/google/home/amedar/sapi_lodepng/test_images/out/test1_1out.png";
|
||||||
|
// const char *filename3 =
|
||||||
|
// "/usr/local/google/home/amedar/sapi_lodepng/test_images/out/test1_2out.png";
|
||||||
|
|
||||||
|
decode_and_encode32(sandbox, api, filename1, filename2);
|
||||||
|
decode_and_encode32(sandbox, api, filename1, filename3);
|
||||||
|
|
||||||
|
if (!cmp_images32(sandbox, api, filename1, filename2)) {
|
||||||
|
std::cout << "files are different" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "files are not different" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cmp_images32(sandbox, api, filename3, filename2)) {
|
||||||
|
std::cout << "files are different" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "files are not different" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// at the moment there are no arguments when running
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||||
|
|
||||||
|
if (argc != 2) {
|
||||||
|
std::cout << "usage: " << basename(argv[0]) << " images_folder_path"
|
||||||
|
<< std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string images_path(argv[1]);
|
||||||
|
|
||||||
|
SapiLodepngSandbox sandbox(images_path);
|
||||||
|
sandbox.Init().IgnoreError();
|
||||||
|
|
||||||
|
LodepngApi api(&sandbox);
|
||||||
|
|
||||||
|
test1(sandbox, api, images_path);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
14
oss-internship-2020/sapi_lodepng/main_unit_test.cc
Normal file
14
oss-internship-2020/sapi_lodepng/main_unit_test.cc
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "lodepng_sapi.sapi.h"
|
||||||
|
#include "sandbox.h"
|
||||||
|
#include <glog/logging.h>
|
||||||
|
#include "gmock/gmock.h"
|
||||||
|
// #include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
TEST(addition, basic) {
|
||||||
|
EXPECT_EQ(2, 1 + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
54
oss-internship-2020/sapi_lodepng/sandbox.h
Normal file
54
oss-internship-2020/sapi_lodepng/sandbox.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright 2020 Google LLC
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#ifndef SAPI_LODEPNG_SANDBOX_H_
|
||||||
|
#define SAPI_LODEPNG_SANDBOX_H_
|
||||||
|
|
||||||
|
#include "lodepng_sapi.sapi.h"
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <syscall.h>
|
||||||
|
|
||||||
|
// TODO change this with the location on your own machine
|
||||||
|
#define base_path "/usr/local/google/home/amedar/internship/sandboxed-api/oss-internship-2020/sapi_lodepng/"
|
||||||
|
|
||||||
|
class SapiLodepngSandbox : public LodepngSandbox {
|
||||||
|
public:
|
||||||
|
SapiLodepngSandbox(const std::string &images_path): images_path_(images_path) {}
|
||||||
|
|
||||||
|
std::unique_ptr<sandbox2::Policy> ModifyPolicy(
|
||||||
|
sandbox2::PolicyBuilder*) override {
|
||||||
|
return sandbox2::PolicyBuilder()
|
||||||
|
.AllowStaticStartup()
|
||||||
|
.AllowRead()
|
||||||
|
.AllowWrite()
|
||||||
|
.AllowOpen()
|
||||||
|
.AllowSystemMalloc()
|
||||||
|
.AllowExit()
|
||||||
|
.AllowStat()
|
||||||
|
// .AddFile("/usr/local/google/home/amedar/sapi_lodepng/test_images/test1.png")
|
||||||
|
.AddDirectory(images_path_, /*is_ro=*/false)
|
||||||
|
// .AddDirectory("/usr/local/google/home/amedar/sapi_lodepng/test_images/out", /*is_ro=*/false)
|
||||||
|
.AllowSyscalls({
|
||||||
|
__NR_futex,
|
||||||
|
__NR_lseek,
|
||||||
|
__NR_close,
|
||||||
|
})
|
||||||
|
.BuildOrDie();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string images_path_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SAPI_LODEPNG_SANDBOX_H_
|
BIN
oss-internship-2020/sapi_lodepng/test_images/out/test1_1out.png
Normal file
BIN
oss-internship-2020/sapi_lodepng/test_images/out/test1_1out.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 947 KiB |
BIN
oss-internship-2020/sapi_lodepng/test_images/out/test1_2out.png
Normal file
BIN
oss-internship-2020/sapi_lodepng/test_images/out/test1_2out.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 947 KiB |
BIN
oss-internship-2020/sapi_lodepng/test_images/test1.png
Normal file
BIN
oss-internship-2020/sapi_lodepng/test_images/test1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 906 KiB |
Loading…
Reference in New Issue
Block a user