ultimatepp/bazaar/PixRaster/PixRasterLoad.cpp
micio 51d82b5bad Bazaar:Leptonica - Code restructuration
git-svn-id: svn://ultimatepp.org/upp/trunk@1570 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2009-09-13 09:39:14 +00:00

540 lines
13 KiB
C++

#include "PixRaster.h"
NAMESPACE_UPP
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// MACROS USED TO CORRECTLY HANDLE ENDIANNESS OF THE MACHINE
#ifdef L_BIG_ENDIAN
#define SHIFT_START 0
#define SHIFT_CHECK(shift) (shift > 24)
#define SHIFT_STEP(shift) shift += 8
#else
#define SHIFT_START 24
#define SHIFT_CHECK(shift) (shift < 0)
#define SHIFT_STEP(shift) shift -= 8
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TRANSFER A BYTE
static inline byte ReverseByte(byte sb)
{
byte db = 0;
if(sb & 0x01) db |= 0x80;
if(sb & 0x02) db |= 0x40;
if(sb & 0x04) db |= 0x20;
if(sb & 0x08) db |= 0x10;
if(sb & 0x10) db |= 0x08;
if(sb & 0x20) db |= 0x04;
if(sb & 0x40) db |= 0x02;
if(sb & 0x80) db |= 0x01;
return db;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// transfers a byte line -- straight bit order
static void TransferLine_STRAIGHT(const byte *rasPnt, l_uint32 *pixPnt, int nBytes)
{
l_uint32 w;
short shift;
for(int iByte = 0, shift = SHIFT_START, w = 0; iByte < nBytes; iByte++)
{
l_uint32 u = *rasPnt++/* ^ 0xff*/;
w |= u << shift;
// w |= ((l_uint32)*rasPnt++) << shift;
SHIFT_STEP(shift);
if(SHIFT_CHECK(shift))
{
*pixPnt++ = w;
w = 0;
shift = SHIFT_START;
}
}
if(shift != SHIFT_START)
*pixPnt = w;
} // END TransferLine_STRAIGHT()
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// transfers a byte line -- reverse bit order
static void TransferLine_REVERSE(const byte *rasPnt, l_uint32 *pixPnt, int nBytes)
{
l_uint32 w;
short shift;
for(int iByte = 0, shift = SHIFT_START, w = 0; iByte < nBytes; iByte++)
{
byte sb = *rasPnt++;
byte db = 0;
if(sb & 0x01) db |= 0x80;
if(sb & 0x02) db |= 0x40;
if(sb & 0x04) db |= 0x20;
if(sb & 0x08) db |= 0x10;
if(sb & 0x10) db |= 0x08;
if(sb & 0x20) db |= 0x04;
if(sb & 0x40) db |= 0x02;
if(sb & 0x80) db |= 0x01;
w |= ((l_uint32)*rasPnt++) << shift;
SHIFT_STEP(shift);
if(SHIFT_CHECK(shift))
{
*pixPnt++ = w;
w = 0;
shift = SHIFT_START;
}
}
if(shift != SHIFT_START)
*pixPnt = w;
} // END TransferLine_REVERSE()
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// raster loading/conversion routines
bool Pix::LoadRASTER_RGBA(Raster &raster)
{
Destroy();
} // END Pix::LoadRASTER_RGBA()
bool Pix::LoadRASTER_1(Raster &raster)
{
Destroy();
// get source Raster dimensions
int width = raster.GetWidth();
int height = raster.GetHeight();
// create the PIX
pix = pixCreateNoInit(width, height, 1);
if(!pix)
return false;
// get PIX width (in words) and pix data pointer
int wpl = pixGetWpl(pix);
l_uint32 *pixLine = pixGetData(pix);
// number of bytes on each source line (full or partial)
// as PIX is padded to 32 bit words, we don't bother to
// get the exact end of source raster -- we transfer full bytes
// BUT, we must operate on full words on dest data, because of
// byte swapping done by Leptonica on le machines.....
int nBytes = (width + 7) / 8;
// transfer all scanlines
for(int iLine = 0; iLine < height; iLine++)
{
// transfers the line
TransferLine_REVERSE(raster.GetLine(iLine).GetRawData(), pixLine, nBytes);
// next dest line
pixLine += wpl;
}
return true;
} // END Pix::LoadRASTER_1()
bool Pix::LoadRASTER_1_MSBFIRST(Raster &raster)
{
Destroy();
// get source Rastet dimensions
int width = raster.GetWidth();
int height = raster.GetHeight();
// create the PIX
pix = pixCreateNoInit(width, height, 1);
if(!pix)
return false;
// get PIX width (in words) and pix data pointer
int wpl = pixGetWpl(pix);
l_uint32 *pixLine = pixGetData(pix);
// number of bytes on each source line (full or partial)
// as PIX is padded to 32 bit words, we don't bother to
// get the exact end of source raster -- we transfer full bytes
// BUT, we must operate on full words on dest data, because of
// byte swapping done by Leptonica on le machines.....
int nBytes = (width + 7) / 8;
// transfer all scanlines
for(int iLine = 0; iLine < height; iLine++)
{
// transfers the line
TransferLine_STRAIGHT(raster.GetLine(iLine).GetRawData(), pixLine, nBytes);
// next dest line
pixLine += wpl;
}
return true;
} // END Pix::LoadRASTER_1_MSBFIRST()
bool Pix::LoadRASTER_2(Raster &raster)
{
Destroy();
// get source Raster dimensions
int width = raster.GetWidth();
int height = raster.GetHeight();
// create the PIX
pix = pixCreateNoInit(width, height,2);
if(!pix)
return false;
// get PIX width (in words) and pix data pointer
int wpl = pixGetWpl(pix);
l_uint32 *pixLine = pixGetData(pix);
// number of bytes on each source line (full or partial)
// as PIX is padded to 32 bit words, we don't bother to
// get the exact end of source raster -- we transfer full bytes
// BUT, we must operate on full words on dest data, because of
// byte swapping done by Leptonica on le machines.....
int nBytes = (width + 3) / 4;
// transfer all scanlines
for(int iLine = 0; iLine < height; iLine++)
{
// transfers the line
TransferLine_REVERSE(raster.GetLine(iLine).GetRawData(), pixLine, nBytes);
// next dest line
pixLine += wpl;
}
return true;
} // END Pix::LoadRASTER_2()
bool Pix::LoadRASTER_2_MSBFIRST(Raster &raster)
{
Destroy();
// get source Rastet dimensions
int width = raster.GetWidth();
int height = raster.GetHeight();
// create the PIX
pix = pixCreateNoInit(width, height, 2);
if(!pix)
return false;
// get PIX width (in words) and pix data pointer
int wpl = pixGetWpl(pix);
l_uint32 *pixLine = pixGetData(pix);
// number of bytes on each source line (full or partial)
// as PIX is padded to 32 bit words, we don't bother to
// get the exact end of source raster -- we transfer full bytes
// BUT, we must operate on full words on dest data, because of
// byte swapping done by Leptonica on le machines.....
int nBytes = (width + 3) / 4;
// transfer all scanlines
for(int iLine = 0; iLine < height; iLine++)
{
// transfers the line
TransferLine_STRAIGHT(raster.GetLine(iLine).GetRawData(), pixLine, nBytes);
// next dest line
pixLine += wpl;
}
return true;
} // END Pix::LoadRASTER_2()
bool Pix::LoadRASTER_4(Raster &raster)
{
Destroy();
// get source Raster dimensions
int width = raster.GetWidth();
int height = raster.GetHeight();
// create the PIX
pix = pixCreateNoInit(width, height, 4);
if(!pix)
return false;
// get PIX width (in words) and pix data pointer
int wpl = pixGetWpl(pix);
l_uint32 *pixLine = pixGetData(pix);
// number of bytes on each source line (full or partial)
// as PIX is padded to 32 bit words, we don't bother to
// get the exact end of source raster -- we transfer full bytes
// BUT, we must operate on full words on dest data, because of
// byte swapping done by Leptonica on le machines.....
int nBytes = (width + 1) / 2;
// transfer all scanlines
for(int iLine = 0; iLine < height; iLine++)
{
// transfers the line
TransferLine_REVERSE(raster.GetLine(iLine).GetRawData(), pixLine, nBytes);
// next dest line
pixLine += wpl;
}
return true;
} // END Pix::LoadRASTER_4()
bool Pix::LoadRASTER_4_MSBFIRST(Raster &raster)
{
Destroy();
// get source Rastet dimensions
int width = raster.GetWidth();
int height = raster.GetHeight();
// create the PIX
pix = pixCreateNoInit(width, height, 4);
if(!pix)
return false;
// get PIX width (in words) and pix data pointer
int wpl = pixGetWpl(pix);
l_uint32 *pixLine = pixGetData(pix);
// number of bytes on each source line (full or partial)
// as PIX is padded to 32 bit words, we don't bother to
// get the exact end of source raster -- we transfer full bytes
// BUT, we must operate on full words on dest data, because of
// byte swapping done by Leptonica on le machines.....
int nBytes = (width + 1) / 2;
// transfer all scanlines
for(int iLine = 0; iLine < height; iLine++)
{
// transfers the line
Raster::Line line = raster.GetLine(iLine);
const byte *data = line.GetRawData();
TransferLine_STRAIGHT(line.GetRawData(), pixLine, nBytes);
// TransferLine_STRAIGHT(raster.GetLine(iLine).GetRawData(), pixLine, nBytes);
// next dest line
pixLine += wpl;
}
return true;
} // END Pix::LoadRASTER_4()
bool Pix::LoadRASTER_8(Raster &raster)
{
Destroy();
// get source Rastet dimensions
int width = raster.GetWidth();
int height = raster.GetHeight();
// create the PIX
pix = pixCreateNoInit(width, height, 8);
if(!pix)
return false;
// get PIX width (in words) and pix data pointer
int wpl = pixGetWpl(pix);
l_uint32 *pixLine = pixGetData(pix);
// number of bytes on each source line (full or partial)
// as PIX is padded to 32 bit words, we don't bother to
// get the exact end of source raster -- we transfer full bytes
// BUT, we must operate on full words on dest data, because of
// byte swapping done by Leptonica on le machines.....
int nBytes = width;
// transfer all scanlines
for(int iLine = 0; iLine < height; iLine++)
{
// transfers the line
Raster::Line line = raster.GetLine(iLine);
const byte *b = line.GetRawData();
TransferLine_STRAIGHT(line.GetRawData(), pixLine, nBytes);
// TransferLine_STRAIGHT(raster.GetLine(iLine).GetRawData(), pixLine, nBytes);
// next dest line
pixLine += wpl;
}
return true;
} // END Pix::LoadRASTER_8()
bool Pix::LoadRASTER_8ALPHA(Raster &raster)
{
Destroy();
Cerr() << "Upp Leptonica library : 8 bpp with alpha channel still not supported";
NEVER();
} // END Pix::LoadRASTER_8ALPHA()
bool Pix::LoadRASTER_16(Raster &raster)
{
Destroy();
Cerr() << "Upp Leptonica library : 16 bpp still not supported";
NEVER();
} // END Pix::LoadRASTER_16()
bool Pix::LoadRASTER_16_MSBFIRST(Raster &raster)
{
Destroy();
Cerr() << "Upp Leptonica library : 16 bpp still not supported";
NEVER();
} // END Pix::LoadRASTER_16()
bool Pix::LoadRASTER_24(Raster &raster)
{
Destroy();
// get source Rastet dimensions
int width = raster.GetWidth();
int height = raster.GetHeight();
// create the PIX
pix = pixCreateNoInit(width, height, 32);
if(!pix)
return false;
// get PIX width (in bytes) and pix data pointer
int wpl = pixGetWpl(pix);
l_uint32 *pixLine = pixGetData(pix);
// transfer all scanlines
for(int iLine = 0; iLine < height; iLine++)
{
Raster::Line line = raster.GetLine(iLine);
const RGBA *rasPtr = line.GetRGBA();
// const RGBA *rasPtr = raster.GetLine(iLine).GetRGBA();
l_uint32 *pixPtr = pixLine;
for(int iDWord = 0; iDWord < wpl; iDWord++)
{
l_uint32 w = 0;
w |= rasPtr->r << 24;
w |= rasPtr->g << 16;
w |= rasPtr->b << 8;
w |= rasPtr->a << 0;
*pixPtr++ = w;
rasPtr++;
}
// next dest line
pixLine += wpl;
}
return true;
} // END Pix::LoadRASTER_24()
bool Pix::LoadRASTER_24_MSBFIRST(Raster &raster)
{
Destroy();
// get source Rastet dimensions
int width = raster.GetWidth();
int height = raster.GetHeight();
// create the PIX
pix = pixCreateNoInit(width, height, 24);
if(!pix)
return false;
// get PIX width (in bytes) and pix data pointer
int wpl = pixGetWpl(pix);
int nBytes = wpl * 4;
l_uint32 *pixLine = pixGetData(pix);
// transfer all scanlines
for(int iLine = 0; iLine < height; iLine++)
{
// transfers the line
memmove(pixLine, raster.GetLine(iLine).GetRGBA(), nBytes);
// next dest line
pixLine += wpl;
}
return true;
} // END Pix::LoadRASTER_24()
bool Pix::LoadRASTER_32(Raster &raster)
{
Destroy();
// get source Rastet dimensions
int width = raster.GetWidth();
int height = raster.GetHeight();
// create the PIX
pix = pixCreateNoInit(width, height, 32);
if(!pix)
return false;
// get PIX width (in bytes) and pix data pointer
int wpl = pixGetWpl(pix);
int nBytes = wpl * 4;
l_uint32 *pixLine = pixGetData(pix);
// transfer all scanlines
for(int iLine = 0; iLine < height; iLine++)
{
byte *rasPtr = (byte *)raster.GetLine(iLine).GetRGBA();
l_uint32 *pixPtr = pixLine;
for(int iWord = 0; iWord < wpl; iWord++)
{
l_uint32 w = 0;
w |= ((dword)(*(rasPtr + 0))) << 24;
w |= ((dword)(*(rasPtr + 1))) << 16;
w |= ((dword)(*(rasPtr + 2))) << 8;
w |= ((dword)(*(rasPtr + 3))) << 0;
*pixLine++ = w;
rasPtr += 4;
}
// next dest line
pixLine += wpl;
}
return true;
} // END Pix::LoadRASTER_32()
bool Pix::LoadRASTER_32_MSBFIRST(Raster &raster)
{
Destroy();
// get source Rastet dimensions
int width = raster.GetWidth();
int height = raster.GetHeight();
// create the PIX
pix = pixCreateNoInit(width, height, 32);
if(!pix)
return false;
// get PIX width (in bytes) and pix data pointer
int wpl = pixGetWpl(pix);
int nBytes = wpl * 4;
l_uint32 *pixLine = pixGetData(pix);
// transfer all scanlines
for(int iLine = 0; iLine < height; iLine++)
{
// transfers the line
memmove(pixLine, raster.GetLine(iLine).GetRGBA(), nBytes);
// next dest line
pixLine += wpl;
}
return true;
} // END Pix::LoadRASTER_32()
END_UPP_NAMESPACE