Handle alpha channel in wxImage::Mirror() and GetSubImage() (patch 1469817)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38762 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -250,9 +250,9 @@ wxImage wxImage::Copy() const
|
||||
image.SetMask( M_IMGDATA->m_hasMask );
|
||||
|
||||
memcpy( data, GetData(), M_IMGDATA->m_width*M_IMGDATA->m_height*3 );
|
||||
|
||||
|
||||
wxImageRefData *imgData = (wxImageRefData *)image.m_refData;
|
||||
|
||||
|
||||
// also copy the alpha channel
|
||||
if (HasAlpha())
|
||||
{
|
||||
@@ -260,7 +260,7 @@ wxImage wxImage::Copy() const
|
||||
unsigned char* alpha = image.GetAlpha();
|
||||
memcpy( alpha, GetAlpha(), M_IMGDATA->m_width*M_IMGDATA->m_height );
|
||||
}
|
||||
|
||||
|
||||
// also copy the image options
|
||||
imgData->m_optionNames = M_IMGDATA->m_optionNames;
|
||||
imgData->m_optionValues = M_IMGDATA->m_optionValues;
|
||||
@@ -549,9 +549,16 @@ wxImage wxImage::Mirror( bool horizontally ) const
|
||||
image.Create( M_IMGDATA->m_width, M_IMGDATA->m_height, false );
|
||||
|
||||
unsigned char *data = image.GetData();
|
||||
unsigned char *alpha = NULL;
|
||||
|
||||
wxCHECK_MSG( data, image, wxT("unable to create image") );
|
||||
|
||||
if (M_IMGDATA->m_alpha != NULL) {
|
||||
image.SetAlpha();
|
||||
alpha = image.GetAlpha();
|
||||
wxCHECK_MSG( alpha, image, wxT("unable to create alpha channel") );
|
||||
}
|
||||
|
||||
if (M_IMGDATA->m_hasMask)
|
||||
image.SetMaskColour( M_IMGDATA->m_maskRed, M_IMGDATA->m_maskGreen, M_IMGDATA->m_maskBlue );
|
||||
|
||||
@@ -574,6 +581,25 @@ wxImage wxImage::Mirror( bool horizontally ) const
|
||||
target_data -= 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (alpha != NULL)
|
||||
{
|
||||
// src_alpha starts at the first pixel and increases by 1 after each step
|
||||
// (a step here is the copy of the alpha value of one pixel)
|
||||
const unsigned char *src_alpha = M_IMGDATA->m_alpha;
|
||||
// dest_alpha starts just beyond the first line, decreases before each step,
|
||||
// and after each line is finished, increases by 2 widths (skipping the line
|
||||
// just copied and the line that will be copied next)
|
||||
unsigned char *dest_alpha = alpha + width;
|
||||
|
||||
for (long jj = 0; jj < height; ++jj)
|
||||
{
|
||||
for (long i = 0; i < width; ++i) {
|
||||
*(--dest_alpha) = *(src_alpha++); // copy one pixel
|
||||
}
|
||||
dest_alpha += 2 * width; // advance beyond the end of the next line
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -583,6 +609,23 @@ wxImage wxImage::Mirror( bool horizontally ) const
|
||||
memcpy( target_data, source_data, (size_t)3*width );
|
||||
source_data += 3*width;
|
||||
}
|
||||
|
||||
if (alpha != NULL)
|
||||
{
|
||||
// src_alpha starts at the first pixel and increases by 1 width after each step
|
||||
// (a step here is the copy of the alpha channel of an entire line)
|
||||
const unsigned char *src_alpha = M_IMGDATA->m_alpha;
|
||||
// dest_alpha starts just beyond the last line (beyond the whole image)
|
||||
// and decreases by 1 width before each step
|
||||
unsigned char *dest_alpha = alpha + width * height;
|
||||
|
||||
for (long jj = 0; jj < height; ++jj)
|
||||
{
|
||||
dest_alpha -= width;
|
||||
memcpy( dest_alpha, src_alpha, (size_t)width );
|
||||
src_alpha += width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
@@ -594,32 +637,47 @@ wxImage wxImage::GetSubImage( const wxRect &rect ) const
|
||||
|
||||
wxCHECK_MSG( Ok(), image, wxT("invalid image") );
|
||||
|
||||
wxCHECK_MSG( (rect.GetLeft()>=0) && (rect.GetTop()>=0) && (rect.GetRight()<=GetWidth()) && (rect.GetBottom()<=GetHeight()),
|
||||
wxCHECK_MSG( (rect.GetLeft()>=0) && (rect.GetTop()>=0) &&
|
||||
(rect.GetRight()<=GetWidth()) && (rect.GetBottom()<=GetHeight()),
|
||||
image, wxT("invalid subimage size") );
|
||||
|
||||
int subwidth=rect.GetWidth();
|
||||
const int subheight=rect.GetHeight();
|
||||
const int subwidth = rect.GetWidth();
|
||||
const int subheight = rect.GetHeight();
|
||||
|
||||
image.Create( subwidth, subheight, false );
|
||||
|
||||
unsigned char *subdata = image.GetData(), *data=GetData();
|
||||
const unsigned char *src_data = GetData();
|
||||
const unsigned char *src_alpha = M_IMGDATA->m_alpha;
|
||||
unsigned char *subdata = image.GetData();
|
||||
unsigned char *subalpha = NULL;
|
||||
|
||||
wxCHECK_MSG( subdata, image, wxT("unable to create image") );
|
||||
|
||||
if (src_alpha != NULL) {
|
||||
image.SetAlpha();
|
||||
subalpha = image.GetAlpha();
|
||||
wxCHECK_MSG( subalpha, image, wxT("unable to create alpha channel"));
|
||||
}
|
||||
|
||||
if (M_IMGDATA->m_hasMask)
|
||||
image.SetMaskColour( M_IMGDATA->m_maskRed, M_IMGDATA->m_maskGreen, M_IMGDATA->m_maskBlue );
|
||||
|
||||
const int subleft=3*rect.GetLeft();
|
||||
const int width=3*GetWidth();
|
||||
subwidth*=3;
|
||||
const int width = GetWidth();
|
||||
const int pixsoff = rect.GetLeft() + width * rect.GetTop();
|
||||
|
||||
data+=rect.GetTop()*width+subleft;
|
||||
src_data += 3 * pixsoff;
|
||||
src_alpha += pixsoff; // won't be used if was NULL, so this is ok
|
||||
|
||||
for (long j = 0; j < subheight; ++j)
|
||||
{
|
||||
memcpy( subdata, data, subwidth);
|
||||
subdata+=subwidth;
|
||||
data+=width;
|
||||
memcpy( subdata, src_data, 3 * subwidth );
|
||||
subdata += 3 * subwidth;
|
||||
src_data += 3 * width;
|
||||
if (subalpha != NULL) {
|
||||
memcpy( subalpha, src_alpha, subwidth );
|
||||
subalpha += subwidth;
|
||||
src_alpha += width;
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
|
Reference in New Issue
Block a user