Skip to content

Commit f9c7338

Browse files
authored
Update lodepng to version 20250506 (#1035)
Includes fixes in the `msc` modifications for crashes and memory leaks that occurred when handling rare cases of invalid .png files. Makes `external/lodepng` a git subrepo of the fork with the `msc` modifications instead of copying files. git subrepo clone --branch=msc_separate_chunk_decode https://github.com/KhronosGroup/lodepng.git external/lodepng subrepo: subdir: "external/lodepng" merged: "d4cc52d8c" upstream: origin: "https://github.com/KhronosGroup/lodepng.git" branch: "msc_separate_chunk_decode" commit: "d4cc52d8c" git-subrepo: version: "0.4.3" origin: "https://github.com/MarkCallow/git-subrepo.git" commit: "c1f1132"
1 parent 64a6900 commit f9c7338

28 files changed

Lines changed: 9781 additions & 80 deletions

REUSE.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,9 @@ SPDX-FileCopyrightText = "2016 The Android Open Source Project"
144144
SPDX-License-Identifier = "Apache-2.0"
145145

146146
[[annotations]]
147-
path = "external/lodepng/lodepng.**"
147+
path = "external/lodepng/**"
148148
precedence = "aggregate"
149-
SPDX-FileCopyrightText = "2005-2019 Lode Vandevenne"
149+
SPDX-FileCopyrightText = "2005-2025 Lode Vandevenne"
150150
SPDX-License-Identifier = "Zlib"
151151

152152
[[annotations]]

external/lodepng/.gitrepo

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; DO NOT EDIT (unless you know what you are doing)
2+
;
3+
; This subdirectory is a git "subrepo", and this file is maintained by the
4+
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
5+
;
6+
[subrepo]
7+
remote = https://github.com/KhronosGroup/lodepng.git
8+
branch = msc_separate_chunk_decode
9+
commit = d4cc52d8c074da137303e1117cc098a97647960c
10+
parent = 64a69009b72bee37ea75f8c4238686ea4c616e0b
11+
method = merge
12+
cmdver = 0.4.3

external/lodepng/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Copyright (c) 2005-2018 Lode Vandevenne
2+
3+
This software is provided 'as-is', without any express or implied
4+
warranty. In no event will the authors be held liable for any damages
5+
arising from the use of this software.
6+
7+
Permission is granted to anyone to use this software for any purpose,
8+
including commercial applications, and to alter it and redistribute it
9+
freely, subject to the following restrictions:
10+
11+
1. The origin of this software must not be misrepresented; you must not
12+
claim that you wrote the original software. If you use this software
13+
in a product, an acknowledgment in the product documentation would be
14+
appreciated but is not required.
15+
16+
2. Altered source versions must be plainly marked as such, and must not be
17+
misrepresented as being the original software.
18+
19+
3. This notice may not be removed or altered from any source
20+
distribution.
21+

external/lodepng/Makefile

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# This makefile only makes the unit test, benchmark and pngdetail and showpng
2+
# utilities. It does not make the PNG codec itself as shared or static library.
3+
# That is because:
4+
# LodePNG itself has only 1 source file (lodepng.cpp, can be renamed to
5+
# lodepng.c) and is intended to be included as source file in other projects and
6+
# their build system directly.
7+
8+
9+
CC ?= gcc
10+
CXX ?= g++
11+
12+
override CFLAGS := -W -Wall -Wextra -ansi -pedantic -O3 -Wno-unused-function $(CFLAGS)
13+
override CXXFLAGS := -W -Wall -Wextra -ansi -pedantic -O3 $(CXXFLAGS)
14+
15+
all: unittest benchmark pngdetail showpng
16+
17+
%.o: %.cpp
18+
@mkdir -p `dirname $@`
19+
$(CXX) -I ./ $(CXXFLAGS) -c $< -o $@
20+
21+
unittest: lodepng.o lodepng_util.o lodepng_unittest.o
22+
$(CXX) $^ $(CXXFLAGS) -o $@
23+
24+
benchmark: lodepng.o lodepng_benchmark.o
25+
$(CXX) $^ $(CXXFLAGS) -lSDL2 -o $@
26+
27+
pngdetail: lodepng.o lodepng_util.o pngdetail.o
28+
$(CXX) $^ $(CXXFLAGS) -o $@
29+
30+
showpng: lodepng.o examples/example_sdl.o
31+
$(CXX) -I ./ $^ $(CXXFLAGS) -lSDL2 -o $@
32+
33+
clean:
34+
rm -f unittest benchmark pngdetail showpng lodepng_unittest.o lodepng_benchmark.o lodepng.o lodepng_util.o pngdetail.o examples/example_sdl.o

external/lodepng/README.md

Lines changed: 68 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,75 @@
1-
<!-- Copyright 2025 Mark Callow -->
2-
<!-- SPDX-License-Identifier: Apache-2.0 -->
1+
LodePNG
2+
-------
33

4-
# LodePNG
4+
PNG encoder and decoder in C and C++, without dependencies
55

6-
Sourced from https://github.com/KhronosGroup/lodepng/tree/split_decode_inflate
7-
which is a branch in a fork of https://github.com/lvandeve/lodepng.
6+
Home page: http://lodev.org/lodepng/
87

9-
The branch in the fork has been modified to split decode and data inflation to
10-
allow it to work with our imageio library. A PR has been submitted to merge
11-
these changes upstream: https://github.com/lvandeve/lodepng/pull/206.
8+
### Documentation
129

13-
The version here has different comments than that in [KhronosGroup/lodepng](https://github.com/KhronosGroup/lodepng/tree/split_decode_inflate).
14-
The one in [KhronosGroup/lodepng](https://github.com/KhronosGroup/lodepng/tree/split_decode_inflate) has been prepared as source for the PR while this one,
15-
in compliance with the license requirements, has comments clearly indicating it has been modified, why and where. The code is identical.
10+
Detailed documentation is included in a large comment in the second half of the
11+
header file `lodepng.h`.
1612

17-
The repo is 3MB but only the 2 files here are needed and it has no tags so
18-
using `git submodule` or `git subrepo` are unattractive options.
13+
Source code examples using LodePNG can be found in the examples directory.
1914

15+
An FAQ can be found on http://lodev.org/lodepng/
2016

17+
### Building
18+
19+
Only two files are needed to encode and decode PNGs:
20+
21+
* `lodepng.cpp` (or renamed to `lodepng.c`)
22+
* `lodepng.h`
23+
24+
All other files are just source code examples, tests, misc utilities, etc...,
25+
which are normally not needed in projects using this.
26+
27+
You can include the files directly in your project's source tree and its
28+
makefile, IDE project file, or other build system. No library is necessary.
29+
30+
In addition to C++, LodePNG also supports ANSI C (C89), with all the same
31+
functionality: C++ only adds extra convenience API.
32+
33+
For C, rename `lodepng.cpp` to `lodepng.c`.
34+
35+
Consider using git submodules to include LodePNG in your project.
36+
37+
### Compiling in C++
38+
39+
If you have a hypothetical `your_program.cpp` that #includes and uses `lodepng.h`,
40+
you can build as follows:
41+
42+
`g++ your_program.cpp lodepng.cpp -Wall -Wextra -pedantic -ansi -O3`
43+
44+
or:
45+
46+
`clang++ your_program.cpp lodepng.cpp -Wall -Wextra -pedantic -ansi -O3`
47+
48+
This shows compiler flags it was designed for, but normally one would use the
49+
compiler or build system of their project instead of those commands, and other
50+
C++ compilers are supported.
51+
52+
### Compiling in C
53+
54+
Rename `lodepng.cpp` to `lodepng.c` for this.
55+
56+
If you have a hypothetical your_program.c that #includes and uses lodepng.h,
57+
you can build as follows:
58+
59+
`gcc your_program.c lodepng.c -ansi -pedantic -Wall -Wextra -O3`
60+
61+
or
62+
63+
`clang your_program.c lodepng.c -ansi -pedantic -Wall -Wextra -O3`
64+
65+
This shows compiler flags it was designed for, but normally one would use the
66+
compiler or build system of their project instead of those commands, and other
67+
C compilers are supported.
68+
69+
### Makefile
70+
71+
There is a Makefile, but this is not intended for using LodePNG itself since the
72+
way to use that one is to include its source files in your program. The Makefile
73+
only builds development and testing utilities. It can be used as follows:
74+
75+
`make -j`
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
LodePNG Examples
3+
4+
Copyright (c) 2005-2012 Lode Vandevenne
5+
6+
This software is provided 'as-is', without any express or implied
7+
warranty. In no event will the authors be held liable for any damages
8+
arising from the use of this software.
9+
10+
Permission is granted to anyone to use this software for any purpose,
11+
including commercial applications, and to alter it and redistribute it
12+
freely, subject to the following restrictions:
13+
14+
1. The origin of this software must not be misrepresented; you must not
15+
claim that you wrote the original software. If you use this software
16+
in a product, an acknowledgment in the product documentation would be
17+
appreciated but is not required.
18+
19+
2. Altered source versions must be plainly marked as such, and must not be
20+
misrepresented as being the original software.
21+
22+
3. This notice may not be removed or altered from any source
23+
distribution.
24+
*/
25+
26+
//g++ lodepng.cpp example_4bit_palette.cpp -ansi -pedantic -Wall -Wextra -O3
27+
28+
29+
30+
/*
31+
LodePNG 4-bit palette example.
32+
This example encodes a 511x511 PNG with a 4-bit palette.
33+
Both image and palette contain sine waves, resulting in a sort of plasma.
34+
The 511 (rather than power of two 512) size is of course chosen on purpose to
35+
confirm that scanlines not filling up an entire byte size are working.
36+
37+
NOTE: a PNG image with a translucent palette is perfectly valid. However there
38+
exist some programs that cannot correctly read those, including, surprisingly,
39+
Gimp 2.8 image editor (until you set mode to RGB).
40+
*/
41+
42+
#include <cmath>
43+
#include <iostream>
44+
45+
#include "lodepng.h"
46+
47+
int main(int argc, char *argv[]) {
48+
//check if user gave a filename
49+
if(argc < 2) {
50+
std::cout << "please provide a filename to save to" << std::endl;
51+
return 0;
52+
}
53+
54+
//create encoder and set settings and info (optional)
55+
lodepng::State state;
56+
57+
//generate palette
58+
for(int i = 0; i < 16; i++) {
59+
unsigned char r = 127 * (1 + std::sin(5 * i * 6.28318531 / 16));
60+
unsigned char g = 127 * (1 + std::sin(2 * i * 6.28318531 / 16));
61+
unsigned char b = 127 * (1 + std::sin(3 * i * 6.28318531 / 16));
62+
unsigned char a = 63 * (1 + std::sin(8 * i * 6.28318531 / 16)) + 128; /*alpha channel of the palette (tRNS chunk)*/
63+
64+
//palette must be added both to input and output color mode, because in this
65+
//sample both the raw image and the expected PNG image use that palette.
66+
lodepng_palette_add(&state.info_png.color, r, g, b, a);
67+
lodepng_palette_add(&state.info_raw, r, g, b, a);
68+
}
69+
70+
//both the raw image and the encoded image must get colorType 3 (palette)
71+
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.
72+
state.info_png.color.bitdepth = 4;
73+
state.info_raw.colortype = LCT_PALETTE;
74+
state.info_raw.bitdepth = 4;
75+
state.encoder.auto_convert = 0; //we specify ourselves exactly what output PNG color mode we want
76+
77+
//generate some image
78+
const unsigned w = 511;
79+
const unsigned h = 511;
80+
std::vector<unsigned char> image;
81+
image.resize((w * h * 4 + 7) / 8, 0);
82+
for(unsigned y = 0; y < h; y++)
83+
for(unsigned x = 0; x < w; x++) {
84+
size_t byte_index = (y * w + x) / 2;
85+
bool byte_half = (y * w + x) % 2 == 1;
86+
87+
int color = (int)(4 * ((1 + std::sin(2.0 * 6.28318531 * x / (double)w))
88+
+ (1 + std::sin(2.0 * 6.28318531 * y / (double)h))) );
89+
90+
image[byte_index] |= (unsigned char)(color << (byte_half ? 0 : 4));
91+
}
92+
93+
//encode and save
94+
std::vector<unsigned char> buffer;
95+
unsigned error = lodepng::encode(buffer, image.empty() ? 0 : &image[0], w, h, state);
96+
if(error) {
97+
std::cout << "encoder error " << error << ": "<< lodepng_error_text(error) << std::endl;
98+
return 0;
99+
}
100+
lodepng::save_file(buffer, argv[1]);
101+
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
LodePNG Examples
3+
4+
Copyright (c) 2005-2010 Lode Vandevenne
5+
6+
This software is provided 'as-is', without any express or implied
7+
warranty. In no event will the authors be held liable for any damages
8+
arising from the use of this software.
9+
10+
Permission is granted to anyone to use this software for any purpose,
11+
including commercial applications, and to alter it and redistribute it
12+
freely, subject to the following restrictions:
13+
14+
1. The origin of this software must not be misrepresented; you must not
15+
claim that you wrote the original software. If you use this software
16+
in a product, an acknowledgment in the product documentation would be
17+
appreciated but is not required.
18+
19+
2. Altered source versions must be plainly marked as such, and must not be
20+
misrepresented as being the original software.
21+
22+
3. This notice may not be removed or altered from any source
23+
distribution.
24+
*/
25+
26+
/*
27+
Load a BMP image and convert it to a PNG image. This example also shows how
28+
to use other data with the same memory structure as BMP, such as the image
29+
format native to win32, GDI (HBITMAP, BITMAPINFO, ...) often encountered if
30+
you're programming for Windows in Visual Studio.
31+
32+
This example only supports uncompressed 24-bit RGB or 32-bit RGBA bitmaps.
33+
For other types of BMP's, use a full fledged BMP decoder, or convert the
34+
bitmap to 24-bit or 32-bit format.
35+
36+
NOTE: it overwrites the output file without warning if it exists!
37+
*/
38+
39+
//g++ lodepng.cpp example_bmp2png.cpp -ansi -pedantic -Wall -Wextra -O3
40+
41+
#include "lodepng.h"
42+
43+
#include <iostream>
44+
45+
//returns 0 if all went ok, non-0 if error
46+
//output image is always given in RGBA (with alpha channel), even if it's a BMP without alpha channel
47+
unsigned decodeBMP(std::vector<unsigned char>& image, unsigned& w, unsigned& h, const std::vector<unsigned char>& bmp) {
48+
static const unsigned MINHEADER = 54; //minimum BMP header size
49+
50+
if(bmp.size() < MINHEADER) return -1;
51+
if(bmp[0] != 'B' || bmp[1] != 'M') return 1; //It's not a BMP file if it doesn't start with marker 'BM'
52+
unsigned pixeloffset = bmp[10] + 256 * bmp[11]; //where the pixel data starts
53+
//read width and height from BMP header
54+
w = bmp[18] + bmp[19] * 256;
55+
h = bmp[22] + bmp[23] * 256;
56+
//read number of channels from BMP header
57+
if(bmp[28] != 24 && bmp[28] != 32) return 2; //only 24-bit and 32-bit BMPs are supported.
58+
unsigned numChannels = bmp[28] / 8;
59+
60+
//The amount of scanline bytes is width of image times channels, with extra bytes added if needed
61+
//to make it a multiple of 4 bytes.
62+
unsigned scanlineBytes = w * numChannels;
63+
if(scanlineBytes % 4 != 0) scanlineBytes = (scanlineBytes / 4) * 4 + 4;
64+
65+
unsigned dataSize = scanlineBytes * h;
66+
if(bmp.size() < dataSize + pixeloffset) return 3; //BMP file too small to contain all pixels
67+
68+
image.resize(w * h * 4);
69+
70+
/*
71+
There are 3 differences between BMP and the raw image buffer for LodePNG:
72+
-it's upside down
73+
-it's in BGR instead of RGB format (or BRGA instead of RGBA)
74+
-each scanline has padding bytes to make it a multiple of 4 if needed
75+
The 2D for loop below does all these 3 conversions at once.
76+
*/
77+
for(unsigned y = 0; y < h; y++)
78+
for(unsigned x = 0; x < w; x++) {
79+
//pixel start byte position in the BMP
80+
unsigned bmpos = pixeloffset + (h - y - 1) * scanlineBytes + numChannels * x;
81+
//pixel start byte position in the new raw image
82+
unsigned newpos = 4 * y * w + 4 * x;
83+
if(numChannels == 3) {
84+
image[newpos + 0] = bmp[bmpos + 2]; //R
85+
image[newpos + 1] = bmp[bmpos + 1]; //G
86+
image[newpos + 2] = bmp[bmpos + 0]; //B
87+
image[newpos + 3] = 255; //A
88+
} else {
89+
image[newpos + 0] = bmp[bmpos + 2]; //R
90+
image[newpos + 1] = bmp[bmpos + 1]; //G
91+
image[newpos + 2] = bmp[bmpos + 0]; //B
92+
image[newpos + 3] = bmp[bmpos + 3]; //A
93+
}
94+
}
95+
return 0;
96+
}
97+
98+
int main(int argc, char *argv[]) {
99+
if(argc < 3) {
100+
std::cout << "Please provide input BMP and output PNG file names" << std::endl;
101+
return 0;
102+
}
103+
104+
std::vector<unsigned char> bmp;
105+
lodepng::load_file(bmp, argv[1]);
106+
std::vector<unsigned char> image;
107+
unsigned w, h;
108+
unsigned error = decodeBMP(image, w, h, bmp);
109+
110+
if(error) {
111+
std::cout << "BMP decoding error " << error << std::endl;
112+
return 0;
113+
}
114+
115+
std::vector<unsigned char> png;
116+
error = lodepng::encode(png, image, w, h);
117+
118+
if(error) {
119+
std::cout << "PNG encoding error " << error << ": " << lodepng_error_text(error) << std::endl;
120+
return 0;
121+
}
122+
123+
lodepng::save_file(png, argv[2]);
124+
125+
}

0 commit comments

Comments
 (0)