Tighten protection against grs_bitmap bm_data confusion

Bitmaps based on grs_main_bitmap own their data.  Bitmaps based on
grs_bitmap do not.  Adjust prototypes to prevent initializing a
grs_main_bitmap with data it will not own.
This commit is contained in:
Kp 2019-02-02 18:36:39 +00:00
parent ba442b99bd
commit 7bcbaae230
6 changed files with 56 additions and 47 deletions

View file

@ -41,7 +41,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
namespace dcx {
// Allocated a bitmap and makes its data be raw_data that is already somewhere.
static grs_bitmap_ptr gr_create_bitmap_raw(uint16_t w, uint16_t h, unsigned char * raw_data);
static grs_bitmap_ptr gr_create_bitmap_raw(uint16_t w, uint16_t h, RAIIdmem<uint8_t[]> raw_data);
void gr_set_bitmap_data(grs_bitmap &bm, const uint8_t *data)
{
@ -53,19 +53,20 @@ void gr_set_bitmap_data(grs_bitmap &bm, const uint8_t *data)
grs_bitmap_ptr gr_create_bitmap(uint16_t w, uint16_t h )
{
unsigned char *d;
RAIIdmem<uint8_t[]> d;
MALLOC(d, unsigned char, MAX_BMP_SIZE(w, h));
return gr_create_bitmap_raw (w, h, d);
return gr_create_bitmap_raw(w, h, std::move(d));
}
grs_bitmap_ptr gr_create_bitmap_raw(uint16_t w, uint16_t h, unsigned char * raw_data )
grs_bitmap_ptr gr_create_bitmap_raw(const uint16_t w, const uint16_t h, RAIIdmem<uint8_t[]> raw_data)
{
auto n = make_unique<grs_main_bitmap>();
gr_init_bitmap(*n.get(), bm_mode::linear, 0, 0, w, h, w, raw_data);
gr_init_main_bitmap(*n.get(), bm_mode::linear, 0, 0, w, h, w, std::move(raw_data));
return n;
}
void gr_init_bitmap(grs_bitmap &bm, const bm_mode mode, const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h, const uint16_t bytesperline, const uint8_t *const data) // TODO: virtualize
// TODO: virtualize
void gr_init_bitmap(grs_bitmap &bm, const bm_mode mode, const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h, const uint16_t bytesperline, const uint8_t *const data) noexcept
{
bm.bm_x = x;
bm.bm_y = y;
@ -75,19 +76,24 @@ void gr_init_bitmap(grs_bitmap &bm, const bm_mode mode, const uint16_t x, const
bm.set_type(mode);
bm.bm_rowsize = bytesperline;
bm.bm_data = nullptr;
bm.bm_data = data;
#if DXX_USE_OGL
bm.bm_parent = nullptr;
bm.gltexture = nullptr;
#endif
gr_set_bitmap_data(bm, data);
}
void gr_init_main_bitmap(grs_main_bitmap &bm, const bm_mode mode, const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h, const uint16_t bytesperline, RAIIdmem<uint8_t[]> data)
{
gr_init_bitmap(bm, mode, x, y, w, h, bytesperline, data.get());
data.release();
}
void gr_init_bitmap_alloc(grs_main_bitmap &bm, const bm_mode mode, const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h, const uint16_t bytesperline)
{
unsigned char *d;
RAIIdmem<uint8_t[]> d;
MALLOC(d, unsigned char, MAX_BMP_SIZE(w, h));
gr_init_bitmap(bm, mode, x, y, w, h, bytesperline, d);
gr_init_main_bitmap(bm, mode, x, y, w, h, bytesperline, std::move(d));
}
grs_main_bitmap::grs_main_bitmap()

View file

@ -28,6 +28,7 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
#include <utility>
#include "palette.h"
#include "maths.h"
#include "u_mem.h"
// some defines for transparency and blending
#define TRANSPARENCY_COLOR 255 // palette entry of transparency color -- 255 on the PC
@ -90,7 +91,6 @@ enum bm_mode : uint8_t
struct grs_bitmap;
struct grs_canvas;
#define GRS_FONT_SIZE 28 // how much space it takes up on disk
struct grs_font;
struct grs_point;
union screen_mode;
@ -109,6 +109,8 @@ typedef std::unique_ptr<grs_subcanvas> grs_subcanvas_ptr;
class grs_main_bitmap;
typedef std::unique_ptr<grs_main_bitmap> grs_bitmap_ptr;
struct grs_font;
#if SDL_MAJOR_VERSION == 1
uint_fast32_t gr_list_modes(array<screen_mode, 50> &modes);
#elif SDL_MAJOR_VERSION == 2
@ -152,7 +154,8 @@ void gr_clear_canvas(grs_canvas &, color_t color);
// Bitmap functions:
// these are the two workhorses, the others just use these
void gr_init_bitmap(grs_bitmap &bm, bm_mode mode, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t bytesperline, const uint8_t* data);
void gr_init_bitmap(grs_bitmap &bm, bm_mode mode, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t bytesperline, const uint8_t *data) noexcept;
void gr_init_main_bitmap(grs_main_bitmap &bm, bm_mode mode, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t bytesperline, RAIIdmem<uint8_t[]> data);
void gr_init_sub_bitmap (grs_bitmap &bm, grs_bitmap &bmParent, uint16_t x, uint16_t y, uint16_t w, uint16_t h);
void gr_init_bitmap_alloc(grs_main_bitmap &bm, bm_mode mode, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t bytesperline);

View file

@ -103,28 +103,6 @@ public:
ubyte avg_color; // Average color of all pixels in texture map.
};
//font structure
struct grs_font : public prohibit_void_ptr<grs_font>
{
short ft_w; // Width in pixels
short ft_h; // Height in pixels
short ft_flags; // Proportional?
short ft_baseline; //
ubyte ft_minchar; // First char defined by this font
ubyte ft_maxchar; // Last char defined by this font
array<char, 13> ft_filename;
const uint8_t *ft_data; // Ptr to raw data.
const uint8_t *const *ft_chars; // Ptrs to data for each char (required for prop font)
const int16_t *ft_widths; // Array of widths (required for prop font)
const uint8_t *ft_kerndata; // Array of kerning triplet data
std::unique_ptr<uint8_t[]> ft_allocdata;
#if DXX_USE_OGL
// These fields do not participate in disk i/o!
std::unique_ptr<grs_bitmap[]> ft_bitmaps;
grs_bitmap ft_parent_bitmap;
#endif /* def OGL */
};
struct grs_canvas : prohibit_void_ptr<grs_canvas>
{
~grs_canvas()
@ -286,6 +264,28 @@ class grs_subbitmap : public grs_bitmap
{
};
//font structure
struct grs_font : public prohibit_void_ptr<grs_font>
{
int16_t ft_w; // Width in pixels
int16_t ft_h; // Height in pixels
int16_t ft_flags; // Proportional?
int16_t ft_baseline; //
uint8_t ft_minchar; // First char defined by this font
uint8_t ft_maxchar; // Last char defined by this font
array<char, 13> ft_filename;
const uint8_t *ft_data = nullptr; // Ptr to raw data.
const uint8_t *const *ft_chars = nullptr; // Ptrs to data for each char (required for prop font)
const int16_t *ft_widths = nullptr; // Array of widths (required for prop font)
const uint8_t *ft_kerndata = nullptr; // Array of kerning triplet data
std::unique_ptr<uint8_t[]> ft_allocdata;
#if DXX_USE_OGL
// These fields do not participate in disk i/o!
std::unique_ptr<grs_bitmap[]> ft_bitmaps;
grs_main_bitmap ft_parent_bitmap;
#endif /* def OGL */
};
}
static inline void gr_set_bitmap_flags(grs_bitmap &bm, uint8_t flags)

View file

@ -158,6 +158,12 @@ RAIIdmem<T> &MALLOC(RAIIdmem<T> &r, std::size_t count, const char *var, const ch
return r.reset(MALLOC<typename RAIIdmem<T>::element_type>(p, count, var, file, line)), r;
}
template <typename T>
RAIIdmem<T[]> &MALLOC(RAIIdmem<T[]> &r, const std::size_t count, const char *const var, const char *const file, const unsigned line)
{
return MALLOC<T[]>(r, count, var, file, line);
}
template <typename T>
void CALLOC(RAIIdmem<T> &r, std::size_t count, const char *var, const char *file, unsigned line)
{

View file

@ -42,9 +42,6 @@ COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
#include "compiler-make_unique.h"
#include "ntstring.h"
struct grs_bitmap;
struct grs_font;
namespace dcx {
struct UI_KEYPAD {

View file

@ -507,15 +507,18 @@ static void ogl_init_font(grs_font * font)
int oglflags = OGL_FLAG_ALPHA;
int nchars = font->ft_maxchar-font->ft_minchar+1;
int w,h,tw,th,curx=0,cury=0;
uint8_t *data;
int gap=1; // x/y offset between the chars so we can filter
th = tw = 0xffff;
ogl_font_choose_size(font,gap,&tw,&th);
MALLOC(data, ubyte, tw*th);
memset(data, TRANSPARENCY_COLOR, tw * th); // map the whole data with transparency so we won't have borders if using gap
gr_init_bitmap(font->ft_parent_bitmap,bm_mode::linear,0,0,tw,th,tw,data);
{
RAIIdmem<uint8_t[]> data;
const unsigned length = tw * th;
MALLOC(data, uint8_t, length);
std::fill_n(data.get(), TRANSPARENCY_COLOR, length); // map the whole data with transparency so we won't have borders if using gap
gr_init_main_bitmap(font->ft_parent_bitmap, bm_mode::linear, 0, 0, tw, th, tw, std::move(data));
}
gr_set_transparent(font->ft_parent_bitmap, 1);
if (!(font->ft_flags & FT_COLOR))
@ -853,9 +856,6 @@ void gr_close_font(std::unique_ptr<grs_font> font)
{
if (font)
{
#if DXX_USE_OGL
gr_free_bitmap_data(font->ft_parent_bitmap);
#endif
//find font in list
if (!(font->ft_flags & FT_COLOR))
return;
@ -1063,9 +1063,6 @@ void gr_remap_font(grs_font *font, const char *fontname)
return;
if (!(n->ft_flags & FT_COLOR))
return;
#if DXX_USE_OGL
gr_free_bitmap_data(font->ft_parent_bitmap);
#endif
*font = std::move(*n.get());
#if DXX_USE_OGL
ogl_init_font(font);