mirror of
https://github.com/fltk/fltk.git
synced 2026-06-04 23:42:15 +08:00
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:
+10
-3
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Image header file for the Fast Light Tool Kit (FLTK).
|
// 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
|
// 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
|
// the file "COPYING" which should have been included with this file. If this
|
||||||
@@ -85,6 +85,14 @@ protected:
|
|||||||
void d(int D) {d_ = D;}
|
void d(int D) {d_ = D;}
|
||||||
/**
|
/**
|
||||||
Sets the current line data size in bytes.
|
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;}
|
void ld(int LD) {ld_ = LD;}
|
||||||
/**
|
/**
|
||||||
@@ -114,8 +122,7 @@ public:
|
|||||||
int d() const {return d_;}
|
int d() const {return d_;}
|
||||||
/**
|
/**
|
||||||
Returns the current line data size in bytes.
|
Returns the current line data size in bytes.
|
||||||
Line data is extra data that is included
|
\see ld(int)
|
||||||
after each line of color image data and is normally not present.
|
|
||||||
*/
|
*/
|
||||||
int ld() const {return ld_;}
|
int ld() const {return ld_;}
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Pixmap (and other images) label support for the Fast Light Tool Kit (FLTK).
|
// 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
|
// 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
|
// 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;
|
image_header_written = write_number;
|
||||||
}
|
}
|
||||||
write_c("static const unsigned char %s[] =\n", idata_name);
|
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_c(";\n");
|
||||||
write_initializer("Fl_RGB_Image", "%s, %d, %d, %d, %d", idata_name, img->w(), img->h(), img->d(), img->ld());
|
write_initializer("Fl_RGB_Image", "%s, %d, %d, %d, %d", idata_name, img->w(), img->h(), img->d(), img->ld());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -330,9 +330,10 @@ int Fl_File_Icon::load_image(const char *ifile) // I - File to read from
|
|||||||
temp; // Temporary color
|
temp; // Temporary color
|
||||||
const uchar *row; // Pointer into image
|
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...
|
// 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;
|
for (x = 0, startx = 0, c = (Fl_Color)-1;
|
||||||
x < img->w();
|
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 x, y; // X & Y in image
|
||||||
int startx; // Starting X coord
|
int startx; // Starting X coord
|
||||||
|
|
||||||
|
|
||||||
// Get the pixmap data...
|
// Get the pixmap data...
|
||||||
ptr = img->data();
|
ptr = img->data();
|
||||||
sscanf(*ptr, "%*d%*d%d%d", &ncolors, &chars_per_color);
|
sscanf(*ptr, "%*d%*d%d%d", &ncolors, &chars_per_color);
|
||||||
|
|||||||
+48
-30
@@ -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.
|
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
|
The data array \p bits must contain sufficient data to provide
|
||||||
\param[in] H The height of the image in pixels
|
\p W * \p H * \p D image bytes and optional line padding, see \p LD.
|
||||||
\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>
|
\p W and \p H are the width and height of the image in pixels, resp.
|
||||||
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>
|
\p D is the image depth and can be:
|
||||||
If D=4, each uchar quad in bits[] is an R/G/B/A pixel value.
|
- D=1: each uchar in \p bits[] is a grayscale pixel value
|
||||||
\param[in] LD Line data size (default=0).<br>
|
- D=2: each uchar pair in \p bits[] is a grayscale + alpha pixel value
|
||||||
Line data is extra data that is included after each line
|
- D=3: each uchar triplet in \p bits[] is an R/G/B pixel value
|
||||||
of color image data and is normally not present.
|
- D=4: each uchar quad in \p bits[] is an R/G/B/A pixel value
|
||||||
|
|
||||||
This constructor sets Fl_RGB_Image::alloc_array to 0.
|
\p LD specifies the line data size of the array, see Fl_Image::ld(int).
|
||||||
To have the image object control the deallocation of the data array,
|
If \p LD is zero, then \p W * \p D is assumed, otherwise \p LD must be
|
||||||
set alloc_array to non-zero after construction.
|
greater than or equal to \p W * \p D to account for (unused) extra data
|
||||||
\see Fl_Image::data(), Fl_Image::w(), Fl_Image::h(), Fl_Image::d(), Fl_Image::ld()
|
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_RGB_Image::Fl_RGB_Image(const uchar *bits, int W, int H, int D, int LD) :
|
||||||
Fl_Image(W,H,D),
|
Fl_Image(W,H,D),
|
||||||
array(bits),
|
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 constructor creates a new RGBA image from the specified Fl_Pixmap.
|
||||||
|
|
||||||
The RGBA image is built fully opaque except for the transparent area
|
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.
|
of the pixmap that is assigned the \p bg color with full transparency.
|
||||||
This constructor sets Fl_RGB_Image::alloc_array to 1.
|
|
||||||
*/
|
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_RGB_Image::Fl_RGB_Image(const Fl_Pixmap *pxm, Fl_Color bg):
|
||||||
Fl_Image(pxm->w(), pxm->h(), 4),
|
Fl_Image(pxm->w(), pxm->h(), 4),
|
||||||
id_(0),
|
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 destructor frees all memory and server resources that are used by
|
||||||
the image.
|
the image.
|
||||||
*/
|
*/
|
||||||
Fl_RGB_Image::~Fl_RGB_Image() {
|
Fl_RGB_Image::~Fl_RGB_Image() {
|
||||||
uncache();
|
uncache();
|
||||||
if (alloc_array) delete[] (uchar *)array;
|
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++) {
|
for (dy = 0; dy < H; dy++) {
|
||||||
float oldy = dy * yscale;
|
float oldy = dy * yscale;
|
||||||
if (oldy >= h())
|
if (oldy >= h())
|
||||||
oldy = (float)(h() - 1);
|
oldy = float(h() - 1);
|
||||||
const float yfract = oldy - (unsigned) oldy;
|
const float yfract = oldy - (unsigned) oldy;
|
||||||
|
|
||||||
for (dx = 0; dx < W; dx++) {
|
for (dx = 0; dx < W; dx++) {
|
||||||
@@ -391,7 +409,7 @@ Fl_Image *Fl_RGB_Image::copy(int W, int H) {
|
|||||||
|
|
||||||
float oldx = dx * xscale;
|
float oldx = dx * xscale;
|
||||||
if (oldx >= w())
|
if (oldx >= w())
|
||||||
oldx = (float)(w() - 1);
|
oldx = float(w() - 1);
|
||||||
const float xfract = oldx - (unsigned) oldx;
|
const float xfract = oldx - (unsigned) oldx;
|
||||||
|
|
||||||
const unsigned leftx = (unsigned)oldx;
|
const unsigned leftx = (unsigned)oldx;
|
||||||
|
|||||||
+5
-6
@@ -1957,8 +1957,10 @@ static HICON image_to_icon(const Fl_RGB_Image *image, bool is_icon,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const uchar *i = (const uchar*)*image->data();
|
const uchar *i = (const uchar*)*image->data();
|
||||||
for (int y = 0;y < image->h();y++) {
|
const int extra_data = image->ld() ? (image->ld()-image->w()*image->d()) : 0;
|
||||||
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()) {
|
switch (image->d()) {
|
||||||
case 1:
|
case 1:
|
||||||
*bits = (0xff<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
|
*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();
|
i += image->d();
|
||||||
bits++;
|
bits++;
|
||||||
}
|
}
|
||||||
i += image->ld();
|
i += extra_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A mask bitmap is still needed even though it isn't used
|
// 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(bitmap);
|
||||||
DeleteObject(mask);
|
DeleteObject(mask);
|
||||||
|
|
||||||
if (icon == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+7
-4
@@ -2612,9 +2612,11 @@ static void icons_to_property(const Fl_RGB_Image *icons[], int count,
|
|||||||
data[1] = image->h();
|
data[1] = image->h();
|
||||||
data += 2;
|
data += 2;
|
||||||
|
|
||||||
|
const int extra_data = image->ld() ? (image->ld()-image->w()*image->d()) : 0;
|
||||||
|
|
||||||
const uchar *in = (const uchar*)*image->data();
|
const uchar *in = (const uchar*)*image->data();
|
||||||
for (int y = 0;y < image->h();y++) {
|
for (int y = 0; y < image->h(); y++) {
|
||||||
for (int x = 0;x < image->w();x++) {
|
for (int x = 0; x < image->w(); x++) {
|
||||||
switch (image->d()) {
|
switch (image->d()) {
|
||||||
case 1:
|
case 1:
|
||||||
*data = ( 0xff<<24) | (in[0]<<16) | (in[0]<<8) | in[0];
|
*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();
|
in += image->d();
|
||||||
data++;
|
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)
|
if (!cursor)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
const int extra_data = image->ld() ? (image->ld()-image->w()*image->d()) : 0;
|
||||||
const uchar *i = (const uchar*)*image->data();
|
const uchar *i = (const uchar*)*image->data();
|
||||||
XcursorPixel *o = cursor->pixels;
|
XcursorPixel *o = cursor->pixels;
|
||||||
for (int y = 0;y < image->h();y++) {
|
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();
|
i += image->d();
|
||||||
o++;
|
o++;
|
||||||
}
|
}
|
||||||
i += image->ld();
|
i += extra_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
cursor->xhot = hotx;
|
cursor->xhot = hotx;
|
||||||
|
|||||||
Reference in New Issue
Block a user