Fix inconsistent interpretation of ld() in image handling (STR #3308).

Documentation has been fixed and clarified, and ld() handling is now
consistent in Fl_(RGB_)Image, their subclasses and fl_draw_image()
and similar functions.


git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@12029 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Albrecht Schlosser 2016-10-14 16:35:52 +00:00
parent 242d5365e6
commit e3670dfda6
6 changed files with 75 additions and 47 deletions

View File

@ -3,7 +3,7 @@
//
// Image header file for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2014 by Bill Spitzak and others.
// Copyright 1998-2016 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@ -85,6 +85,14 @@ protected:
void d(int D) {d_ = D;}
/**
Sets the current line data size in bytes.
Color images may contain extra data that is included after every
line of color image data and is normally not present.
If \p LD is zero, then line data size is assumed to be w() * d() bytes.
If \p LD is non-zero, then it must be positive and larger than w() * d()
to account for the extra data per line.
*/
void ld(int LD) {ld_ = LD;}
/**
@ -114,8 +122,7 @@ public:
int d() const {return d_;}
/**
Returns the current line data size in bytes.
Line data is extra data that is included
after each line of color image data and is normally not present.
\see ld(int)
*/
int ld() const {return ld_;}
/**

View File

@ -3,7 +3,7 @@
//
// Pixmap (and other images) label support for the Fast Light Tool Kit (FLTK).
//
// Copyright 1998-2015 by Bill Spitzak and others.
// Copyright 1998-2016 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@ -123,7 +123,8 @@ void Fluid_Image::write_static() {
image_header_written = write_number;
}
write_c("static const unsigned char %s[] =\n", idata_name);
write_cdata(img->data()[0], (img->w() * img->d() + img->ld()) * img->h());
const int extra_data = img->ld() ? (img->ld()-img->w()*img->d()) : 0;
write_cdata(img->data()[0], (img->w() * img->d() + extra_data) * img->h());
write_c(";\n");
write_initializer("Fl_RGB_Image", "%s, %d, %d, %d, %d", idata_name, img->w(), img->h(), img->d(), img->ld());
}

View File

@ -330,9 +330,10 @@ int Fl_File_Icon::load_image(const char *ifile) // I - File to read from
temp; // Temporary color
const uchar *row; // Pointer into image
const int extra_data = img->ld() ? (img->ld()-img->w()*img->d()) : 0;
// Loop through grayscale or RGB image...
for (y = 0, row = (const uchar *)(*(img->data())); y < img->h(); y ++, row += img->ld())
for (y = 0, row = (const uchar *)(*(img->data())); y < img->h(); y ++, row += extra_data)
{
for (x = 0, startx = 0, c = (Fl_Color)-1;
x < img->w();
@ -404,7 +405,6 @@ int Fl_File_Icon::load_image(const char *ifile) // I - File to read from
int x, y; // X & Y in image
int startx; // Starting X coord
// Get the pixmap data...
ptr = img->data();
sscanf(*ptr, "%*d%*d%d%d", &ncolors, &chars_per_color);

View File

@ -233,24 +233,39 @@ int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg);
/**
The constructor creates a new image from the specified data.
\param[in] bits The image data array.
\param[in] W The width of the image in pixels
\param[in] H The height of the image in pixels
\param[in] D The image depth, or 'number of channels'. Default=3<br>
If D=1, each uchar in bits[] is a grayscale pixel value.<br>
If D=2, each uchar pair in bits[] is a grayscale + alpha pixel value.<br>
If D=3, each uchar triplet in bits[] is an R/G/B pixel value<br>
If D=4, each uchar quad in bits[] is an R/G/B/A pixel value.
\param[in] LD Line data size (default=0).<br>
Line data is extra data that is included after each line
of color image data and is normally not present.
This constructor sets Fl_RGB_Image::alloc_array to 0.
To have the image object control the deallocation of the data array,
set alloc_array to non-zero after construction.
\see Fl_Image::data(), Fl_Image::w(), Fl_Image::h(), Fl_Image::d(), Fl_Image::ld()
*/
The constructor creates a new image from the specified data.
The data array \p bits must contain sufficient data to provide
\p W * \p H * \p D image bytes and optional line padding, see \p LD.
\p W and \p H are the width and height of the image in pixels, resp.
\p D is the image depth and can be:
- D=1: each uchar in \p bits[] is a grayscale pixel value
- D=2: each uchar pair in \p bits[] is a grayscale + alpha pixel value
- D=3: each uchar triplet in \p bits[] is an R/G/B pixel value
- D=4: each uchar quad in \p bits[] is an R/G/B/A pixel value
\p LD specifies the line data size of the array, see Fl_Image::ld(int).
If \p LD is zero, then \p W * \p D is assumed, otherwise \p LD must be
greater than or equal to \p W * \p D to account for (unused) extra data
per line (padding).
The caller is responsible that the image data array \p bits persists as
long as the image is used.
This constructor sets Fl_RGB_Image::alloc_array to 0.
To have the image object control the deallocation of the data array
\p bits, set alloc_array to non-zero after construction.
\param[in] bits The image data array.
\param[in] W The width of the image in pixels.
\param[in] H The height of the image in pixels.
\param[in] D The image depth, or 'number of channels' (default=3).
\param[in] LD Line data size (default=0).
\see Fl_Image::data(), Fl_Image::w(), Fl_Image::h(), Fl_Image::d(), Fl_Image::ld(int)
*/
Fl_RGB_Image::Fl_RGB_Image(const uchar *bits, int W, int H, int D, int LD) :
Fl_Image(W,H,D),
array(bits),
@ -264,12 +279,15 @@ Fl_RGB_Image::Fl_RGB_Image(const uchar *bits, int W, int H, int D, int LD) :
/**
The constructor creates a new RGBA image from the specified Fl_Pixmap.
The RGBA image is built fully opaque except for the transparent area
of the pixmap that is assigned the \p bg color with full transparency.
This constructor sets Fl_RGB_Image::alloc_array to 1.
*/
The constructor creates a new RGBA image from the specified Fl_Pixmap.
The RGBA image is built fully opaque except for the transparent area
of the pixmap that is assigned the \p bg color with full transparency.
This constructor creates a new internal data array and sets
Fl_RGB_Image::alloc_array to 1 so the data array is deleted when the
image is destroyed.
*/
Fl_RGB_Image::Fl_RGB_Image(const Fl_Pixmap *pxm, Fl_Color bg):
Fl_Image(pxm->w(), pxm->h(), 4),
id_(0),
@ -282,10 +300,10 @@ Fl_RGB_Image::Fl_RGB_Image(const Fl_Pixmap *pxm, Fl_Color bg):
}
/**
The destructor frees all memory and server resources that are used by
the image.
*/
/**
The destructor frees all memory and server resources that are used by
the image.
*/
Fl_RGB_Image::~Fl_RGB_Image() {
uncache();
if (alloc_array) delete[] (uchar *)array;
@ -383,7 +401,7 @@ Fl_Image *Fl_RGB_Image::copy(int W, int H) {
for (dy = 0; dy < H; dy++) {
float oldy = dy * yscale;
if (oldy >= h())
oldy = (float)(h() - 1);
oldy = float(h() - 1);
const float yfract = oldy - (unsigned) oldy;
for (dx = 0; dx < W; dx++) {
@ -391,7 +409,7 @@ Fl_Image *Fl_RGB_Image::copy(int W, int H) {
float oldx = dx * xscale;
if (oldx >= w())
oldx = (float)(w() - 1);
oldx = float(w() - 1);
const float xfract = oldx - (unsigned) oldx;
const unsigned leftx = (unsigned)oldx;

View File

@ -1957,8 +1957,10 @@ static HICON image_to_icon(const Fl_RGB_Image *image, bool is_icon,
return NULL;
const uchar *i = (const uchar*)*image->data();
for (int y = 0;y < image->h();y++) {
for (int x = 0;x < image->w();x++) {
const int extra_data = image->ld() ? (image->ld()-image->w()*image->d()) : 0;
for (int y = 0; y < image->h(); y++) {
for (int x = 0; x < image->w(); x++) {
switch (image->d()) {
case 1:
*bits = (0xff<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
@ -1976,7 +1978,7 @@ static HICON image_to_icon(const Fl_RGB_Image *image, bool is_icon,
i += image->d();
bits++;
}
i += image->ld();
i += extra_data;
}
// A mask bitmap is still needed even though it isn't used
@ -1999,9 +2001,6 @@ static HICON image_to_icon(const Fl_RGB_Image *image, bool is_icon,
DeleteObject(bitmap);
DeleteObject(mask);
if (icon == NULL)
return NULL;
return icon;
}

View File

@ -2612,9 +2612,11 @@ static void icons_to_property(const Fl_RGB_Image *icons[], int count,
data[1] = image->h();
data += 2;
const int extra_data = image->ld() ? (image->ld()-image->w()*image->d()) : 0;
const uchar *in = (const uchar*)*image->data();
for (int y = 0;y < image->h();y++) {
for (int x = 0;x < image->w();x++) {
for (int y = 0; y < image->h(); y++) {
for (int x = 0; x < image->w(); x++) {
switch (image->d()) {
case 1:
*data = ( 0xff<<24) | (in[0]<<16) | (in[0]<<8) | in[0];
@ -2632,7 +2634,7 @@ static void icons_to_property(const Fl_RGB_Image *icons[], int count,
in += image->d();
data++;
}
in += image->ld();
in += extra_data;
}
}
}
@ -2748,6 +2750,7 @@ int Fl_X11_Window_Driver::set_cursor(const Fl_RGB_Image *image, int hotx, int ho
if (!cursor)
return 0;
const int extra_data = image->ld() ? (image->ld()-image->w()*image->d()) : 0;
const uchar *i = (const uchar*)*image->data();
XcursorPixel *o = cursor->pixels;
for (int y = 0;y < image->h();y++) {
@ -2769,7 +2772,7 @@ int Fl_X11_Window_Driver::set_cursor(const Fl_RGB_Image *image, int hotx, int ho
i += image->d();
o++;
}
i += image->ld();
i += extra_data;
}
cursor->xhot = hotx;