mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-21 06:45:39 -06:00
Bazaar:Leptonica - some bug fixes
git-svn-id: svn://ultimatepp.org/upp/trunk@1556 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
05bbc36045
commit
a5ad08c0e1
5 changed files with 551 additions and 397 deletions
|
|
@ -9,6 +9,7 @@ void PixRaster::SetRasterFormat(int page)
|
|||
|
||||
if (IsEmpty())
|
||||
return;
|
||||
|
||||
page = getTruePage(page);
|
||||
|
||||
// removes old format for page
|
||||
|
|
@ -17,11 +18,14 @@ void PixRaster::SetRasterFormat(int page)
|
|||
delete formats[page];
|
||||
formats[page] = NULL;
|
||||
}
|
||||
|
||||
RasterFormat *format = new RasterFormat;
|
||||
|
||||
pix = pixaGetPix(pixa, page, L_CLONE);
|
||||
|
||||
switch (pixGetDepth(pix))
|
||||
{
|
||||
|
||||
case 1:
|
||||
format->Set1mf();
|
||||
break;
|
||||
|
|
@ -68,6 +72,7 @@ void PixRaster::SetRasterFormat(int page)
|
|||
} // switch
|
||||
|
||||
formats[page] = format;
|
||||
|
||||
pixDestroy(&pix);
|
||||
}
|
||||
|
||||
|
|
@ -104,6 +109,7 @@ void PixRaster::CreateGrayPalette2(int page)
|
|||
{
|
||||
if (IsEmpty())
|
||||
return;
|
||||
|
||||
page = getTruePage(page);
|
||||
|
||||
if (localPalettes[page])
|
||||
|
|
@ -111,6 +117,7 @@ void PixRaster::CreateGrayPalette2(int page)
|
|||
delete[] localPalettes[page];
|
||||
localPalettes[page] = NULL;
|
||||
}
|
||||
|
||||
RGBA *pal = new RGBA[2];
|
||||
|
||||
*(dword *)pal = 0xFFFFFFFF;
|
||||
|
|
@ -124,6 +131,7 @@ void PixRaster::CreateGrayPalette4(int page)
|
|||
{
|
||||
if (IsEmpty())
|
||||
return;
|
||||
|
||||
page = getTruePage(page);
|
||||
|
||||
if (localPalettes[page])
|
||||
|
|
@ -131,6 +139,7 @@ void PixRaster::CreateGrayPalette4(int page)
|
|||
delete[] localPalettes[page];
|
||||
localPalettes[page] = NULL;
|
||||
}
|
||||
|
||||
RGBA *pal = new RGBA[4];
|
||||
|
||||
*(dword *)pal = 0xFF0000;
|
||||
|
|
@ -146,6 +155,7 @@ void PixRaster::CreateGrayPalette16(int page)
|
|||
{
|
||||
if (IsEmpty())
|
||||
return;
|
||||
|
||||
page = getTruePage(page);
|
||||
|
||||
if (localPalettes[page])
|
||||
|
|
@ -153,9 +163,11 @@ void PixRaster::CreateGrayPalette16(int page)
|
|||
delete[] localPalettes[page];
|
||||
localPalettes[page] = NULL;
|
||||
}
|
||||
|
||||
RGBA *pal = new RGBA[16];
|
||||
|
||||
dword *palPnt = (dword *)pal;
|
||||
|
||||
for (dword i = 0; i < 16; i++)
|
||||
*palPnt++ = i << 4 | i << 12 | i << 20 | 0xff000000;
|
||||
|
||||
|
|
@ -167,6 +179,7 @@ void PixRaster::CreateGrayPalette256(int page)
|
|||
{
|
||||
if (IsEmpty())
|
||||
return;
|
||||
|
||||
page = getTruePage(page);
|
||||
|
||||
if (localPalettes[page])
|
||||
|
|
@ -174,10 +187,12 @@ void PixRaster::CreateGrayPalette256(int page)
|
|||
delete[] localPalettes[page];
|
||||
localPalettes[page] = NULL;
|
||||
}
|
||||
|
||||
RGBA *pal = new RGBA[256];
|
||||
|
||||
dword *palPnt = (dword *)pal;
|
||||
dword val;
|
||||
|
||||
for (dword i = 0; i < 256; i++)
|
||||
{
|
||||
val = (255 * i) / 255;
|
||||
|
|
@ -197,6 +212,7 @@ void PixRaster::ConvertPIXPalette(PIXCMAP *colormap, int page)
|
|||
|
||||
if (IsEmpty())
|
||||
return;
|
||||
|
||||
page = getTruePage(page);
|
||||
|
||||
if (localPalettes[page])
|
||||
|
|
@ -207,12 +223,15 @@ void PixRaster::ConvertPIXPalette(PIXCMAP *colormap, int page)
|
|||
|
||||
// get number of entries in colormap
|
||||
numColors = pixcmapGetCount(colormap);
|
||||
|
||||
if (numColors > 256)
|
||||
numColors = 256;
|
||||
|
||||
RGBA *pal = new RGBA[numColors];
|
||||
|
||||
// convert and copy it to local palette
|
||||
palPnt = pal;
|
||||
|
||||
for (iColor = 0; iColor < numColors; iColor++)
|
||||
{
|
||||
pixcmapGetColor(colormap, iColor, &rval, &gval, &bval);
|
||||
|
|
@ -235,6 +254,7 @@ void PixRaster::DestroyLocalPalette(int page)
|
|||
|
||||
// gets true page number
|
||||
page = getTruePage(page);
|
||||
|
||||
if (localPalettes[page])
|
||||
{
|
||||
delete[] localPalettes[page];
|
||||
|
|
@ -267,24 +287,36 @@ int PixRaster::getTruePage(int page)
|
|||
// shouldn't happen, but....
|
||||
if (page == PIXRASTER_INVALID_PAGE)
|
||||
NEVER();
|
||||
|
||||
// if empty raster, returns INVALID_PAGE
|
||||
else if(IsEmpty() )
|
||||
else
|
||||
if (IsEmpty() )
|
||||
return 0;
|
||||
|
||||
// special value for current page
|
||||
else if(page == PIXRASTER_CURPAGE)
|
||||
else
|
||||
if (page == PIXRASTER_CURPAGE)
|
||||
return curPage;
|
||||
|
||||
// special value for last page
|
||||
else if(page == PIXRASTER_LASTPAGE)
|
||||
else
|
||||
if (page == PIXRASTER_LASTPAGE)
|
||||
return pixaGetCount(pixa) - 1;
|
||||
|
||||
// negative values mean back offset from last page
|
||||
else if(page < 0)
|
||||
else
|
||||
if (page < 0)
|
||||
{
|
||||
page = pixaGetCount(pixa) - 1 + page;
|
||||
|
||||
if (page < 0)
|
||||
page = 0;
|
||||
|
||||
return page;
|
||||
}
|
||||
else if(page >= pixaGetCount(pixa))
|
||||
|
||||
else
|
||||
if (page >= pixaGetCount(pixa))
|
||||
return pixaGetCount(pixa) - 1;
|
||||
else
|
||||
return page;
|
||||
|
|
@ -309,6 +341,7 @@ int PixRaster::GetPageCount()
|
|||
{
|
||||
if (IsEmpty())
|
||||
return 0;
|
||||
|
||||
return pixaGetCount(pixa);
|
||||
}
|
||||
|
||||
|
|
@ -322,6 +355,7 @@ Size PixRaster::GetSize(int page)
|
|||
Size sz(0, 0);
|
||||
|
||||
// if empty raster, returns a zero size
|
||||
|
||||
if (IsEmpty())
|
||||
return sz;
|
||||
|
||||
|
|
@ -330,8 +364,11 @@ Size PixRaster::GetSize(int page)
|
|||
|
||||
// return size of current page
|
||||
PIX *pix = pixaGetPix(pixa, page, L_CLONE);
|
||||
|
||||
pixGetDimensions(pix, &sz.cx, &sz.cy, NULL);
|
||||
|
||||
pixDestroy(&pix);
|
||||
|
||||
return sz;
|
||||
|
||||
} // END PixRaster::GetSize()
|
||||
|
|
@ -351,14 +388,20 @@ Raster::Info PixRaster::GetInfo(int page)
|
|||
|
||||
// image dimensions from pixel sizes and resolution
|
||||
info.bpp = pixGetDepth(pix);
|
||||
|
||||
int width = pixGetWidth(pix);
|
||||
|
||||
int height = pixGetHeight(pix);
|
||||
|
||||
int xRes = pixGetXRes(pix);
|
||||
|
||||
int yRes = pixGetYRes(pix);
|
||||
|
||||
if (xRes)
|
||||
info.dots.cx = iscale(width, 600, xRes);
|
||||
else
|
||||
info.dots.cx = 0;
|
||||
|
||||
if (yRes)
|
||||
info.dots.cy = iscale(height, 600, yRes);
|
||||
else
|
||||
|
|
@ -374,6 +417,7 @@ Raster::Info PixRaster::GetInfo(int page)
|
|||
info.colors = 1 << pixGetDepth(pix);
|
||||
|
||||
pixDestroy(&pix);
|
||||
|
||||
return info;
|
||||
|
||||
} // END PixRaster::GetInfo()
|
||||
|
|
@ -401,6 +445,7 @@ Raster::Line PixRaster::GetLine(int line, int page)
|
|||
// which don't have an Upp counterpart
|
||||
// as a side problem, for 16 bit grayscaled BPP we must precalculate
|
||||
// both raw and RGBA data
|
||||
|
||||
if (pixGetDepth(pix) == 16)
|
||||
{
|
||||
// we return here an RGBA buffer filled with
|
||||
|
|
@ -417,12 +462,14 @@ Raster::Line PixRaster::GetLine(int line, int page)
|
|||
RGBA *rgbaPtr = rgba;
|
||||
|
||||
l_uint32 *pixPtr = pixGetData(pix) + line * pixGetWpl(pix);
|
||||
|
||||
for (int iPix = 0, mask = 0xFFFF0000, shift = 16; iPix < width; iPix++)
|
||||
{
|
||||
grayVal = ((*pixPtr & mask) >> shift) >> 4;
|
||||
*(dword *)rgbaPtr++ = grayVal | (grayVal << 8) | (grayVal << 16);
|
||||
mask >>= 16;
|
||||
shift -= 16;
|
||||
|
||||
if (!mask)
|
||||
{
|
||||
mask = 0xFFFF0000;
|
||||
|
|
@ -432,6 +479,7 @@ Raster::Line PixRaster::GetLine(int line, int page)
|
|||
}
|
||||
|
||||
pixDestroy(&pix);
|
||||
|
||||
return Raster::Line((byte *)rgba, this, true);
|
||||
}
|
||||
|
||||
|
|
@ -439,11 +487,16 @@ Raster::Line PixRaster::GetLine(int line, int page)
|
|||
// BUT, for LE machines we must re-swap bytes inside words
|
||||
// to reverse the weird Leptonica mechanics
|
||||
int Wpl = pixGetWpl(pix);
|
||||
|
||||
byte *pixData = (byte *)(pixGetData(pix) + line * Wpl);
|
||||
|
||||
#ifdef L_LITTLE_ENDIAN
|
||||
byte *pixPtr = pixData;
|
||||
|
||||
byte *fmtData = new byte[Wpl*4];
|
||||
|
||||
byte *fmtPtr = fmtData;
|
||||
|
||||
for (int iDWord = 0; iDWord < Wpl; iDWord++)
|
||||
{
|
||||
*fmtPtr++ = *(pixPtr + 3);
|
||||
|
|
@ -452,7 +505,9 @@ Raster::Line PixRaster::GetLine(int line, int page)
|
|||
*fmtPtr++ = *(pixPtr + 0);
|
||||
pixPtr += 4;
|
||||
}
|
||||
|
||||
Raster::Line l(fmtData, this, true);
|
||||
|
||||
#else
|
||||
Raster::Line l(pixData, this, false);
|
||||
#endif
|
||||
|
|
@ -469,6 +524,7 @@ int PixRaster::GetPaletteCount(int page)
|
|||
int bpp;
|
||||
|
||||
// no palette on empty image
|
||||
|
||||
if (IsEmpty())
|
||||
return 0;
|
||||
|
||||
|
|
@ -484,6 +540,7 @@ int PixRaster::GetPaletteCount(int page)
|
|||
// we must handle un-paletted PIX grayscale images
|
||||
// so, in that case, we use one of 4 predefined grayscale palettes
|
||||
colormap = pixGetColormap(pix);
|
||||
|
||||
if (!colormap)
|
||||
if (bpp <= 8)
|
||||
palCount = 1 << bpp;
|
||||
|
|
@ -493,6 +550,7 @@ int PixRaster::GetPaletteCount(int page)
|
|||
palCount = pixcmapGetCount(colormap);
|
||||
|
||||
pixDestroy(&pix);
|
||||
|
||||
return palCount;
|
||||
|
||||
} // END PixRaster::GetPaletteCount()
|
||||
|
|
@ -505,6 +563,7 @@ const RGBA *PixRaster::GetPalette(int page)
|
|||
RGBA *palette;
|
||||
|
||||
// no palette on empty image
|
||||
|
||||
if (IsEmpty())
|
||||
return 0;
|
||||
|
||||
|
|
@ -524,10 +583,12 @@ const RGBA *PixRaster::GetPalette(int page)
|
|||
// we must handle un-paletted PIX grayscale images
|
||||
// so, in that case, we use one of 4 predefined grayscale palettes
|
||||
colormap = pixGetColormap(pix);
|
||||
|
||||
if (!colormap || bpp == 1 /* 1bpp PIXs seems not care of colormap.... */)
|
||||
{
|
||||
switch (bpp)
|
||||
{
|
||||
|
||||
case 1:
|
||||
CreateGrayPalette2(page);
|
||||
palette = localPalettes[page];
|
||||
|
|
@ -553,6 +614,7 @@ const RGBA *PixRaster::GetPalette(int page)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// convert PIX palette
|
||||
|
|
@ -561,6 +623,7 @@ const RGBA *PixRaster::GetPalette(int page)
|
|||
}
|
||||
|
||||
pixDestroy(&pix);
|
||||
|
||||
return palette;
|
||||
|
||||
} // END PixRaster::GetPalette()
|
||||
|
|
@ -575,6 +638,7 @@ const RasterFormat *PixRaster::GetFormat(int page)
|
|||
|
||||
if (!IsRasterFormatValid(page))
|
||||
SetRasterFormat(page);
|
||||
|
||||
return formats[page];
|
||||
|
||||
} // END PixRaster::GetFormat()
|
||||
|
|
@ -612,6 +676,7 @@ PixRaster::PixRaster(PIXA *_pixa, CopyModes copyMode)
|
|||
curPage = 0;
|
||||
|
||||
// allocates empty format and local palette
|
||||
|
||||
for (int i = 0; i < pixaGetCount(pixa); i++)
|
||||
{
|
||||
formats.Add((RasterFormat *)NULL);
|
||||
|
|
@ -623,17 +688,25 @@ PixRaster::PixRaster(PIXA *_pixa, CopyModes copyMode)
|
|||
// destructor -- must free PIXA array
|
||||
void PixRaster::Destroy()
|
||||
{
|
||||
if(IsEmpty())
|
||||
return;
|
||||
|
||||
// frees formats and local palettes
|
||||
for (int i = 0; i < pixaGetCount(pixa); i++)
|
||||
{
|
||||
DestroyRasterFormat(i);
|
||||
DestroyLocalPalette(i);
|
||||
}
|
||||
formats.Clear();
|
||||
localPalettes.Clear();
|
||||
|
||||
// frees pix array
|
||||
if (pixa)
|
||||
pixaDestroy(&pixa);
|
||||
|
||||
// sets current page
|
||||
curPage = 0;
|
||||
|
||||
} // END Destructor class PixRaster
|
||||
|
||||
// loads / appends Pix from another raster object
|
||||
|
|
@ -643,6 +716,7 @@ void PixRaster::Load(Raster& raster, bool Append, CopyModes copyMode)
|
|||
|
||||
// if we don't want the array to be appended,
|
||||
// we destroy current array, if any
|
||||
|
||||
if (!Append && pixa)
|
||||
Destroy();
|
||||
|
||||
|
|
@ -655,8 +729,11 @@ void PixRaster::Load(Raster& raster, bool Append, CopyModes copyMode)
|
|||
|
||||
// shortcut if raster is a pixRaster
|
||||
Raster::Info info = raster.GetInfo();
|
||||
|
||||
int width = raster.GetWidth();
|
||||
|
||||
pixRaster = dynamic_cast<PixRaster *>(&raster);
|
||||
|
||||
if (pixRaster)
|
||||
{
|
||||
ASSERT(copyMode == PIXRASTER_COPY || copyMode == PIXRASTER_CLONE);
|
||||
|
|
@ -668,6 +745,7 @@ void PixRaster::Load(Raster& raster, bool Append, CopyModes copyMode)
|
|||
|
||||
// loop for all pages on source raster
|
||||
int oldPage = raster.GetActivePage();
|
||||
|
||||
for (int iPage = 0; iPage < raster.GetPageCount(); iPage++)
|
||||
{
|
||||
PIX *pix;
|
||||
|
|
@ -679,15 +757,18 @@ void PixRaster::Load(Raster& raster, bool Append, CopyModes copyMode)
|
|||
const RasterFormat *format = raster.GetFormat();
|
||||
|
||||
// convert source image to PIX
|
||||
|
||||
if (!format)
|
||||
{
|
||||
// null RasterFormat -- standard Upp RGBA
|
||||
pix = LoadRASTER_RGBA(raster);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
switch (format->GetType())
|
||||
{
|
||||
|
||||
case RASTER_1:
|
||||
pix = LoadRASTER_1(raster);
|
||||
break;
|
||||
|
|
@ -713,11 +794,13 @@ void PixRaster::Load(Raster& raster, bool Append, CopyModes copyMode)
|
|||
break;
|
||||
|
||||
case RASTER_8:
|
||||
|
||||
case RASTER_8 | RASTER_MSBFIRST:
|
||||
pix = LoadRASTER_8(raster);
|
||||
break;
|
||||
|
||||
case RASTER_8ALPHA:
|
||||
|
||||
case RASTER_8ALPHA | RASTER_MSBFIRST:
|
||||
pix = LoadRASTER_8ALPHA(raster);
|
||||
break;
|
||||
|
|
@ -739,13 +822,17 @@ void PixRaster::Load(Raster& raster, bool Append, CopyModes copyMode)
|
|||
break;
|
||||
|
||||
case RASTER_32:
|
||||
|
||||
case RASTER_32ALPHA:
|
||||
|
||||
case RASTER_32PREMULTIPLIED:
|
||||
pix = LoadRASTER_32(raster);
|
||||
break;
|
||||
|
||||
case RASTER_32 | RASTER_MSBFIRST:
|
||||
|
||||
case RASTER_32ALPHA | RASTER_MSBFIRST:
|
||||
|
||||
case RASTER_32PREMULTIPLIED | RASTER_MSBFIRST:
|
||||
pix = LoadRASTER_32_MSBFIRST(raster);
|
||||
break;
|
||||
|
|
@ -756,40 +843,52 @@ void PixRaster::Load(Raster& raster, bool Append, CopyModes copyMode)
|
|||
// if source raster has a palette, create a corresponding
|
||||
// PIXCMAP and fill it
|
||||
const RGBA *palette = raster.GetPalette();
|
||||
|
||||
int palCount = raster.GetPaletteCount(); // needed because of bug of png plugin
|
||||
|
||||
if (palette && palCount)
|
||||
{
|
||||
int bpp = raster.GetInfo().bpp;
|
||||
PIXCMAP *colorTable = pixcmapCreate(bpp);
|
||||
palCount = min(1 << bpp, palCount);
|
||||
|
||||
for (int iPal = 0; iPal < palCount; iPal++)
|
||||
{
|
||||
pixcmapAddColor(colorTable, palette->r, palette->g, palette->b);
|
||||
palette++;
|
||||
}
|
||||
|
||||
pixSetColormap(pix, colorTable);
|
||||
}
|
||||
|
||||
// gets physical resolution from source raster pys dimensions, if any
|
||||
int dotX = raster.GetInfo().dots.cx;
|
||||
|
||||
int dotY = raster.GetInfo().dots.cy;
|
||||
|
||||
int resX, resY;
|
||||
|
||||
if (dotX)
|
||||
resX = iscale(600, raster.GetWidth(), dotX);
|
||||
else
|
||||
resX = 0;
|
||||
|
||||
if (dotY)
|
||||
resY = iscale(600, raster.GetHeight(), dotY);
|
||||
else
|
||||
resY = 0;
|
||||
|
||||
pixSetXRes(pix, resX);
|
||||
|
||||
pixSetYRes(pix, resY);
|
||||
|
||||
// adds the newly loaded PIX to array
|
||||
AddPIX(pix, copyMode);
|
||||
|
||||
pixDestroy(&pix);
|
||||
|
||||
} // for iPage
|
||||
|
||||
raster.SeekPage(oldPage);
|
||||
|
||||
} // END PixRaster::Load()
|
||||
|
|
@ -810,8 +909,10 @@ PIX *PixRaster::GetPIX(int page, CopyModes copyMode)
|
|||
pix = pixaGetPix(pixa, page, L_COPY);
|
||||
else
|
||||
pix = pixaGetPix(pixa, page, L_CLONE);
|
||||
|
||||
if (pix && copyMode == PIXRASTER_REF)
|
||||
pix->refcount--;
|
||||
|
||||
return pix;
|
||||
|
||||
} // END PixRaster::GetPix()
|
||||
|
|
@ -822,17 +923,21 @@ PIXA *PixRaster::GetPIXA(CopyModes copyMode)
|
|||
|
||||
switch (copyMode)
|
||||
{
|
||||
|
||||
case PIXRASTER_REF:
|
||||
return pixa;
|
||||
|
||||
case PIXRASTER_CLONE:
|
||||
|
||||
case PIXRASTER_COPY_CLONE:
|
||||
|
||||
case PIXRASTER_COPY:
|
||||
return pixaCopy(pixa, copyMode);
|
||||
|
||||
default:
|
||||
NEVER();
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
} // END PixRaster::GetPIXA()
|
||||
|
|
@ -847,11 +952,14 @@ void PixRaster::SetPIX(PIX *pix, int page, CopyModes copyMode)
|
|||
|
||||
if (copyMode == PIXRASTER_COPY)
|
||||
pix = pixCopy(NULL, pix);
|
||||
else if(copyMode == PIXRASTER_CLONE)
|
||||
else
|
||||
if (copyMode == PIXRASTER_CLONE)
|
||||
pix = pixClone(pix);
|
||||
|
||||
pixaReplacePix(pixa, page, pix, NULL);
|
||||
|
||||
DestroyLocalPalette(page);
|
||||
|
||||
DestroyRasterFormat(page);
|
||||
|
||||
} // END PixRaster::SetPIX()
|
||||
|
|
@ -869,10 +977,12 @@ void PixRaster::AddPIX(PIX *pix, CopyModes copyMode)
|
|||
{
|
||||
if (!pixa)
|
||||
pixa = pixaCreate(0);
|
||||
|
||||
pixaAddPix(pixa, pix, copyMode);
|
||||
|
||||
// allocates empty format and local palette
|
||||
formats.Add((RasterFormat *)NULL);
|
||||
|
||||
localPalettes.Add((RGBA *)NULL);
|
||||
|
||||
} // END PixRaster::AddPIX()
|
||||
|
|
@ -881,6 +991,7 @@ void PixRaster::AddPIXA(PIXA *_pixa, CopyModes copyMode)
|
|||
{
|
||||
if (!pixa)
|
||||
pixa = pixaCreate(0);
|
||||
|
||||
pixaJoin(pixa, _pixa, 0, 0);
|
||||
|
||||
// allocates empty format and local palette
|
||||
|
|
@ -910,6 +1021,7 @@ void PixRaster::InsertPIX(PIX *pix, int where, CopyModes copyMode)
|
|||
|
||||
// inserts empty format and palette
|
||||
formats.Insert(where, (RasterFormat *)NULL);
|
||||
|
||||
localPalettes.Insert(where, (RGBA *)NULL);
|
||||
|
||||
}
|
||||
|
|
@ -948,12 +1060,15 @@ void PixRaster::RemovePIX(int where, int count)
|
|||
{
|
||||
if (IsEmpty())
|
||||
return;
|
||||
|
||||
if (where == PIXRASTER_END)
|
||||
where = pixaGetCount(pixa) - 1;
|
||||
|
||||
where = getTruePage(where);
|
||||
|
||||
if (pixaGetCount(pixa) - where < count)
|
||||
count = pixaGetCount(pixa) - where;
|
||||
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
pixaRemovePix(pixa, where);
|
||||
|
|
@ -980,15 +1095,161 @@ void PixRaster::Drop(int count)
|
|||
{
|
||||
if (IsEmpty())
|
||||
return;
|
||||
|
||||
int start = pixaGetCount(pixa) - count;
|
||||
|
||||
if (start < 0)
|
||||
{
|
||||
count += start;
|
||||
start = 0;
|
||||
}
|
||||
|
||||
RemovePIX(start, count);
|
||||
|
||||
SeekPage(PIXRASTER_LASTPAGE);
|
||||
|
||||
}
|
||||
|
||||
enum {
|
||||
READ_24_BIT_COLOR = 0, /* read in as 24 (really 32) bit pix */
|
||||
CONVERT_TO_PALETTE = 1, /* convert to 8 bit colormapped pix */
|
||||
READ_GRAY = 2 /* read gray only */
|
||||
};
|
||||
|
||||
// File I/O operations
|
||||
bool PixRaster::Load(FileIn &fs, bool Append)
|
||||
{
|
||||
PIX *pix;
|
||||
int format;
|
||||
#ifdef WIN32
|
||||
HANDLE fh;
|
||||
#else
|
||||
int fh;
|
||||
#endif
|
||||
fh = fs.GetHandle();
|
||||
int iPage;
|
||||
|
||||
if (!fh)
|
||||
return false;
|
||||
FILE *fp = fdopen(fh, "r");
|
||||
if(!fp)
|
||||
return false;
|
||||
|
||||
// if not appending, destroy actual content
|
||||
if(!Append)
|
||||
Destroy();
|
||||
|
||||
pix = NULL;
|
||||
format = findFileFormat(fp);
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case IFF_BMP:
|
||||
if ((pix = pixReadStreamBmp(fp)) == NULL )
|
||||
{
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
pixSetInputFormat(pix, format);
|
||||
AddPIX(pix, PIXRASTER_CLONE);
|
||||
pixDestroy(&pix);
|
||||
break;
|
||||
|
||||
case IFF_JFIF_JPEG:
|
||||
if ((pix = pixReadStreamJpeg(fp, READ_24_BIT_COLOR, 1, NULL, 0)) == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
pixSetInputFormat(pix, format);
|
||||
AddPIX(pix, PIXRASTER_CLONE);
|
||||
pixDestroy(&pix);
|
||||
break;
|
||||
|
||||
case IFF_PNG:
|
||||
if ((pix = pixReadStreamPng(fp)) == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
pixSetInputFormat(pix, format);
|
||||
AddPIX(pix, PIXRASTER_CLONE);
|
||||
pixDestroy(&pix);
|
||||
break;
|
||||
|
||||
case IFF_TIFF:
|
||||
case IFF_TIFF_PACKBITS:
|
||||
case IFF_TIFF_RLE:
|
||||
case IFF_TIFF_G3:
|
||||
case IFF_TIFF_G4:
|
||||
case IFF_TIFF_LZW:
|
||||
case IFF_TIFF_ZIP:
|
||||
// read first page
|
||||
if ((pix = pixReadStreamTiff(fp, 0)) == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
pixSetInputFormat(pix, format);
|
||||
AddPIX(pix, PIXRASTER_CLONE);
|
||||
pixDestroy(&pix);
|
||||
|
||||
// read next pages, if any
|
||||
iPage = 1;
|
||||
while((pix = pixReadStreamTiff(fp, iPage)) != NULL)
|
||||
{
|
||||
pixSetInputFormat(pix, format);
|
||||
AddPIX(pix, PIXRASTER_CLONE);
|
||||
pixDestroy(&pix);
|
||||
iPage++;
|
||||
}
|
||||
break;
|
||||
|
||||
case IFF_PNM:
|
||||
if ((pix = pixReadStreamPnm(fp)) == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
pixSetInputFormat(pix, format);
|
||||
AddPIX(pix, PIXRASTER_CLONE);
|
||||
pixDestroy(&pix);
|
||||
break;
|
||||
|
||||
case IFF_GIF:
|
||||
if ((pix = pixReadStreamGif(fp)) == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
return false;
|
||||
}
|
||||
pixSetInputFormat(pix, format);
|
||||
AddPIX(pix, PIXRASTER_CLONE);
|
||||
pixDestroy(&pix);
|
||||
break;
|
||||
|
||||
case IFF_UNKNOWN:
|
||||
fclose(fp);
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PixRaster::Load(String fileName, bool Append)
|
||||
{
|
||||
FileIn f(fileName);
|
||||
return Load(f, Append);
|
||||
}
|
||||
|
||||
bool PixRaster::Save(String fileName, int page) // @@ to do - add compression and type handling
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool PixRaster::SaveAll(String fileName)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
END_UPP_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -180,9 +180,10 @@ class PixRaster : public Raster
|
|||
void operator+=(Raster &raster) { Load(raster, true, PIXRASTER_COPY); }
|
||||
|
||||
// file I/O
|
||||
void Load(String fileName, bool Append = false);
|
||||
void Save(String fileName, int page = PIXRASTER_CURPAGE); // @@ to do - add compression and type handling
|
||||
void SaveAll(String fileName);
|
||||
bool Load(FileIn &fs, bool Append = false);
|
||||
bool Load(String fileName, bool Append = false);
|
||||
bool Save(String fileName, int page = PIXRASTER_CURPAGE); // @@ to do - add compression and type handling
|
||||
bool SaveAll(String fileName);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////// LEPTONICA OPERATIONS //////////////////////////////////////////
|
||||
|
|
|
|||
|
|
@ -174,22 +174,40 @@ Appends [%-*@3 raster]`'s content at the end of Pixraster`'s one&]
|
|||
[ {{10000F(128)G(128)@1 [s0;%% [* File I/O]]}}&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:PixRaster`:`:Load`(String`,bool`): [@(0.0.255) void]_Load([_^String^ String]_[@3 fileN
|
||||
[s5;:PixRaster`:`:Load`(FileIn`&`,bool`): [@(0.0.255) bool]_Load([_^FileIn^ FileIn]_`&[@3 f
|
||||
s], [@(0.0.255) bool]_[@3 Append]_`=_[@(0.0.255) false])&]
|
||||
[s2;%% Loads images from stream [%-*@3 fs][%- ,] [%-*@3 Append][%- ing them
|
||||
to current PixRaster`'s content if required].&]
|
||||
[s2;%% [* WARNING], it seems that don`'t support 8 bit alpha channel
|
||||
images.&]
|
||||
[s0;%% &]
|
||||
[s2;%% Returns [%-@(0.0.255) true] on success, [%-@(0.0.255) false] otherwise.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:PixRaster`:`:Load`(String`,bool`): [@(0.0.255) bool]_Load([_^String^ String]_[@3 fileN
|
||||
ame], [@(0.0.255) bool]_[@3 Append]_`=_[@(0.0.255) false])&]
|
||||
[s2;%% Loads images from [%-*@3 fileName ][%- named file,] [%-*@3 Append][%- ing
|
||||
them to current PixRaster`'s content if required].&]
|
||||
[s2;%% [* WARNING], it seems that don`'t support 8 bit alpha channel
|
||||
images.&]
|
||||
[s0;%% &]
|
||||
[s2;%% Returns [%-@(0.0.255) true] on success, [%-@(0.0.255) false] otherwise.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:PixRaster`:`:Save`(String`,int`): [@(0.0.255) void]_Save([_^String^ String]_[@3 fileNa
|
||||
[s5;:PixRaster`:`:Save`(String`,int`): [@(0.0.255) bool]_Save([_^String^ String]_[@3 fileNa
|
||||
me], [@(0.0.255) int]_[@3 page]_`=_PIXRASTER`_CURPAGE)&]
|
||||
[s2;%% Stores a single [%-*@3 page ][%- of PixRaster to] [%-*@3 fileName]
|
||||
named file.&]
|
||||
[s0;%% &]
|
||||
[s2;%% Returns [%-@(0.0.255) true] on success, [%-@(0.0.255) false] otherwise.&]
|
||||
[s3;%% &]
|
||||
[s4; &]
|
||||
[s5;:PixRaster`:`:SaveAll`(String`): [@(0.0.255) void]_SaveAll([_^String^ String]_[@3 fileN
|
||||
[s5;:PixRaster`:`:SaveAll`(String`): [@(0.0.255) bool]_SaveAll([_^String^ String]_[@3 fileN
|
||||
ame])&]
|
||||
[s2;%% Stores all pages of PixRaster to a [%-*@3 fileName] named file;
|
||||
choosen file format must support multiple pages.&]
|
||||
[s0;%% &]
|
||||
[s2;%% Returns [%-@(0.0.255) true] on success, [%-@(0.0.255) false] otherwise.&]
|
||||
[s3;%% &]
|
||||
[s0; &]
|
||||
[ {{10000F(128)G(128)@1 [s0;%% [* Page handling functions]]}}&]
|
||||
|
|
|
|||
|
|
@ -2,34 +2,8 @@
|
|||
|
||||
#include <plugin/tif/tif.h>
|
||||
|
||||
void TestLeptonica::onLineRemoval()
|
||||
static void RemoveLines(PixRaster &pixRaster)
|
||||
{
|
||||
String fileName;
|
||||
FileSelector fs;
|
||||
PIX *pix;
|
||||
|
||||
if(!PromptYesNo(
|
||||
"[= [* Line removal demo]&&"
|
||||
"Please select the 'dave-orig.png' image on TestLeptonica folder&"
|
||||
"or some equivalent GrayScale image with horizontal stripes on it&&"
|
||||
"[* CONTINUE ??]]"
|
||||
))
|
||||
return;
|
||||
|
||||
fs.ReadOnlyOption();
|
||||
if(fs.ExecuteOpen("Please select image for line removal:"))
|
||||
{
|
||||
FileIn s;
|
||||
if(!s.Open(~fs))
|
||||
{
|
||||
PromptOK("Error opening image");
|
||||
return;
|
||||
}
|
||||
One<StreamRaster>streamRaster = StreamRaster::OpenAny(s);
|
||||
|
||||
// Loads pixraster from source raster
|
||||
pixRaster.Load(*streamRaster);
|
||||
|
||||
// gets source image page
|
||||
int source = pixRaster.GetActivePage();
|
||||
|
||||
|
|
@ -88,6 +62,42 @@ void TestLeptonica::onLineRemoval()
|
|||
// created before to fill just the stripes and leave the rest of image unchanged
|
||||
CHECKR(pixRaster.CombineMasked(grayAdded, opened2, thresh4), "CombineMasked error");
|
||||
int final = pixRaster.GetActivePage();
|
||||
}
|
||||
|
||||
void TestLeptonica::onLineRemoval()
|
||||
{
|
||||
String fileName;
|
||||
FileSelector fs;
|
||||
PIX *pix;
|
||||
|
||||
if(!PromptYesNo(
|
||||
"[= [* Line removal demo]&&"
|
||||
"Please select the 'dave-orig.png' image on TestLeptonica folder&"
|
||||
"or some equivalent GrayScale image with horizontal stripes on it&&"
|
||||
"[* CONTINUE ??]]"
|
||||
))
|
||||
return;
|
||||
|
||||
fs.ReadOnlyOption();
|
||||
if(fs.ExecuteOpen("Please select image for line removal:"))
|
||||
{
|
||||
FileIn s;
|
||||
if(!s.Open(~fs))
|
||||
{
|
||||
PromptOK("Error opening image");
|
||||
s.Close();
|
||||
return;
|
||||
}
|
||||
// One<StreamRaster>streamRaster = StreamRaster::OpenAny(s);
|
||||
|
||||
// Loads pixraster from source raster
|
||||
CHECKR(pixRaster.Load(s), "Error loading image");
|
||||
s.Close();
|
||||
|
||||
int ctc = pixRaster.GetPaletteCount();
|
||||
|
||||
// apply line removal algothithm
|
||||
RemoveLines(pixRaster);
|
||||
|
||||
// refresh the PixRasterCtrl control with the new image contents
|
||||
pixRasterCtrl.Reload();
|
||||
|
|
|
|||
|
|
@ -1,136 +0,0 @@
|
|||
#include "TestLeptonica.h"
|
||||
|
||||
#include <plugin/tif/tif.h>
|
||||
|
||||
void TestLeptonica::onOpen()
|
||||
{
|
||||
String fileName;
|
||||
FileSelector fs;
|
||||
PIX *pix;
|
||||
|
||||
/*
|
||||
FileIn s;
|
||||
if(!s.Open("/home/massimo/tmp/TestLept2.tif"))
|
||||
{
|
||||
PromptOK("Error creating first image file");
|
||||
return;
|
||||
}
|
||||
One<StreamRaster>streamRaster = StreamRaster::OpenAny(s);
|
||||
|
||||
Raster::Info info = streamRaster->GetInfo();
|
||||
pixRaster.Load(*streamRaster);
|
||||
*/
|
||||
int bpp = 32;
|
||||
int wh = 1024;
|
||||
pix = pixCreate(wh, wh, bpp);
|
||||
memset(pixGetData(pix), 0x0, pixGetHeight(pix)*pixGetWpl(pix)*4);
|
||||
|
||||
/*
|
||||
PIXCMAP *colorMap = pixcmapCreateLinear(bpp, 1 << bpp);
|
||||
pixSetColormap(pix, colorMap);
|
||||
*/
|
||||
/*
|
||||
PIXCMAP *colorMap = pixcmapCreate(bpp);
|
||||
pixcmapAddColor(colorMap, 0x00, 0x00, 0xff);
|
||||
pixcmapAddColor(colorMap, 0xff, 0x00, 0x00);
|
||||
*/
|
||||
|
||||
pixRaster.AddPIX(pix);
|
||||
|
||||
if(bpp < 16)
|
||||
{
|
||||
int thick = wh / (1 << bpp);
|
||||
l_uint32 nColors = 1 << bpp;
|
||||
l_uint32 iColor = 0;
|
||||
int iThick = 0;
|
||||
for(int i = 0; i < wh; i++)
|
||||
{
|
||||
for(int j = 0; j < wh; j++)
|
||||
{
|
||||
pixSetPixel(pix, i, j, iColor);
|
||||
pixSetPixel(pix, j, i, iColor);
|
||||
}
|
||||
iThick++;
|
||||
if(iThick >= thick)
|
||||
{
|
||||
iThick = 0;
|
||||
iColor++;
|
||||
}
|
||||
}
|
||||
} // if bpp < 16
|
||||
else
|
||||
{
|
||||
l_uint32 r = 0, g = 0, b = 0;
|
||||
for(int y = 0; y < wh; y++)
|
||||
{
|
||||
for(int x = 0; x < wh; x++)
|
||||
{
|
||||
r = x * 256 / wh;
|
||||
g = y * 256 / wh;
|
||||
b = sqrt((x * 256 / wh) * (y * 256 / wh));
|
||||
pixSetPixel(pix, x, y, (r << 24) | (g << 16) | (b << 8));
|
||||
}
|
||||
}
|
||||
r = b;
|
||||
}
|
||||
pixDestroy(&pix);
|
||||
|
||||
int width = pixRaster.GetWidth();
|
||||
pix = pixRaster;
|
||||
pixWrite("/home/massimo/tmp/TestLeptOut.tif", pix, IFF_TIFF);
|
||||
FileOut of;
|
||||
if(!of.Open("/home/massimo/tmp/TestLeptOut2.tif"))
|
||||
{
|
||||
PromptOK("Error creating second image file");
|
||||
return;
|
||||
}
|
||||
TIFEncoder enc(pixRaster.GetInfo().bpp);
|
||||
enc.SetStream(of);
|
||||
enc.Create(pixRaster.GetSize(), pixRaster);
|
||||
enc.SetDots(Size(1024,1024));
|
||||
const RGBA *pal = enc.GetPalette();
|
||||
enc.Save(of, pixRaster);
|
||||
int pc = enc.GetPaletteCount();
|
||||
|
||||
return;
|
||||
|
||||
|
||||
/*
|
||||
fs.ReadOnlyOption();
|
||||
if(fs.ExecuteOpen("Please select a graphic file to view:"))
|
||||
{
|
||||
FileIn s;
|
||||
if(!s.Open(~fs))
|
||||
{
|
||||
PromptOK("Error opening image");
|
||||
return;
|
||||
}
|
||||
One<StreamRaster>streamRaster = StreamRaster::OpenAny(s);
|
||||
pixRaster.Load(*streamRaster);
|
||||
PIX *pix = pixRaster;
|
||||
pixWrite("/home/massimo/out.tif", pix, IFF_UNKNOWN);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
void TestLeptonica::onQuit()
|
||||
{
|
||||
Break();
|
||||
}
|
||||
|
||||
TestLeptonica::TestLeptonica()
|
||||
{
|
||||
CtrlLayout(*this, "Window title");
|
||||
|
||||
// connects button handlers
|
||||
OpenButton <<= THISBACK(onOpen);
|
||||
QuitButton <<= THISBACK(onQuit);
|
||||
}
|
||||
|
||||
GUI_APP_MAIN
|
||||
{
|
||||
TestLeptonica testLept;
|
||||
|
||||
testLept.Run();
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue