Implement libnsbmp for bmp decoding
This commit is contained in:
parent
c2cdf256ba
commit
946deb210d
29
bmp.hpp
29
bmp.hpp
@ -241,7 +241,7 @@ struct BMP {
|
||||
uint32_t channels = bmp_info_header.bit_count / 8;
|
||||
for (uint32_t y = y0; y < y0 + h; ++y) {
|
||||
for (uint32_t x = x0; x < x0 + w; ++x) {
|
||||
if (!(x + w > (uint32_t)bmp_info_header.width) || !(y + h > (uint32_t)-1)) {
|
||||
if (!(x + w > (uint32_t)bmp_info_header.width) || this->bmp_info_header.height - y - h < (uint32_t)0) {
|
||||
|
||||
data[channels * (y * bmp_info_header.width + x) + 0] = B;
|
||||
data[channels * (y * bmp_info_header.width + x) + 1] = G;
|
||||
@ -549,6 +549,21 @@ struct BMP {
|
||||
}
|
||||
}
|
||||
|
||||
void set_pixel_df(uint32_t x0, uint32_t y0, uint8_t B, uint8_t G, uint8_t R, uint8_t A) {
|
||||
uint32_t y1 = this->bmp_info_header.height - y0;
|
||||
if (x0 >= (uint32_t)bmp_info_header.width || y1 <= (uint32_t)bmp_info_header.width || x0 < 0 || y0 > 0) {
|
||||
return;//throw std::runtime_error("The point is outside the image boundaries!");
|
||||
}
|
||||
|
||||
uint32_t channels = bmp_info_header.bit_count / 8;
|
||||
data[channels * (y0 * bmp_info_header.width + x0) + 0] = B;
|
||||
data[channels * (y0 * bmp_info_header.width + x0) + 1] = G;
|
||||
data[channels * (y0 * bmp_info_header.width + x0) + 2] = R;
|
||||
if (channels == 4) {
|
||||
data[channels * (y0 * bmp_info_header.width + x0) + 3] = A;
|
||||
}
|
||||
}
|
||||
|
||||
void draw_rectangle(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h,
|
||||
uint8_t B, uint8_t G, uint8_t R, uint8_t A, uint8_t line_w) {
|
||||
if (x0 + w > (uint32_t)bmp_info_header.width || y0 + h > (uint32_t)bmp_info_header.height) {
|
||||
@ -561,6 +576,18 @@ struct BMP {
|
||||
fill_region(x0, (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, A); // left line
|
||||
}
|
||||
|
||||
void draw_rectangle_df(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h,
|
||||
uint8_t B, uint8_t G, uint8_t R, uint8_t A, uint8_t line_w) {
|
||||
if (x0 + w > (uint32_t)bmp_info_header.width || y0 + h > (uint32_t)bmp_info_header.height) {
|
||||
return;//throw std::runtime_error("The rectangle does not fit in the image!");
|
||||
}
|
||||
|
||||
fill_region_df(x0, y0, w, line_w, B, G, R, A); // top line
|
||||
fill_region_df(x0, (y0 + h - line_w), w, line_w, B, G, R, A); // bottom line
|
||||
fill_region_df((x0 + w - line_w), (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, A); // right line
|
||||
fill_region_df(x0, (y0 + line_w), line_w, (h - (2 * line_w)), B, G, R, A); // left line
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t row_stride{ 0 };
|
||||
|
||||
|
20
external/libnsbmp/COPYING
vendored
Normal file
20
external/libnsbmp/COPYING
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
Copyright (C) 2006 Richard Wilson
|
||||
Copyright (C) 2008 Sean Fox
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
1388
external/libnsbmp/libnsbmp.c
vendored
Normal file
1388
external/libnsbmp/libnsbmp.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
250
external/libnsbmp/libnsbmp.h
vendored
Normal file
250
external/libnsbmp/libnsbmp.h
vendored
Normal file
@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright 2006 Richard Wilson <richard.wilson@netsurf-browser.org>
|
||||
* Copyright 2008 Sean Fox <dyntryx@gmail.com>
|
||||
*
|
||||
* This file is part of NetSurf's libnsbmp, http://www.netsurf-browser.org/
|
||||
* Licenced under the MIT License,
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Bitmap file decoding interface.
|
||||
*/
|
||||
|
||||
#ifndef libnsbmp_h_
|
||||
#define libnsbmp_h_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* bmp flags */
|
||||
#define BMP_NEW 0
|
||||
/** image is opaque (as opposed to having an alpha mask) */
|
||||
#define BMP_OPAQUE (1 << 0)
|
||||
/** memory should be wiped */
|
||||
#define BMP_CLEAR_MEMORY (1 << 1)
|
||||
|
||||
/**
|
||||
* error return values
|
||||
*/
|
||||
typedef enum {
|
||||
BMP_OK = 0,
|
||||
BMP_INSUFFICIENT_MEMORY = 1,
|
||||
BMP_INSUFFICIENT_DATA = 2,
|
||||
BMP_DATA_ERROR = 3
|
||||
} bmp_result;
|
||||
|
||||
/**
|
||||
* encoding types
|
||||
*/
|
||||
typedef enum {
|
||||
BMP_ENCODING_RGB = 0,
|
||||
BMP_ENCODING_RLE8 = 1,
|
||||
BMP_ENCODING_RLE4 = 2,
|
||||
BMP_ENCODING_BITFIELDS = 3
|
||||
} bmp_encoding;
|
||||
|
||||
/* API for Bitmap callbacks */
|
||||
typedef void* (*bmp_bitmap_cb_create)(int width, int height, unsigned int state);
|
||||
typedef void (*bmp_bitmap_cb_destroy)(void *bitmap);
|
||||
typedef unsigned char* (*bmp_bitmap_cb_get_buffer)(void *bitmap);
|
||||
typedef size_t (*bmp_bitmap_cb_get_bpp)(void *bitmap);
|
||||
|
||||
/**
|
||||
* The Bitmap callbacks function table
|
||||
*/
|
||||
typedef struct bmp_bitmap_callback_vt_s {
|
||||
/** Callback to allocate bitmap storage. */
|
||||
bmp_bitmap_cb_create bitmap_create;
|
||||
/** Called to free bitmap storage. */
|
||||
bmp_bitmap_cb_destroy bitmap_destroy;
|
||||
/** Return a pointer to the pixel data in a bitmap. */
|
||||
bmp_bitmap_cb_get_buffer bitmap_get_buffer;
|
||||
/** Find the width of a pixel row in bytes. */
|
||||
bmp_bitmap_cb_get_bpp bitmap_get_bpp;
|
||||
} bmp_bitmap_callback_vt;
|
||||
|
||||
/**
|
||||
* bitmap image
|
||||
*/
|
||||
typedef struct bmp_image {
|
||||
/** callbacks for bitmap functions */
|
||||
bmp_bitmap_callback_vt bitmap_callbacks;
|
||||
/** pointer to BMP data */
|
||||
uint8_t *bmp_data;
|
||||
/** width of BMP (valid after _analyse) */
|
||||
uint32_t width;
|
||||
/** heigth of BMP (valid after _analyse) */
|
||||
uint32_t height;
|
||||
/** whether the image has been decoded */
|
||||
bool decoded;
|
||||
/** decoded image */
|
||||
void *bitmap;
|
||||
|
||||
/* Internal members are listed below */
|
||||
/** total number of bytes of BMP data available */
|
||||
uint32_t buffer_size;
|
||||
/** pixel encoding type */
|
||||
bmp_encoding encoding;
|
||||
/** offset of bitmap data */
|
||||
uint32_t bitmap_offset;
|
||||
/** bits per pixel */
|
||||
uint16_t bpp;
|
||||
/** number of colours */
|
||||
uint32_t colours;
|
||||
/** colour table */
|
||||
uint32_t *colour_table;
|
||||
/** whether to use bmp's limited transparency */
|
||||
bool limited_trans;
|
||||
/** colour to display for "transparent" pixels when using limited
|
||||
* transparency
|
||||
*/
|
||||
uint32_t trans_colour;
|
||||
/** scanlines are top to bottom */
|
||||
bool reversed;
|
||||
/** image is part of an ICO, mask follows */
|
||||
bool ico;
|
||||
/** true if the bitmap does not contain an alpha channel */
|
||||
bool opaque;
|
||||
/** four bitwise mask */
|
||||
uint32_t mask[4];
|
||||
/** four bitwise shifts */
|
||||
int32_t shift[4];
|
||||
/** colour representing "transparency" in the bitmap */
|
||||
uint32_t transparent_index;
|
||||
} bmp_image;
|
||||
|
||||
typedef struct ico_image {
|
||||
bmp_image bmp;
|
||||
struct ico_image *next;
|
||||
} ico_image;
|
||||
|
||||
/**
|
||||
* icon image collection
|
||||
*/
|
||||
typedef struct ico_collection {
|
||||
/** callbacks for bitmap functions */
|
||||
bmp_bitmap_callback_vt bitmap_callbacks;
|
||||
/** width of largest BMP */
|
||||
uint16_t width;
|
||||
/** heigth of largest BMP */
|
||||
uint16_t height;
|
||||
|
||||
/* Internal members are listed below */
|
||||
/** pointer to ICO data */
|
||||
uint8_t *ico_data;
|
||||
/** total number of bytes of ICO data available */
|
||||
uint32_t buffer_size;
|
||||
/** root of linked list of images */
|
||||
ico_image *first;
|
||||
} ico_collection;
|
||||
|
||||
/**
|
||||
* Initialises bitmap ready for analysing the bitmap.
|
||||
*
|
||||
* \param bmp The Bitmap to initialise
|
||||
* \param callbacks The callbacks the library will call on operations.
|
||||
* \return BMP_OK on success or appropriate error code.
|
||||
*/
|
||||
bmp_result bmp_create(bmp_image *bmp, bmp_bitmap_callback_vt *callbacks);
|
||||
|
||||
/**
|
||||
* Initialises icon ready for analysing the icon
|
||||
*
|
||||
* \param bmp The Bitmap to initialise
|
||||
* \param callbacks The callbacks the library will call on operations.
|
||||
* \return BMP_OK on success or appropriate error code.
|
||||
*/
|
||||
bmp_result ico_collection_create(ico_collection *ico,
|
||||
bmp_bitmap_callback_vt *callbacks);
|
||||
|
||||
/**
|
||||
* Analyse a BMP prior to decoding.
|
||||
*
|
||||
* This will scan the data provided and perform checks to ensure the data is a
|
||||
* valid BMP and prepare the bitmap image structure ready for decode.
|
||||
*
|
||||
* This function must be called and resturn BMP_OK before bmp_decode() as it
|
||||
* prepares the bmp internal state for the decode process.
|
||||
*
|
||||
* \param bmp the BMP image to analyse.
|
||||
* \param size The size of data in cdata.
|
||||
* \param data The bitmap source data.
|
||||
* \return BMP_OK on success or error code on faliure.
|
||||
*/
|
||||
bmp_result bmp_analyse(bmp_image *bmp, size_t size, uint8_t *data);
|
||||
|
||||
/**
|
||||
* Analyse an ICO prior to decoding.
|
||||
*
|
||||
* This function will scan the data provided and perform checks to ensure the
|
||||
* data is a valid ICO.
|
||||
*
|
||||
* This function must be called before ico_find().
|
||||
*
|
||||
* \param ico the ICO image to analyse
|
||||
* \param size The size of data in cdata.
|
||||
* \param data The bitmap source data.
|
||||
* \return BMP_OK on success
|
||||
*/
|
||||
bmp_result ico_analyse(ico_collection *ico, size_t size, uint8_t *data);
|
||||
|
||||
/**
|
||||
* Decode a BMP
|
||||
*
|
||||
* This function decodes the BMP data such that bmp->bitmap is a valid
|
||||
* image. The state of bmp->decoded is set to TRUE on exit such that it
|
||||
* can easily be identified which BMPs are in a fully decoded state.
|
||||
*
|
||||
* \param bmp the BMP image to decode
|
||||
* \return BMP_OK on success
|
||||
*/
|
||||
bmp_result bmp_decode(bmp_image *bmp);
|
||||
|
||||
/**
|
||||
* Decode a BMP using "limited transparency"
|
||||
*
|
||||
* Bitmaps do not have native transparency support. However, there is a
|
||||
* "trick" that is used in some instances in which the first pixel of the
|
||||
* bitmap becomes the "transparency index". The decoding application can
|
||||
* replace this index with whatever background colour it chooses to
|
||||
* create the illusion of transparency.
|
||||
*
|
||||
* When to use transparency is at the discretion of the decoding
|
||||
* application.
|
||||
*
|
||||
* \param bmp the BMP image to decode
|
||||
* \param colour the colour to use as "transparent"
|
||||
* \return BMP_OK on success
|
||||
*/
|
||||
bmp_result bmp_decode_trans(bmp_image *bmp, uint32_t transparent_colour);
|
||||
|
||||
/**
|
||||
* Finds the closest BMP within an ICO collection
|
||||
*
|
||||
* This function finds the BMP with dimensions as close to a specified set
|
||||
* as possible from the images in the collection.
|
||||
*
|
||||
* \param ico the ICO collection to examine
|
||||
* \param width the preferred width (0 to use ICO header width)
|
||||
* \param height the preferred height (0 to use ICO header height)
|
||||
*/
|
||||
bmp_image *ico_find(ico_collection *ico, uint16_t width, uint16_t height);
|
||||
|
||||
/**
|
||||
* Finalise a BMP prior to destruction.
|
||||
*
|
||||
* \param bmp the BMP image to finalise.
|
||||
*/
|
||||
void bmp_finalise(bmp_image *bmp);
|
||||
|
||||
/**
|
||||
* Finalise an ICO prior to destruction.
|
||||
*
|
||||
* \param ico the ICO image to finalise,
|
||||
*/
|
||||
void ico_finalise(ico_collection *ico);
|
||||
|
||||
#endif
|
27
external/libnsbmp/log.h
vendored
Normal file
27
external/libnsbmp/log.h
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2003 James Bursa <bursa@users.sourceforge.net>
|
||||
* Copyright 2004 John Tytgat <John.Tytgat@aaug.net>
|
||||
*
|
||||
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
||||
* Licenced under the MIT License,
|
||||
* http://www.opensource.org/licenses/mit-license.php
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifndef _LIBNSBMP_LOG_H_
|
||||
#define _LIBNSBMP_LOG_H_
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define LOG(x) ((void) 0)
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# define LOG(x) do { printf x, fputc('\n', stdout)); } while (0)
|
||||
# elif defined(__CC_NORCROFT)
|
||||
# define LOG(x) do { printf x, fputc('\n', stdout)); } while (0)
|
||||
# else
|
||||
# define LOG(x) do { printf x, fputc('\n', stdout)); } while (0)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif
|
82
renderd7.cpp
82
renderd7.cpp
@ -1421,22 +1421,84 @@ std::string RenderD7::GetTimeStr(void)
|
||||
struct tm* timeStruct = gmtime((const time_t*)&unixTime);
|
||||
return RenderD7::FormatString("%02i:%02i:%02i", timeStruct->tm_hour, timeStruct->tm_min, timeStruct->tm_sec);
|
||||
}
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "libnsbmp.h"
|
||||
}
|
||||
static const u32 BYTES_PER_PIXEL = 4;
|
||||
#define MAX_IMAGE_BYTES (48 * 1024 * 1024)
|
||||
|
||||
unsigned Image_to_C3D(C2D_Image img, const std::vector<unsigned char>& bmp) {
|
||||
C2D_Image* images;
|
||||
C3DTexToC2DImage(images, 1024, 1024, (u8*)bmp.data());
|
||||
img.tex = images->tex;
|
||||
img.subtex = images->subtex;
|
||||
return false;
|
||||
namespace LIBBMP {
|
||||
static void *bitmap_create(int width, int height, [[maybe_unused]] unsigned int state) {
|
||||
/* ensure a stupidly large (>50Megs or so) bitmap is not created */
|
||||
if ((static_cast<long long>(width) * static_cast<long long>(height)) > (MAX_IMAGE_BYTES/BYTES_PER_PIXEL))
|
||||
return nullptr;
|
||||
|
||||
return std::calloc(width * height, BYTES_PER_PIXEL);
|
||||
}
|
||||
|
||||
static unsigned char *bitmap_get_buffer(void *bitmap) {
|
||||
assert(bitmap);
|
||||
return static_cast<unsigned char *>(bitmap);
|
||||
}
|
||||
|
||||
static size_t bitmap_get_bpp([[maybe_unused]] void *bitmap) {
|
||||
return BYTES_PER_PIXEL;
|
||||
}
|
||||
|
||||
static void bitmap_destroy(void *bitmap) {
|
||||
assert(bitmap);
|
||||
std::free(bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned Image_to_C3D(C2D_Image img, const std::vector<unsigned char>& bmpc) {
|
||||
bmp_bitmap_callback_vt bitmap_callbacks = {
|
||||
LIBBMP::bitmap_create,
|
||||
LIBBMP::bitmap_destroy,
|
||||
LIBBMP::bitmap_get_buffer,
|
||||
LIBBMP::bitmap_get_bpp
|
||||
};
|
||||
|
||||
bmp_result code = BMP_OK;
|
||||
bmp_image bmp;
|
||||
bmp_create(&bmp, &bitmap_callbacks);
|
||||
|
||||
code = bmp_analyse(&bmp, bmpc.size(), (u8*)bmpc.data());
|
||||
if (code != BMP_OK) {
|
||||
bmp_finalise(&bmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
code = bmp_decode(&bmp);
|
||||
if (code != BMP_OK) {
|
||||
if ((code != BMP_INSUFFICIENT_DATA) && (code != BMP_DATA_ERROR)) {
|
||||
bmp_finalise(&bmp);
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* skip if the decoded image would be ridiculously large */
|
||||
if ((bmp.width * bmp.height) > 200000) {
|
||||
bmp_finalise(&bmp);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
C2D_Image* texture;
|
||||
bool ret = C3DTexToC2DImage(texture, static_cast<u32>(bmp.width), static_cast<u32>(bmp.height), static_cast<u8 *>(bmp.bitmap));
|
||||
bmp_finalise(&bmp);
|
||||
if (!ret)
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RenderD7::Image::LoadFromBitmap(BMP bitmap)
|
||||
{
|
||||
unsigned error = Image_to_C3D(this->img, bitmap.DATA());
|
||||
|
||||
if(error) {
|
||||
if(error) {
|
||||
std::cout << "BMP decoding error " << error << std::endl;
|
||||
RenderD7::AddOvl(std::make_unique<RenderD7::Toast>("Bmp - Error", "Code: " + std::to_string(error)));
|
||||
}
|
||||
@ -1460,7 +1522,7 @@ void RenderD7::Toast::Draw(void) const
|
||||
void RenderD7::Toast::Logic()
|
||||
{
|
||||
this->delay++/*=(int)RenderD7::GetDeltaTime()*/;
|
||||
if (msgposy > 170 && delay < 5*60) msgposy--/*=(int)RenderD7::GetDeltaTime()*/;
|
||||
if (msgposy > 170 && delay < 2*60) msgposy--/*=(int)RenderD7::GetDeltaTime()*/;
|
||||
|
||||
if (delay >= 5*60)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user