wernsey / bitmap Goto Github PK
View Code? Open in Web Editor NEWA C module for manipulating bitmap/raster graphics
License: MIT No Attribution
A C module for manipulating bitmap/raster graphics
License: MIT No Attribution
-----------------------------------------------------------------------
813: if(rd.fread(data, 1, dib.bmp_bytesz, rd.data) != dib.bmp_bytesz) {
-----------------------------------------------------------------------
the bmp_bytesz attribute is controlled by the attacker and the
on line 813, a memory read takes place from the input file and
the data allocated by malloc.
The data is allocated for width and height of image.
-----------------------------------------------------
801: data = CAST(unsigned char *)(malloc(rs * b->h));
-----------------------------------------------------
Potentially Exploitable
--
if(dib.bmp_bytesz == 0) {
// allocate data according to row and height
data = CAST(unsigned char *)(malloc(rs * b->h));
if(!data) {
SET_ERROR("out of memory");
goto error;
}
if(rd.fread(data, 1, rs * b->h, rd.data) != rs * b->h) {
SET_ERROR("fread on data");
goto error;
}
} else {
// allocate data according to image length
data = CAST(unsigned char *)(malloc(dib.bmp_bytesz));
if(!data) {
SET_ERROR("out of memory");
goto error;
}
if(rd.fread(data, 1, dib.bmp_bytesz, rd.data) != dib.bmp_bytesz) {
SET_ERROR("fread on data");
goto error;
}
}
the dimentions of the image can be set to very large values resulting in integer overflow when allocating b->data.
sometimes this value is so large that that b->data often returns
NULL
-------------------------------------------------------------------
279: b->data = CAST(unsigned char *)(malloc(b->w * b->h * BM_BPP));
-------------------------------------------------------------------
which can later cause an out of bounds memory access when
setting the RGBA color.
--------------------------------------------------
798: rs = ((dib.width * dib.bitspp / 8) + 3) & ~3;
--------------------------------------------------
rs is checked to be a multiple of 4, if not the program aborts.
-----------------------------------------------------------------
873: int p = y * rs + i * 3;
874: BM_SET_RGBA(b, i, j, data[p+2], data[p+1], data[p+0], 0xFF);
-----------------------------------------------------------------
on line 6842, the result of bmp->w * bmp->h * BM_BPP may cross the 32 bit range and overflow to a smaller number which then may cause an out of bounds write in BM_SET
-----------------------------------
6842: BM_SET(b, x + i, y + j, col);
-----------------------------------
pwndbg> p/x b->h
$13 = 0xa64d
pwndbg> p/x b->w
$14 = 0x8000
pwndbg> p/x (0xa64d * 0x8000) * 4 # malloc(0x4c9a0000)
$20 = 0x4c9a0000 # it should be 0x14c9a0000
pwndbg> p/x (0x5326 * b->w + 0x4001) * 4 # BM_SET accessing memory
$16 = 0xa64d0004 # 0xa64d004 > 0x4c9a0000
The same issue also exists on line no. 859, 846, 834, 6842
-----------------------------------------------------------
858: uint32_t* pixel = (uint32_t*)(data + p); // p out of range
859: uint32_t r_unc = (*pixel & rgbmask[0]) >> rgbshift[0];
-----------------------------------------------------------
-----------------------------------------------------------
844: int byt = y * rs + (i >> 3); // byt is out of range
845: int bit = 7 - (i % 8);
846: uint8_t p = (data[byt] & (1 << bit)) >> bit;
-----------------------------------------------------------
-----------------------------------------------------------
834: int byt = y * rs + (i >> 1); // byt is out of range
835: uint8_t p = ( (i & 0x01) ? data[byt] : (data[byt] >> 4) ) & 0x0F;
-----------------------------------------------------------
I think width and height must be limited to a value such that calculating ROW_SIZE never overflows the 32 bit range.
If i made a mistake somewhere please dont mind it.
i have a bunch of corpses i got during fuzzing. Crashing BMPs
I'm getting a heap-buffer-overflow when running my auto test which loads the attached gif:
16:56:20: Starting /home/mitch/dev/build-slate-qt5_dev2_debug-Debug/Debug/install-root/usr/local/test-app animationGifExport...
Failed to load qt_* translation for locale "en_GB" from "/home/mitch/dev/qt-dev2-debug/qtbase/translations"
********* Start testing of tst_App *********
Config: Using QtTest library 6.0.0, Qt 6.0.0 (x86_64-little_endian-lp64 shared (dynamic) debug build; by GCC 7.5.0)
PASS : tst_App::initTestCase()
QDEBUG : tst_App::animationGifExport() "/tmp/Slate Test Suite-dVzHHb/animation.gif"
=================================================================
==27720==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6040002eeccf at pc 0x55e95dd0ae9f bp 0x7ffe90423790 sp 0x7ffe90423780
READ of size 1 at 0x6040002eeccf thread T0
#0 0x55e95dd0ae9e in gif_load_fp /home/mitch/dev/slate/lib/3rdparty/bitmap/misc/gif.c:213
#1 0x55e95dd10d47 in gif_load /home/mitch/dev/slate/lib/3rdparty/bitmap/misc/gif.c:825
#2 0x55e95dd51eb9 in tst_App::animationGifExport() /home/mitch/dev/slate/tests/auto/tst_app.cpp:1044
#3 0x55e95de590af in tst_App::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /home/mitch/dev/build-slate-qt5_dev2_debug-Debug/Debug/test-app.99bdad93/qt.headers/tst_app.moc:601
#4 0x7fa80c9035cf in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const /home/mitch/dev/qt-dev2/qtbase/src/corelib/kernel/qmetaobject.cpp:2301
#5 0x7fa815cace02 in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const (/home/mitch/dev/qt-dev2-debug/qtbase/lib/libQt6Test.so.6+0x4ce02)
#6 0x7fa815c97a74 in QTest::TestMethods::invokeTestOnData(int) const /home/mitch/dev/qt-dev2/qtbase/src/testlib/qtestcase.cpp:934
#7 0x7fa815c99b46 in QTest::TestMethods::invokeTest(int, char const*, QTest::WatchDog*) const /home/mitch/dev/qt-dev2/qtbase/src/testlib/qtestcase.cpp:1162
#8 0x7fa815c9cff4 in QTest::TestMethods::invokeTests(QObject*) const /home/mitch/dev/qt-dev2/qtbase/src/testlib/qtestcase.cpp:1503
#9 0x7fa815c9e73b in QTest::qRun() /home/mitch/dev/qt-dev2/qtbase/src/testlib/qtestcase.cpp:1928
#10 0x7fa815c9d960 in QTest::qExec(QObject*, int, char**) /home/mitch/dev/qt-dev2/qtbase/src/testlib/qtestcase.cpp:1836
#11 0x55e95de58d96 in main /home/mitch/dev/slate/tests/auto/tst_app.cpp:6268
#12 0x7fa80b38bb96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#13 0x55e95dd09e29 in _start (/home/mitch/dev/build-slate-qt5_dev2_debug-Debug/Debug/install-root/usr/local/test-app+0x58e29)
Address 0x6040002eeccf is a wild pointer.
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/mitch/dev/slate/lib/3rdparty/bitmap/misc/gif.c:213 in gif_load_fp
Shadow bytes around the buggy address:
0x0c0880055d40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0880055d50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0880055d60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0880055d70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0880055d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c0880055d90: fa fa fa fa fa fa fa fa fa[fa]fa fa fa fa fa fa
0x0c0880055da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0880055db0: fa fa fa fa fa f
![animation](https://user-images.githubusercontent.com/6002340/88071598-54593a00-cb74-11ea-856b-b7451d65ff8b.gif)
a fa fa fa fa fa fa fa fa fa fa
0x0c0880055dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0880055dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c0880055de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==27720==ABORTING
16:56:24: /home/mitch/dev/build-slate-qt5_dev2_debug-Debug/Debug/install-root/usr/local/test-app exited with code 1
The stack trace prints to https://github.com/wernsey/bitmap/blob/master/misc/gif.c#L213, and if I split that expression up:
uint8_t r = bg->r;
uint8_t g = bg->g;
uint8_t b = bg->b;
file.gif->background = bm_rgb(r, g, b);
it points to bg->r
.
I will try to come up with a minimal example.
When building as part of a C++ project on macOS:
/usr/bin/gcc -O2 -Wall -Wextra -target x86_64-apple-macosx10.7-macho -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -pipe -fvisibility=default -fPIC -DNDEBUG -DQT_DEPRECATED_WARNINGS -DQT_CORE_LIB -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_QML_LIB -DQT_QMLTEST_LIB -DQT_TESTLIB_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -I/Users/mitch/dev/slate/app -I/Users/mitch/dev/slate/tests/shared -I/Users/mitch/dev/slate/lib/3rdparty -I/Users/mitch/dev/qt5-slate-fw/qtbase/include -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtCore -I/Users/mitch/dev/qt5-slate/qtbase/mkspecs/macx-clang -I/Users/mitch/dev/slate-qt5_slate_fw-Release/Release/test-app.99bdad93/qt.headers -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtCore/5.13.0 -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtCore/5.13.0/QtCore -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtGui -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtNetwork -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtQml -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtQml/5.13.0 -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtQml/5.13.0/QtQml -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtQuickTest -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtTest -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtWidgets -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtQuick -I/Users/mitch/dev/slate/lib -o /Users/mitch/dev/slate-qt5_slate_fw-Release/Release/test-app.99bdad93/1158f7fbc157be47/gif.c.o -c /Users/mitch/dev/slate/lib/3rdparty/bitmap/misc/gif.c
/Users/mitch/dev/slate/lib/3rdparty/bitmap/misc/gif.c:198:54: warning: comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Wsign-compare]
if(fread(palette, sizeof *palette, sgct, fp) != sgct) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~
/Users/mitch/dev/slate/lib/3rdparty/bitmap/misc/gif.c:363:44: warning: comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Wsign-compare]
if(fread(ct, sizeof *ct, slct, fp) != slct) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~
/Users/mitch/dev/slate/lib/3rdparty/bitmap/misc/gif.c:858:22: warning: comparison of integers of different signs: 'unsigned int' and 'int' [-Wsign-compare]
for(q = 0; q < nc; q++) {
~ ^ ~~
/Users/mitch/dev/slate/lib/3rdparty/bitmap/misc/gif.c:862:22: warning: comparison of integers of different signs: 'unsigned int' and 'int' [-Wsign-compare]
for(q = 0; q < nc; q++) {
~ ^ ~~
/Users/mitch/dev/slate/lib/3rdparty/bitmap/misc/gif.c:882:22: warning: comparison of integers of different signs: 'unsigned int' and 'int' [-Wsign-compare]
for(q = 0; q < nc; q++) {
~ ^ ~~
/Users/mitch/dev/slate/lib/3rdparty/bitmap/misc/gif.c:929:42: warning: comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Wsign-compare]
if(fwrite(gct, sizeof *gct, sgct, f) != sgct) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~
6 warnings generated.
[...]
/usr/bin/gcc -O2 -Wall -Wextra -target x86_64-apple-macosx10.7-macho -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -F/Users/mitch/dev/qt5-slate-fw/qtbase/lib -pipe -fvisibility=default -fPIC -DNDEBUG -DQT_DEPRECATED_WARNINGS -DQT_CORE_LIB -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_QML_LIB -DQT_QMLTEST_LIB -DQT_TESTLIB_LIB -DQT_WIDGETS_LIB -DQT_QUICK_LIB -I/Users/mitch/dev/slate/app -I/Users/mitch/dev/slate/tests/shared -I/Users/mitch/dev/slate/lib/3rdparty -I/Users/mitch/dev/qt5-slate-fw/qtbase/include -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtCore -I/Users/mitch/dev/qt5-slate/qtbase/mkspecs/macx-clang -I/Users/mitch/dev/slate-qt5_slate_fw-Release/Release/test-app.99bdad93/qt.headers -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtCore/5.13.0 -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtCore/5.13.0/QtCore -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtGui -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtNetwork -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtQml -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtQml/5.13.0 -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtQml/5.13.0/QtQml -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtQuickTest -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtTest -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtWidgets -I/Users/mitch/dev/qt5-slate-fw/qtbase/include/QtQuick -I/Users/mitch/dev/slate/lib -o /Users/mitch/dev/slate-qt5_slate_fw-Release/Release/test-app.99bdad93/7562038ad4e26393/bmp.c.o -c /Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:439:26: warning: result of comparison of constant 255 with expression of type 'char' is always false [-Wtautological-constant-out-of-range-compare]
else if(magic[0] == 0xFF && magic[1] == 0xD8)
~~~~~~~~ ^ ~~~~
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:439:46: warning: result of comparison of constant 216 with expression of type 'char' is always false [-Wtautological-constant-out-of-range-compare]
else if(magic[0] == 0xFF && magic[1] == 0xD8)
~~~~~~~~ ^ ~~~~
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:443:26: warning: result of comparison of constant 137 with expression of type 'char' is always false [-Wtautological-constant-out-of-range-compare]
else if(magic[0] == 0x89 && !memcmp(magic+1, "PNG", 3))
~~~~~~~~ ^ ~~~~
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:683:50: warning: comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Wsign-compare]
if(rd.fread(data, 1, rs * b->h, rd.data) != rs * b->h) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:1757:62: warning: comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Wsign-compare]
if(rd.fread(palette, sizeof *palette, sgct, rd.data) != sgct) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:1877:52: warning: comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Wsign-compare]
if(rd.fread(ct, sizeof *ct, slct, rd.data) != slct) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:2427:43: warning: comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Wsign-compare]
fwrite(gct, sizeof *gct, sgct, f) != sgct) {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:3549:27: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
if(!mask || c != maskc)
~ ^ ~~~~~
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:3636:46: warning: unused parameter 'dx' [-Wunused-parameter]
unsigned int bm_smp_outline(Bitmap *dst, int dx, int dy, Bitmap *src, int sx, int sy, unsigned int dest_color) {
^
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:3636:54: warning: unused parameter 'dy' [-Wunused-parameter]
unsigned int bm_smp_outline(Bitmap *dst, int dx, int dy, Bitmap *src, int sx, int sy, unsigned int dest_color) {
^
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:3664:45: warning: unused parameter 'dx' [-Wunused-parameter]
unsigned int bm_smp_border(Bitmap *dst, int dx, int dy, Bitmap *src, int sx, int sy, unsigned int dest_color) {
^
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:3664:53: warning: unused parameter 'dy' [-Wunused-parameter]
unsigned int bm_smp_border(Bitmap *dst, int dx, int dy, Bitmap *src, int sx, int sy, unsigned int dest_color) {
^
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:3696:45: warning: unused parameter 'dx' [-Wunused-parameter]
unsigned int bm_smp_binary(Bitmap *dst, int dx, int dy, Bitmap *src, int sx, int sy, unsigned int dest_color) {
^
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:3696:53: warning: unused parameter 'dy' [-Wunused-parameter]
unsigned int bm_smp_binary(Bitmap *dst, int dx, int dy, Bitmap *src, int sx, int sy, unsigned int dest_color) {
^
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:3703:37: warning: unused parameter 'dst' [-Wunused-parameter]
unsigned int bm_smp_blend50(Bitmap *dst, int dx, int dy, Bitmap *src, int sx, int sy, unsigned int dest_color) {
^
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:3703:46: warning: unused parameter 'dx' [-Wunused-parameter]
unsigned int bm_smp_blend50(Bitmap *dst, int dx, int dy, Bitmap *src, int sx, int sy, unsigned int dest_color) {
^
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:3703:54: warning: unused parameter 'dy' [-Wunused-parameter]
unsigned int bm_smp_blend50(Bitmap *dst, int dx, int dy, Bitmap *src, int sx, int sy, unsigned int dest_color) {
^
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:5537:18: warning: comparison of integers of different signs: 'int' and 'unsigned int' [-Wsign-compare]
for(i = 0; i < npal; i++) {
~ ^ ~~~~
/Users/mitch/dev/slate/lib/3rdparty/bitmap/bmp.c:6034:32: warning: unused parameter 'font' [-Wunused-parameter]
static int xbmf_height(BmFont *font) {
^
19 warnings generated.
Compiler version:
/usr/bin/gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.0 (clang-1000.11.45.2)
Target: x86_64-apple-darwin18.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Thanks for the fixes that resolved the previous issue I raised. It seems to be working OK. This is more of a question than an issue per-se.
Now that I have a bitmap image that is 384 pixels wide and however many pixels long I need to convert it to a format that I can send to a thermal printer that understands "black dot" and "no black dot".
Once the image is converted then I can send it one row at a time to the printer using its own slightly odd control codes.
Is there a more intelligent way to process the colour information so that some of the detail isn't lost?
-Andy.
I am working with a .tga source file which has been generated by an external application which I am then resizing (from 800x480 to 640x384) and rotating using the bitmap library. In outline the code looks like:
Bitmap *in = bm_load("test.tga");
Bitmap *resized = bm_resample_blin(in, NEW_WIDTH, NEW_HEIGHT);
// Create a new bitmap to hold the rotated image hence NEW_WIDTH and NEW_HEIGHT reversed
Bitmap *rotated = bm_create(NEW_HEIGHT, NEW_WIDTH);
bm_rotate_blit(rotated, 0, 640, resized, 0, 0, 4.71239, 1);
bm_save(rotated, "out.bmp");
The resizing process is working OK but when I perform the rotate operation the colours in the background:
Apologies for not being able to show the full image with all the corrupt colours but to do so would put information into the public domain which isn't yet allowed to be there.
The only option being passed on the command line when bmp.c is compiled is -DBM_LAST_ERROR
.
Do you know what I am missing or what I have done wrong?
-Andy.
System: Ubuntu 18.04
Compile use: clang++ with asan, libpng, libjpeg
Here's my program:
#include <cstdio>
#include "bmp.h"
typedef unsigned int uint;
int main(int argc,char** argv)
{
if (argc == 1)
{
std::printf("No Input.\n");
return 0;
}
// Load File
Bitmap *bmp = bm_load(argv[1]);
std::printf("Load OK\n");
// Test W&H
int w = bm_width(bmp);
int h = bm_height(bmp);
std::printf("W&H OK\n");
// Test
bm_clip(bmp,w/4,h/4,3*w/4,3*h/4);
bm_flip_vertical(bmp);
bm_unclip(bmp);
uint col = bm_get(bmp,w/8,h/8);
bm_set(bmp,w/8,h/8,0xFFFFFFFF-col);
std::printf("Test OK\n");
// Save
int sav = bm_save(bmp,"out.bmp");
if (sav)
std::printf("Save OK\n");
else
{
std::printf("Save Crash!\n");
throw 1;
return 1;
}
// free
bm_free(bmp);
std::printf("Finish\n");
return 0;
}
and here is my bmp:
not_kitty.zip
==18470==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000553844 bp 0x000000572df0 sp 0x7ffc6aced1f0 T0)
==18470==The signal is caused by a READ memory access.
==18470==Hint: address points to the zero page.
#0 0x553843 in bm_width /opt/bitmap/bmp.c:4255:15
#1 0x517f7e in main /opt/bitmap/mytest.cpp:19:10
#2 0x7fd86af7fb96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
#3 0x41b669 in _start (/opt/bitmap/mytest+0x41b669)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /opt/bitmap/bmp.c:4255:15 in bm_width
==18470==ABORTING
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.