diff --git a/bazaar/PixRaster/PixRaster.cpp b/bazaar/PixRaster/PixRaster.cpp index ee4dd40b2..182287f57 100644 --- a/bazaar/PixRaster/PixRaster.cpp +++ b/bazaar/PixRaster/PixRaster.cpp @@ -6,38 +6,42 @@ NAMESPACE_UPP void PixRaster::SetRasterFormat(int page) { PIX *pix; - - if(IsEmpty()) + + if (IsEmpty()) return; + page = getTruePage(page); - + // removes old format for page - if(formats[page]) + if (formats[page]) { delete formats[page]; formats[page] = NULL; } + RasterFormat *format = new RasterFormat; - + pix = pixaGetPix(pixa, page, L_CLONE); - switch(pixGetDepth(pix)) + + switch (pixGetDepth(pix)) { + case 1: format->Set1mf(); break; - + case 2: format->Set2mf(); break; - + case 4: format->Set4mf(); break; - + case 8: format->Set8(); break; - + case 16: // Upp does 16bpp color, Leptonica does 16bpp grayscale // MakeRGBA() will fail converting from Leptonica format anyways @@ -49,7 +53,7 @@ void PixRaster::SetRasterFormat(int page) 0x000000FF << L_BLUE_SHIFT ); break; - + case 24: format->Set24be( 0x000000FF << L_RED_SHIFT, @@ -57,7 +61,7 @@ void PixRaster::SetRasterFormat(int page) 0x000000FF << L_BLUE_SHIFT ); break; - + case 32: format->Set32be( 0x000000FF << L_RED_SHIFT, @@ -66,140 +70,152 @@ void PixRaster::SetRasterFormat(int page) ); break; } // switch - + formats[page] = format; + pixDestroy(&pix); } // checks wether page format is valid bool PixRaster::IsRasterFormatValid(int page) { - if(IsEmpty()) + if (IsEmpty()) return false; // gets true page number page = getTruePage(page); - + return (formats[page] != NULL); } - + // destroys page format void PixRaster::DestroyRasterFormat(int page) { - if(IsEmpty()) + if (IsEmpty()) return; // gets true page number page = getTruePage(page); - - if(formats[page]) + + if (formats[page]) { delete formats[page]; formats[page] = NULL; } } - + // synthesyze grayscale palettes void PixRaster::CreateGrayPalette2(int page) { - if(IsEmpty()) + if (IsEmpty()) return; + page = getTruePage(page); - - if(localPalettes[page]) + + if (localPalettes[page]) { delete[] localPalettes[page]; localPalettes[page] = NULL; } + RGBA *pal = new RGBA[2]; - + *(dword *)pal = 0xFFFFFFFF; *((dword *)pal + 1) = 0xFF000000; - + localPalettes[page] = pal; - + } // END PixRaster::CreateGrayPalette2() void PixRaster::CreateGrayPalette4(int page) { - if(IsEmpty()) + if (IsEmpty()) return; + page = getTruePage(page); - - if(localPalettes[page]) + + if (localPalettes[page]) { delete[] localPalettes[page]; localPalettes[page] = NULL; } + RGBA *pal = new RGBA[4]; *(dword *)pal = 0xFF0000; *((dword *)pal + 1) = 0xFF555555; *((dword *)pal + 2) = 0xFFAAAAAA; *((dword *)pal + 3) = 0xFFFFFFFF; - + localPalettes[page] = pal; - + } // END PixRaster::CreateGrayPalette4() void PixRaster::CreateGrayPalette16(int page) { - if(IsEmpty()) + if (IsEmpty()) return; + page = getTruePage(page); - - if(localPalettes[page]) + + if (localPalettes[page]) { delete[] localPalettes[page]; localPalettes[page] = NULL; } + RGBA *pal = new RGBA[16]; dword *palPnt = (dword *)pal; - for(dword i = 0; i < 16; i++) + + for (dword i = 0; i < 16; i++) *palPnt++ = i << 4 | i << 12 | i << 20 | 0xff000000; - + localPalettes[page] = pal; - + } // END PixRaster::CreateGrayPalette16() void PixRaster::CreateGrayPalette256(int page) { - if(IsEmpty()) + if (IsEmpty()) return; + page = getTruePage(page); - - if(localPalettes[page]) + + if (localPalettes[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++) + + for (dword i = 0; i < 256; i++) { - val = (255 * i) / 255; + val = (255 * i) / 255; *palPnt++ = val | val << 8 | val << 16 | 0xff000000; } - + localPalettes[page] = pal; - + } // END PixRaster::CreateGrayPalette256() - + // convert PIX palette void PixRaster::ConvertPIXPalette(PIXCMAP *colormap, int page) { int iColor, numColors; l_int32 rval, gval, bval; RGBA *palPnt; - - if(IsEmpty()) + + if (IsEmpty()) return; + page = getTruePage(page); - - if(localPalettes[page]) + + if (localPalettes[page]) { delete[] localPalettes[page]; localPalettes[page] = NULL; @@ -207,12 +223,15 @@ void PixRaster::ConvertPIXPalette(PIXCMAP *colormap, int page) // get number of entries in colormap numColors = pixcmapGetCount(colormap); - if(numColors > 256) + + 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); @@ -222,20 +241,21 @@ void PixRaster::ConvertPIXPalette(PIXCMAP *colormap, int page) palPnt->b = (byte)bval; palPnt++; } - + localPalettes[page] = pal; - + } // END PixRaster::ConvertPIXPalette() // destroys local palette void PixRaster::DestroyLocalPalette(int page) { - if(IsEmpty()) + if (IsEmpty()) return; // gets true page number page = getTruePage(page); - if(localPalettes[page]) + + if (localPalettes[page]) { delete[] localPalettes[page]; localPalettes[page] = NULL; @@ -245,12 +265,12 @@ void PixRaster::DestroyLocalPalette(int page) // checks wether local palette is valid bool PixRaster::IsLocalPaletteValid(int page) { - if(IsEmpty()) + if (IsEmpty()) return false; // gets true page number page = getTruePage(page); - + return (localPalettes[page] != NULL); } @@ -259,56 +279,69 @@ bool PixRaster::IsEmpty() { return (!pixa || !pixaGetCount(pixa)); } - + // gets real page int PixRaster::getTruePage(int page) { // if error page, throw exception // shouldn't happen, but.... - if(page == PIXRASTER_INVALID_PAGE) + if (page == PIXRASTER_INVALID_PAGE) NEVER(); + // if empty raster, returns INVALID_PAGE - else if(IsEmpty() ) - return 0; - // special value for current page - else if(page == PIXRASTER_CURPAGE) - return curPage; - // special value for last page - else if(page == PIXRASTER_LASTPAGE) - return pixaGetCount(pixa) - 1; - // negative values mean back offset from last page - else if(page < 0) - { - page = pixaGetCount(pixa) - 1 + page; - if(page < 0) - page = 0; - return page; - } - else if(page >= pixaGetCount(pixa)) - return pixaGetCount(pixa) - 1; else - return page; + if (IsEmpty() ) + return 0; + + // special value for current page + else + if (page == PIXRASTER_CURPAGE) + return curPage; + + // special value for last page + else + if (page == PIXRASTER_LASTPAGE) + return pixaGetCount(pixa) - 1; + + // negative values mean back offset from last page + else + if (page < 0) + { + page = pixaGetCount(pixa) - 1 + page; + + if (page < 0) + page = 0; + + return page; + } + + else + if (page >= pixaGetCount(pixa)) + return pixaGetCount(pixa) - 1; + else + return page; } - + void PixRaster::SeekPage(int page) { - if(IsEmpty()) + if (IsEmpty()) return; // gets true page number page = getTruePage(page); - if(page == curPage) + if (page == curPage) return; - curPage = page; + curPage = page; } int PixRaster::GetPageCount() { - if(IsEmpty()) + if (IsEmpty()) return 0; + return pixaGetCount(pixa); } @@ -322,18 +355,22 @@ Size PixRaster::GetSize(int page) Size sz(0, 0); // if empty raster, returns a zero size - if(IsEmpty()) + + if (IsEmpty()) return sz; - + // gets true page number page = getTruePage(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() Raster::Info PixRaster::GetInfo(int page) @@ -341,39 +378,46 @@ Raster::Info PixRaster::GetInfo(int page) Raster::Info info; memset(&info, sizeof(info), 0); - if(IsEmpty()) + if (IsEmpty()) return info; // gets true page number page = getTruePage(page); - + PIX *pix = pixaGetPix(pixa, page, L_CLONE); // 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) + + if (xRes) info.dots.cx = iscale(width, 600, xRes); else info.dots.cx = 0; - if(yRes) + + if (yRes) info.dots.cy = iscale(height, 600, yRes); else info.dots.cy = 0; - + // image kind -- Leptonica just handles opaque images info.kind = IMAGE_OPAQUE; - + // number of colors - if(pixGetColormap(pix)) + if (pixGetColormap(pix)) info.colors = pixcmapGetCount(pixGetColormap(pix)); else info.colors = 1 << pixGetDepth(pix); - + pixDestroy(&pix); + return info; } // END PixRaster::GetInfo() @@ -381,27 +425,28 @@ Raster::Info PixRaster::GetInfo(int page) Raster::Line PixRaster::GetLine(int line, int page) { // empty line on empty image - if(IsEmpty()) + if (IsEmpty()) return Raster::Line(); // gets true page number page = getTruePage(page); - + // gets current PIX handle PIX *pix = pixaGetPix(pixa, page, L_CLONE); - + // if line out of bounds, return empty line - if(line < 0 || line >= pixGetHeight(pix)) + if (line < 0 || line >= pixGetHeight(pix)) { pixDestroy(&pix); return Raster::Line(); } - + // gets PIX bpp -- we must handle special case for 16bpp grayscale // 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) + + if (pixGetDepth(pix) == 16) { // we return here an RGBA buffer filled with // MSBs from PIX @@ -411,27 +456,30 @@ Raster::Line PixRaster::GetLine(int line, int page) // gets image width int width = pixGetWidth(pix); - + // allocates an RGBA buffer for data RGBA *rgba = new RGBA[width]; RGBA *rgbaPtr = rgba; - + l_uint32 *pixPtr = pixGetData(pix) + line * pixGetWpl(pix); - for(int iPix = 0, mask = 0xFFFF0000, shift = 16; iPix < width; iPix++) + + 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) + + if (!mask) { mask = 0xFFFF0000; shift = 16; pixPtr++; } - } - + } + pixDestroy(&pix); + return Raster::Line((byte *)rgba, this, true); } @@ -439,12 +487,17 @@ 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++) + + for (int iDWord = 0; iDWord < Wpl; iDWord++) { *fmtPtr++ = *(pixPtr + 3); *fmtPtr++ = *(pixPtr + 2); @@ -452,13 +505,15 @@ 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 pixDestroy(&pix); return l; - + } // END PixRaster::GetLine() int PixRaster::GetPaletteCount(int page) @@ -467,34 +522,37 @@ int PixRaster::GetPaletteCount(int page) PIXCMAP *colormap; int palCount; int bpp; - + // no palette on empty image - if(IsEmpty()) + + if (IsEmpty()) return 0; // gets true page number page = getTruePage(page); - + // gets current PIX handle pix = pixaGetPix(pixa, page, L_CLONE); - + // get current pix's depth bpp = pixGetDepth(pix); - + // 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) + + if (!colormap) + if (bpp <= 8) palCount = 1 << bpp; else palCount = 0; else palCount = pixcmapGetCount(colormap); - + pixDestroy(&pix); + return palCount; - + } // END PixRaster::GetPaletteCount() const RGBA *PixRaster::GetPalette(int page) @@ -503,31 +561,34 @@ const RGBA *PixRaster::GetPalette(int page) PIXCMAP *colormap; int bpp; RGBA *palette; - + // no palette on empty image - if(IsEmpty()) + + if (IsEmpty()) return 0; - + // gets true page number page = getTruePage(page); - + // if palette is up to date, just return it - if(IsLocalPaletteValid(page)) + if (IsLocalPaletteValid(page)) return localPalettes[page]; - + // gets current PIX handle pix = pixaGetPix(pixa, page, L_CLONE); - + // get current pix's depth bpp = pixGetDepth(pix); - + // 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.... */) + + if (!colormap || bpp == 1 /* 1bpp PIXs seems not care of colormap.... */) { - switch(bpp) + switch (bpp) { + case 1: CreateGrayPalette2(page); palette = localPalettes[page]; @@ -547,12 +608,13 @@ const RGBA *PixRaster::GetPalette(int page) CreateGrayPalette256(page); palette = localPalettes[page]; break; - + default: palette = 0; break; } } + else { // convert PIX palette @@ -561,22 +623,24 @@ const RGBA *PixRaster::GetPalette(int page) } pixDestroy(&pix); + return palette; - + } // END PixRaster::GetPalette() const RasterFormat *PixRaster::GetFormat(int page) { - if(IsEmpty()) + if (IsEmpty()) return NULL; // gets true page number page = getTruePage(page); - - if(!IsRasterFormatValid(page)) + + if (!IsRasterFormatValid(page)) SetRasterFormat(page); + return formats[page]; - + } // END PixRaster::GetFormat() // constructor -- empty raster @@ -593,205 +657,240 @@ PixRaster::PixRaster(PIX *pix, CopyModes copyMode) { pixa = pixaCreate(0); pixaAddPix(pixa, pix, copyMode); - + // sets the current page curPage = 0; - + // allocates empty format and local palette formats.Add((RasterFormat *)NULL); localPalettes.Add((RGBA *)NULL); - + } // END Constructor class PixRaster // constructor -- takes an array of Leptonica Pix PixRaster::PixRaster(PIXA *_pixa, CopyModes copyMode) { pixa = pixaCopy(_pixa, copyMode); - + // sets the current page curPage = 0; - + // allocates empty format and local palette - for(int i = 0; i < pixaGetCount(pixa); i++) + + for (int i = 0; i < pixaGetCount(pixa); i++) { formats.Add((RasterFormat *)NULL); localPalettes.Add((RGBA *)NULL); } - + } // END Constructor class PixRaster // destructor -- must free PIXA array void PixRaster::Destroy() { + if(IsEmpty()) + return; + // frees formats and local palettes - for(int i = 0; i < pixaGetCount(pixa); i++) + for (int i = 0; i < pixaGetCount(pixa); i++) { DestroyRasterFormat(i); DestroyLocalPalette(i); } - + formats.Clear(); + localPalettes.Clear(); + // frees pix array - if(pixa) + if (pixa) pixaDestroy(&pixa); + // sets current page + curPage = 0; + } // END Destructor class PixRaster // loads / appends Pix from another raster object void PixRaster::Load(Raster& raster, bool Append, CopyModes copyMode) { PixRaster *pixRaster; - + // if we don't want the array to be appended, // we destroy current array, if any - if(!Append && pixa) + + if (!Append && pixa) Destroy(); - + // if empty raster, we create it - if(IsEmpty()) + if (IsEmpty()) { - pixa=pixaCreate(0); + pixa = pixaCreate(0); curPage = 0; } - + // shortcut if raster is a pixRaster Raster::Info info = raster.GetInfo(); + int width = raster.GetWidth(); + pixRaster = dynamic_cast(&raster); - if(pixRaster) + + if (pixRaster) { ASSERT(copyMode == PIXRASTER_COPY || copyMode == PIXRASTER_CLONE); AddPIXA(pixRaster->GetPIXA(copyMode)); return; } - + // not a PixRaster, we should go the slow way - + // loop for all pages on source raster int oldPage = raster.GetActivePage(); - for(int iPage = 0; iPage < raster.GetPageCount(); iPage++) + + for (int iPage = 0; iPage < raster.GetPageCount(); iPage++) { PIX *pix; - + // gets current page on source raster raster.SeekPage(iPage); - + // gets information from source object const RasterFormat *format = raster.GetFormat(); // convert source image to PIX - if(!format) + + if (!format) { // null RasterFormat -- standard Upp RGBA pix = LoadRASTER_RGBA(raster); } + else { - switch(format->GetType()) + switch (format->GetType()) { + case RASTER_1: pix = LoadRASTER_1(raster); break; - + case RASTER_1 | RASTER_MSBFIRST: pix = LoadRASTER_1_MSBFIRST(raster); break; - + case RASTER_2: pix = LoadRASTER_2(raster); break; - + case RASTER_2 | RASTER_MSBFIRST: pix = LoadRASTER_2_MSBFIRST(raster); break; - + case RASTER_4: pix = LoadRASTER_4(raster); break; - + case RASTER_4 | RASTER_MSBFIRST: pix = LoadRASTER_4_MSBFIRST(raster); 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; - + case RASTER_16: pix = LoadRASTER_16(raster); break; - + case RASTER_16 | RASTER_MSBFIRST: pix = LoadRASTER_16_MSBFIRST(raster); break; - + case RASTER_24: pix = LoadRASTER_24(raster); break; - + case RASTER_24 | RASTER_MSBFIRST: pix = LoadRASTER_24_MSBFIRST(raster); 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; - + } // switch } - + // 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 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++) + + 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) + + if (dotX) resX = iscale(600, raster.GetWidth(), dotX); else resX = 0; - if(dotY) + + 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() // gets PIX and PIX array from raster @@ -800,60 +899,69 @@ void PixRaster::Load(Raster& raster, bool Append, CopyModes copyMode) PIX *PixRaster::GetPIX(int page, CopyModes copyMode) { PIX *pix; - - if(IsEmpty()) + + if (IsEmpty()) return NULL; - + page = getTruePage(page); - - if(copyMode == PIXRASTER_COPY) + + if (copyMode == PIXRASTER_COPY) pix = pixaGetPix(pixa, page, L_COPY); else pix = pixaGetPix(pixa, page, L_CLONE); - if(pix && copyMode == PIXRASTER_REF) + + if (pix && copyMode == PIXRASTER_REF) pix->refcount--; + return pix; - + } // END PixRaster::GetPix() PIXA *PixRaster::GetPIXA(CopyModes copyMode) { PIXA *_pixa; - - switch(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() // sets PIX and PIX array void PixRaster::SetPIX(PIX *pix, int page, CopyModes copyMode) { - if(IsEmpty()) + if (IsEmpty()) return; - + page = getTruePage(page); - - if(copyMode == PIXRASTER_COPY) + + if (copyMode == PIXRASTER_COPY) pix = pixCopy(NULL, pix); - else if(copyMode == PIXRASTER_CLONE) - pix = pixClone(pix); + else + if (copyMode == PIXRASTER_CLONE) + pix = pixClone(pix); + pixaReplacePix(pixa, page, pix, NULL); DestroyLocalPalette(page); + DestroyRasterFormat(page); - + } // END PixRaster::SetPIX() void PixRaster::SetPIXA(PIXA *_pixa, CopyModes copyMode) @@ -861,30 +969,33 @@ void PixRaster::SetPIXA(PIXA *_pixa, CopyModes copyMode) Destroy(); curPage = 0; AddPIXA(_pixa, copyMode); - + } // END PixRaster::SetPIXA() // adds a PIX or a PIX array void PixRaster::AddPIX(PIX *pix, CopyModes copyMode) { - if(!pixa) + 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() void PixRaster::AddPIXA(PIXA *_pixa, CopyModes copyMode) { - if(!pixa) + if (!pixa) pixa = pixaCreate(0); + pixaJoin(pixa, _pixa, 0, 0); - + // allocates empty format and local palette - for(int i = 0; i < pixaGetCount(_pixa); i++) + for (int i = 0; i < pixaGetCount(_pixa); i++) { formats.Add((RasterFormat *)NULL); localPalettes.Add((RGBA *)NULL); @@ -896,65 +1007,69 @@ void PixRaster::AddPIXA(PIXA *_pixa, CopyModes copyMode) void PixRaster::InsertPIX(PIX *pix, int where, CopyModes copyMode) { // if adding at end, just append - if(where == PIXRASTER_END || !pixa) + if (where == PIXRASTER_END || !pixa) { AddPIX(pix, copyMode); return; } - + // gets true page where = getTruePage(where); - + // insert pix into pixa array pixaInsertPix(pixa, where, pix, NULL); // inserts empty format and palette formats.Insert(where, (RasterFormat *)NULL); - localPalettes.Insert(where, (RGBA *)NULL); - + + localPalettes.Insert(where, (RGBA *)NULL); + } void PixRaster::InsertPIXA(PIXA *_pixa, int where, CopyModes copyMode) { // if adding at end, just append - if(where == PIXRASTER_END || !pixa) + if (where == PIXRASTER_END || !pixa) { AddPIXA(_pixa, copyMode); return; } - + // gets true page where = getTruePage(where); - - if(copyMode == PIXRASTER_COPY_CLONE) + + if (copyMode == PIXRASTER_COPY_CLONE) copyMode = PIXRASTER_CLONE; - - for(int i = 0; i < pixaGetCount(_pixa); i++) + + for (int i = 0; i < pixaGetCount(_pixa); i++) { // insert pix into pixa array PIX *pix = pixaGetPix(_pixa, i, copyMode); pixaInsertPix(pixa, where, pix, NULL); - + // inserts empty format and palette formats.Insert(where, (RasterFormat *)NULL); localPalettes.Insert(where, (RGBA *)NULL); where++; } - + } // removes a PIX or a series of PIX void PixRaster::RemovePIX(int where, int count) { - if(IsEmpty()) + if (IsEmpty()) return; - if(where == PIXRASTER_END) + + 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++) + if (pixaGetCount(pixa) - where < count) + count = pixaGetCount(pixa) - where; + + for (int i = 0; i < count; i++) { pixaRemovePix(pixa, where); delete formats[where]; @@ -962,7 +1077,7 @@ void PixRaster::RemovePIX(int where, int count) delete[] localPalettes[where]; localPalettes.Remove(where); } - + } // duplicates a page at the end of array (useful for stack-like operations) @@ -972,23 +1087,169 @@ void PixRaster::Dup(int page) AddPIX(pix, PIXRASTER_COPY); pixDestroy(&pix); SeekPage(PIXRASTER_LASTPAGE); - + } // Drops last page(s) of array (ditto) void PixRaster::Drop(int count) { - if(IsEmpty()) + if (IsEmpty()) return; + int start = pixaGetCount(pixa) - count; - if(start < 0) + + 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 diff --git a/bazaar/PixRaster/PixRaster.h b/bazaar/PixRaster/PixRaster.h index 680672e79..bf653f111 100644 --- a/bazaar/PixRaster/PixRaster.h +++ b/bazaar/PixRaster/PixRaster.h @@ -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 ////////////////////////////////////////// diff --git a/bazaar/PixRaster/src.tpp/PixRaster$en-us.tpp b/bazaar/PixRaster/src.tpp/PixRaster$en-us.tpp index 8f2080b74..07c91ad24 100644 --- a/bazaar/PixRaster/src.tpp/PixRaster$en-us.tpp +++ b/bazaar/PixRaster/src.tpp/PixRaster$en-us.tpp @@ -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]]}}&] diff --git a/bazaar/TestLeptonica/LineRemoval.cpp b/bazaar/TestLeptonica/LineRemoval.cpp index 71c538960..63a962cf9 100644 --- a/bazaar/TestLeptonica/LineRemoval.cpp +++ b/bazaar/TestLeptonica/LineRemoval.cpp @@ -2,34 +2,8 @@ #include -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; - } - OnestreamRaster = 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; + } +// OnestreamRaster = 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(); diff --git a/bazaar/TestLeptonica/oldMain.cpp b/bazaar/TestLeptonica/oldMain.cpp deleted file mode 100644 index dad4ead6e..000000000 --- a/bazaar/TestLeptonica/oldMain.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include "TestLeptonica.h" - -#include - -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; - } - OnestreamRaster = 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; - } - OnestreamRaster = 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(); -} -