Skip to content

Commit

Permalink
Convert 32 bits icons to 24 bits icons with considering AND map
Browse files Browse the repository at this point in the history
Some 32 bits icons are converted incorrectly. Converting them to 24 bits
icons solve those problems. And considering AND map removes glitches of
background if an icon is inversed when selected.

    modified:   Icon.cpp
    modified:   IconImage.hpp
    modified:   IconMgr.cpp
  • Loading branch information
komh committed Apr 18, 2015
1 parent d92a2e0 commit 932afb6
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 33 deletions.
111 changes: 81 additions & 30 deletions src/Icon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,27 @@

#include "Icon.hpp"

static inline int calcStride(int w, int bpp)
{
int stride;

// Convert pixel to bits
stride = w * bpp;

// Conver to bytes
stride = (stride + 7) / 8;

// Align with 4 bytes boundary
stride = (stride + 3 ) & ~3;

return stride ;
}

static inline int calcImageSize(int w, int h, int bpp)
{
return calcStride(w, bpp) * h;
}

int Os2Icon::ipow(int b, int e){
int p=b;
while(--e)
Expand All @@ -22,42 +43,19 @@ void Os2Icon::setMaskData(PBYTE datos){
memcpy(pMaskData+maskSize,datos,maskSize);
}
ULONG Os2Icon::getSizeImage(){
ULONG ret;

// Convert pixel to bits
ret = ibih->getCx() * ibih->getCBitCount();

// Conver to bytes
ret = (ret + 7) / 8;

// Align with 4 bytes boundary
ret = (ret + 3 ) & ~3;

// Return the image size
return ret * ibih->getCy();
return calcImageSize(ibih->getCx(), ibih->getCy(), ibih->getCBitCount());
}

ULONG Os2Icon::getSizeMaskImage(){
ULONG ret;

// Convert pixel to bits
ret = Mibih->getCx(); // Mask image is 1 bits per pixel

// Conver to bytes
ret = (ret + 7) / 8;

// Align with 4 bytes boundary
ret = (ret + 3 ) & ~3;

// Return the size of mask image which is square
return ret * Mibih->getCx();
// Mask image is square and 1 bpp.
return calcImageSize(Mibih->getCx(), Mibih->getCx(), 1);
}

ULONG Os2Icon::sizePaleta(){
ULONG buffer;
int porte;
int numbits = getIbih()->getCPlanes()*getIbih()->getCBitCount();
if(numbits != 24 && numbits != 32)
if(numbits != 24)
porte = ipow(2,numbits);
else
porte = 0;
Expand Down Expand Up @@ -95,12 +93,63 @@ Os2Icon12::Os2Icon12(IconImage *imagenWin){
bih = new BITMAPINFOHEADER;
pArray = new BITMAPARRAYFILEHEADER;
pHead = new BITMAPFILEHEADER;
int winBpp = imagenWin->getBitsXPixel();
//No configuro la paleta de colores si es un icono de 24 bits
if(imagenWin->getBitsXPixel() != 24 && imagenWin->getBitsXPixel() != 32)
if(winBpp < 24)
convPal(imagenWin->getIcColors(),imagenWin->getNumColores());
setNumBitsColores(imagenWin->getBitsXPixel());
setNumBitsColores(winBpp < 24 ? winBpp : 24);
setPalBW();
setDataImage(imagenWin->getIcXor(),imagenWin->getNumBytes());

PBYTE dataImage = imagenWin->getIcXor();
int numBytes = imagenWin->getNumBytes();
// 32 bpp ? Then convert to 24 bpp
if(winBpp == 32)
{
PBYTE src;
PBYTE dst;
int w = imagenWin->getBitmapHeader()->getBiWidth();
int h = imagenWin->getBitmapHeader()->getBiHeight() / 2;
int srcStride = calcStride(w, 32);
int dstStride = calcStride(w, 24);
int x;
int y;

src = dataImage;
numBytes = dstStride * h;
dataImage = (PBYTE)calloc(numBytes, 1);
dst = dataImage;

for(y = 0; y < h; y++)
{
for(x = 0; x < w; x++)
{
// Consider AND map
if (imagenWin->getIcAndPixel(x, y))
{
*dst++ = 0; src++;
*dst++ = 0; src++;
*dst++ = 0; src++;
}
else
{
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
}

// skip alpha value
src++;
}

// skip remains bytes
src += srcStride - w * 4; // 32 bpp
dst += dstStride - w * 3; // 24 bpp
}
}
setDataImage(dataImage, numBytes);
if(winBpp == 32)
free(dataImage);

setArray();
setDatos(imagenWin);
setXorAnd(imagenWin);
Expand Down Expand Up @@ -144,6 +193,8 @@ int Os2Icon12::setDatos(IconImage *datos){
pHead->bmp.cPlanes =datos->getBitmapHeader()->getBiPlanes();
// pHead->bmp.cBitCount =datos->getBitmapHeader()->getBiBitCount();
pHead->bmp.cBitCount =datos->getBitsXPixel();
if (pHead->bmp.cBitCount == 32)
pHead->bmp.cBitCount = 24;
ibih->setIBIH(&pHead->bmp);
return 0;
}
Expand Down
12 changes: 11 additions & 1 deletion src/IconImage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class IconImage{
icHeader = (BitmapHeader *)pImgData;
//Calculates the number of bytes of this image
numBytesInImg = ((icHeader->getBiHeight()/2)*icHeader->getBiWidth()*icHeader->getBiBitCount())/8;
if(getBitsXPixel() != 24 && getBitsXPixel() != 32){
if(getBitsXPixel() < 24){
icColors = (RgbQuad *)(pImgData + sizeof(BitmapHeader));
icXor = (PBYTE)(pImgData + sizeof(BitmapHeader) + (ipow(2,icHeader->getBiBitCount()) * sizeof(RgbQuad)));
//Set the pointer of the AND mask
Expand All @@ -23,6 +23,8 @@ class IconImage{
}
//Calculates the number of colors of this image
numcolores = ipow(2,icHeader->getBiBitCount()*icHeader->getBiPlanes());
//Calculate the stride of AND map which 1 bpp
andStride = ((icHeader->getBiWidth() + 7) / 8 + 3) & ~3;
}
BitmapHeader* getBitmapHeader(){
return icHeader;
Expand All @@ -36,6 +38,13 @@ class IconImage{
PBYTE getIcAnd(){
return icAnd;
}
int getIcAndPixel(int x, int y) {
// AND map is 1 bpp
int xBytes = x / 8;
int xBit = 7 - (x % 8);

return (*((icAnd + y * andStride) + xBytes ) >> xBit) & 1;
}
int ipow(int b, int e){
int p=b;
while(--e)
Expand Down Expand Up @@ -71,6 +80,7 @@ class IconImage{
PBYTE icAnd;
int numcolores;
int numBytesInImg;
int andStride;
};

#endif
4 changes: 2 additions & 2 deletions src/IconMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ void Os2IconMgr12::grabaIcono(char* nArchivo){
rc = DosWrite(fileHandle,(*i)->getPHead(),sizeof(BITMAPFILEHEADER),&bwrote);
if(rc!=0)
printf("Error al grabar el encabezado del la imagen color\n");
if((*i)->getBitsXPixel() != 24 && (*i)->getBitsXPixel() != 32){
if((*i)->getBitsXPixel() != 24){
rc = DosWrite(fileHandle,(*i)->getPPaletaColor(),(*i)->sizePaleta(),&bwrote);
if(rc!=0)
printf("Error al grabar la paleta de la imagen color\n");
Expand Down Expand Up @@ -442,7 +442,7 @@ PBYTE Os2IconMgr::centerImageData(PBYTE data, const int tamanio, int bits){
PBYTE scanor;
PBYTE scands;
PBYTE retorno;
if(bits==24 || bits==32)
if(bits==24)
ppc=bits/8;
else
ppc=1;
Expand Down

0 comments on commit 932afb6

Please sign in to comment.