|
Packit |
df99a1 |
//C- -*- C++ -*-
|
|
Packit |
df99a1 |
//C- -------------------------------------------------------------------
|
|
Packit |
df99a1 |
//C- DjVuLibre-3.5
|
|
Packit |
df99a1 |
//C- Copyright (c) 2002 Leon Bottou and Yann Le Cun.
|
|
Packit |
df99a1 |
//C- Copyright (c) 2001 AT&T
|
|
Packit |
df99a1 |
//C-
|
|
Packit |
df99a1 |
//C- This software is subject to, and may be distributed under, the
|
|
Packit |
df99a1 |
//C- GNU General Public License, either Version 2 of the license,
|
|
Packit |
df99a1 |
//C- or (at your option) any later version. The license should have
|
|
Packit |
df99a1 |
//C- accompanied the software or you may obtain a copy of the license
|
|
Packit |
df99a1 |
//C- from the Free Software Foundation at http://www.fsf.org .
|
|
Packit |
df99a1 |
//C-
|
|
Packit |
df99a1 |
//C- This program is distributed in the hope that it will be useful,
|
|
Packit |
df99a1 |
//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
df99a1 |
//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
df99a1 |
//C- GNU General Public License for more details.
|
|
Packit |
df99a1 |
//C-
|
|
Packit |
df99a1 |
//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from
|
|
Packit |
df99a1 |
//C- Lizardtech Software. Lizardtech Software has authorized us to
|
|
Packit |
df99a1 |
//C- replace the original DjVu(r) Reference Library notice by the following
|
|
Packit |
df99a1 |
//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu):
|
|
Packit |
df99a1 |
//C-
|
|
Packit |
df99a1 |
//C- ------------------------------------------------------------------
|
|
Packit |
df99a1 |
//C- | DjVu (r) Reference Library (v. 3.5)
|
|
Packit |
df99a1 |
//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
|
|
Packit |
df99a1 |
//C- | The DjVu Reference Library is protected by U.S. Pat. No.
|
|
Packit |
df99a1 |
//C- | 6,058,214 and patents pending.
|
|
Packit |
df99a1 |
//C- |
|
|
Packit |
df99a1 |
//C- | This software is subject to, and may be distributed under, the
|
|
Packit |
df99a1 |
//C- | GNU General Public License, either Version 2 of the license,
|
|
Packit |
df99a1 |
//C- | or (at your option) any later version. The license should have
|
|
Packit |
df99a1 |
//C- | accompanied the software or you may obtain a copy of the license
|
|
Packit |
df99a1 |
//C- | from the Free Software Foundation at http://www.fsf.org .
|
|
Packit |
df99a1 |
//C- |
|
|
Packit |
df99a1 |
//C- | The computer code originally released by LizardTech under this
|
|
Packit |
df99a1 |
//C- | license and unmodified by other parties is deemed "the LIZARDTECH
|
|
Packit |
df99a1 |
//C- | ORIGINAL CODE." Subject to any third party intellectual property
|
|
Packit |
df99a1 |
//C- | claims, LizardTech grants recipient a worldwide, royalty-free,
|
|
Packit |
df99a1 |
//C- | non-exclusive license to make, use, sell, or otherwise dispose of
|
|
Packit |
df99a1 |
//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the
|
|
Packit |
df99a1 |
//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
|
|
Packit |
df99a1 |
//C- | General Public License. This grant only confers the right to
|
|
Packit |
df99a1 |
//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
|
|
Packit |
df99a1 |
//C- | the extent such infringement is reasonably necessary to enable
|
|
Packit |
df99a1 |
//C- | recipient to make, have made, practice, sell, or otherwise dispose
|
|
Packit |
df99a1 |
//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
|
|
Packit |
df99a1 |
//C- | any greater extent that may be necessary to utilize further
|
|
Packit |
df99a1 |
//C- | modifications or combinations.
|
|
Packit |
df99a1 |
//C- |
|
|
Packit |
df99a1 |
//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
|
|
Packit |
df99a1 |
//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
Packit |
df99a1 |
//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
|
|
Packit |
df99a1 |
//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
|
|
Packit |
df99a1 |
//C- +------------------------------------------------------------------
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
df99a1 |
# include "config.h"
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
#if NEED_GNUG_PRAGMAS
|
|
Packit |
df99a1 |
# pragma implementation
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#include "GBitmap.h"
|
|
Packit |
df99a1 |
#include "ByteStream.h"
|
|
Packit |
df99a1 |
#include "GRect.h"
|
|
Packit |
df99a1 |
#include "GString.h"
|
|
Packit |
df99a1 |
#include "GThreads.h"
|
|
Packit |
df99a1 |
#include "GException.h"
|
|
Packit |
df99a1 |
#include <stddef.h>
|
|
Packit |
df99a1 |
#include <stdlib.h>
|
|
Packit |
df99a1 |
#include <string.h>
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// - Author: Leon Bottou, 05/1997
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#ifdef HAVE_NAMESPACES
|
|
Packit |
df99a1 |
namespace DJVU {
|
|
Packit |
df99a1 |
# ifdef NOT_DEFINED // Just to fool emacs c++ mode
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----- constructor and destructor
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GBitmap::~GBitmap()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::destroy(void)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
gbytes_data.resize(0);
|
|
Packit |
df99a1 |
bytes = 0;
|
|
Packit |
df99a1 |
grle.resize(0);
|
|
Packit |
df99a1 |
grlerows.resize(0);
|
|
Packit |
df99a1 |
rlelength = 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GBitmap::GBitmap()
|
|
Packit |
df99a1 |
: nrows(0), ncolumns(0), border(0),
|
|
Packit |
df99a1 |
bytes_per_row(0), grays(0), bytes(0), gbytes_data(bytes_data),
|
|
Packit |
df99a1 |
grle(rle), grlerows(rlerows), rlelength(0),
|
|
Packit |
df99a1 |
monitorptr(0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GBitmap::GBitmap(int nrows, int ncolumns, int border)
|
|
Packit |
df99a1 |
: nrows(0), ncolumns(0), border(0),
|
|
Packit |
df99a1 |
bytes_per_row(0), grays(0), bytes(0), gbytes_data(bytes_data),
|
|
Packit |
df99a1 |
grle(rle), grlerows(rlerows), rlelength(0),
|
|
Packit |
df99a1 |
monitorptr(0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
init(nrows, ncolumns, border);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
destroy();
|
|
Packit |
df99a1 |
G_RETHROW;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GBitmap::GBitmap(ByteStream &ref, int border)
|
|
Packit |
df99a1 |
: nrows(0), ncolumns(0), border(0),
|
|
Packit |
df99a1 |
bytes_per_row(0), grays(0), bytes(0), gbytes_data(bytes_data),
|
|
Packit |
df99a1 |
grle(rle), grlerows(rlerows), rlelength(0),
|
|
Packit |
df99a1 |
monitorptr(0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
init(ref, border);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
destroy();
|
|
Packit |
df99a1 |
G_RETHROW;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GBitmap::GBitmap(const GBitmap &ref)
|
|
Packit |
df99a1 |
: nrows(0), ncolumns(0), border(0),
|
|
Packit |
df99a1 |
bytes_per_row(0), grays(0), bytes(0), gbytes_data(bytes_data),
|
|
Packit |
df99a1 |
grle(rle), grlerows(rlerows), rlelength(0),
|
|
Packit |
df99a1 |
monitorptr(0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
init(ref, ref.border);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
destroy();
|
|
Packit |
df99a1 |
G_RETHROW;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GBitmap::GBitmap(const GBitmap &ref, int border)
|
|
Packit |
df99a1 |
: nrows(0), ncolumns(0), border(0),
|
|
Packit |
df99a1 |
bytes_per_row(0), grays(0), bytes(0), gbytes_data(bytes_data),
|
|
Packit |
df99a1 |
grle(rle), grlerows(rlerows), rlelength(0),
|
|
Packit |
df99a1 |
monitorptr(0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
init(ref, border);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
destroy();
|
|
Packit |
df99a1 |
G_RETHROW;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GBitmap::GBitmap(const GBitmap &ref, const GRect &rect, int border)
|
|
Packit |
df99a1 |
: nrows(0), ncolumns(0), border(0),
|
|
Packit |
df99a1 |
bytes_per_row(0), grays(0), bytes(0), gbytes_data(bytes_data),
|
|
Packit |
df99a1 |
grle(rle), grlerows(rlerows), rlelength(0),
|
|
Packit |
df99a1 |
monitorptr(0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
G_TRY
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
init(ref, rect, border);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_CATCH_ALL
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
destroy();
|
|
Packit |
df99a1 |
G_RETHROW;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_ENDCATCH;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----- initialization
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::init(int arows, int acolumns, int aborder)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (arows != (unsigned short) arows ||
|
|
Packit |
df99a1 |
acolumns != (unsigned short) acolumns ||
|
|
Packit |
df99a1 |
acolumns + aborder != (unsigned short)(acolumns + aborder))
|
|
Packit |
df99a1 |
G_THROW("Illegal arguments");
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
destroy();
|
|
Packit |
df99a1 |
grays = 2;
|
|
Packit |
df99a1 |
nrows = arows;
|
|
Packit |
df99a1 |
ncolumns = acolumns;
|
|
Packit |
df99a1 |
border = aborder;
|
|
Packit |
df99a1 |
bytes_per_row = ncolumns + border;
|
|
Packit |
df99a1 |
int npixels = nrows * bytes_per_row + border;
|
|
Packit |
df99a1 |
gzerobuffer=zeroes(bytes_per_row + border);
|
|
Packit |
df99a1 |
if (npixels > 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
gbytes_data.resize(npixels);
|
|
Packit |
df99a1 |
gbytes_data.clear();
|
|
Packit |
df99a1 |
bytes = bytes_data;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::init(const GBitmap &ref, int aborder)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
if (this != &ref)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(ref.monitor());
|
|
Packit |
df99a1 |
init(ref.nrows, ref.ncolumns, aborder);
|
|
Packit |
df99a1 |
grays = ref.grays;
|
|
Packit |
df99a1 |
unsigned char *row = bytes_data+border;
|
|
Packit |
df99a1 |
for (int n=0; n
|
|
Packit |
df99a1 |
memcpy( (void*)row, (void*)ref[n], ncolumns );
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (aborder > border)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
minborder(aborder);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::init(const GBitmap &ref, const GRect &rect, int border)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
// test bitmap physical equality
|
|
Packit |
df99a1 |
if (this == &ref)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GBitmap tmp;
|
|
Packit |
df99a1 |
tmp.grays = grays;
|
|
Packit |
df99a1 |
tmp.border = border;
|
|
Packit |
df99a1 |
tmp.bytes_per_row = bytes_per_row;
|
|
Packit |
df99a1 |
tmp.ncolumns = ncolumns;
|
|
Packit |
df99a1 |
tmp.nrows = nrows;
|
|
Packit |
df99a1 |
tmp.bytes = bytes;
|
|
Packit |
df99a1 |
tmp.gbytes_data.swap(gbytes_data);
|
|
Packit |
df99a1 |
tmp.grle.swap(grle);
|
|
Packit |
df99a1 |
bytes = 0 ;
|
|
Packit |
df99a1 |
init(tmp, rect, border);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(ref.monitor());
|
|
Packit |
df99a1 |
// create empty bitmap
|
|
Packit |
df99a1 |
init(rect.height(), rect.width(), border);
|
|
Packit |
df99a1 |
grays = ref.grays;
|
|
Packit |
df99a1 |
// compute destination rectangle
|
|
Packit |
df99a1 |
GRect rect2(0, 0, ref.columns(), ref.rows() );
|
|
Packit |
df99a1 |
rect2.intersect(rect2, rect);
|
|
Packit |
df99a1 |
rect2.translate(-rect.xmin, -rect.ymin);
|
|
Packit |
df99a1 |
// copy bits
|
|
Packit |
df99a1 |
if (! rect2.isempty())
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
for (int y=rect2.ymin; y
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char *dst = (*this)[y];
|
|
Packit |
df99a1 |
const unsigned char *src = ref[y+rect.ymin] + rect.xmin;
|
|
Packit |
df99a1 |
for (int x=rect2.xmin; x
|
|
Packit |
df99a1 |
dst[x] = src[x];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::init(ByteStream &ref, int aborder)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
// Get magic number
|
|
Packit |
df99a1 |
char magic[2];
|
|
Packit |
df99a1 |
magic[0] = magic[1] = 0;
|
|
Packit |
df99a1 |
ref.readall((void*)magic, sizeof(magic));
|
|
Packit |
df99a1 |
char lookahead = '\n';
|
|
Packit |
df99a1 |
int acolumns = read_integer(lookahead, ref);
|
|
Packit |
df99a1 |
int arows = read_integer(lookahead, ref);
|
|
Packit |
df99a1 |
int maxval = 1;
|
|
Packit |
df99a1 |
init(arows, acolumns, aborder);
|
|
Packit |
df99a1 |
// go reading file
|
|
Packit |
df99a1 |
if (magic[0]=='P')
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
switch(magic[1])
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
case '1':
|
|
Packit |
df99a1 |
grays = 2;
|
|
Packit |
df99a1 |
read_pbm_text(ref);
|
|
Packit |
df99a1 |
return;
|
|
Packit |
df99a1 |
case '2':
|
|
Packit |
df99a1 |
maxval = read_integer(lookahead, ref);
|
|
Packit |
df99a1 |
if (maxval > 65535)
|
|
Packit |
df99a1 |
G_THROW("Cannot read PGM with depth greater than 16 bits.");
|
|
Packit |
df99a1 |
grays = (maxval>255 ? 256 : maxval+1);
|
|
Packit |
df99a1 |
read_pgm_text(ref, maxval);
|
|
Packit |
df99a1 |
return;
|
|
Packit |
df99a1 |
case '4':
|
|
Packit |
df99a1 |
grays = 2;
|
|
Packit |
df99a1 |
read_pbm_raw(ref);
|
|
Packit |
df99a1 |
return;
|
|
Packit |
df99a1 |
case '5':
|
|
Packit |
df99a1 |
maxval = read_integer(lookahead, ref);
|
|
Packit |
df99a1 |
if (maxval > 65535)
|
|
Packit |
df99a1 |
G_THROW("Cannot read PGM with depth greater than 16 bits.");
|
|
Packit |
df99a1 |
grays = (maxval>255 ? 256 : maxval+1);
|
|
Packit |
df99a1 |
read_pgm_raw(ref, maxval);
|
|
Packit |
df99a1 |
return;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (magic[0]=='R')
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
switch(magic[1])
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
case '4':
|
|
Packit |
df99a1 |
grays = 2;
|
|
Packit |
df99a1 |
read_rle_raw(ref);
|
|
Packit |
df99a1 |
return;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.bad_format") );
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::donate_data(unsigned char *data, int w, int h)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
destroy();
|
|
Packit |
df99a1 |
grays = 2;
|
|
Packit |
df99a1 |
nrows = h;
|
|
Packit |
df99a1 |
ncolumns = w;
|
|
Packit |
df99a1 |
border = 0;
|
|
Packit |
df99a1 |
bytes_per_row = w;
|
|
Packit |
df99a1 |
gbytes_data.replace(data,w*h);
|
|
Packit |
df99a1 |
bytes = bytes_data;
|
|
Packit |
df99a1 |
rlelength = 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::donate_rle(unsigned char *rledata, unsigned int rledatalen, int w, int h)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
destroy();
|
|
Packit |
df99a1 |
grays = 2;
|
|
Packit |
df99a1 |
nrows = h;
|
|
Packit |
df99a1 |
ncolumns = w;
|
|
Packit |
df99a1 |
border = 0;
|
|
Packit |
df99a1 |
bytes_per_row = w;
|
|
Packit |
df99a1 |
// rle = rledata;
|
|
Packit |
df99a1 |
grle.replace(rledata,rledatalen);
|
|
Packit |
df99a1 |
rlelength = rledatalen;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
unsigned char *
|
|
Packit |
df99a1 |
GBitmap::take_data(size_t &offset)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
unsigned char *ret = bytes_data;
|
|
Packit |
df99a1 |
if (ret) offset = (size_t)border;
|
|
Packit |
df99a1 |
bytes_data=0;
|
|
Packit |
df99a1 |
return ret;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
const unsigned char *
|
|
Packit |
df99a1 |
GBitmap::get_rle(unsigned int &rle_length)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if(!rle)
|
|
Packit |
df99a1 |
compress();
|
|
Packit |
df99a1 |
rle_length=rlelength;
|
|
Packit |
df99a1 |
return rle;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----- compression
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::compress()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (grays > 2)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.cant_compress") );
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
if (bytes)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
grle.resize(0);
|
|
Packit |
df99a1 |
grlerows.resize(0);
|
|
Packit |
df99a1 |
rlelength = encode(rle,grle);
|
|
Packit |
df99a1 |
if (rlelength)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
gbytes_data.resize(0);
|
|
Packit |
df99a1 |
bytes = 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::uncompress()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
if (!bytes && rle)
|
|
Packit |
df99a1 |
decode(rle);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
unsigned int
|
|
Packit |
df99a1 |
GBitmap::get_memory_usage() const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned long usage = sizeof(GBitmap);
|
|
Packit |
df99a1 |
if (bytes)
|
|
Packit |
df99a1 |
usage += nrows * bytes_per_row + border;
|
|
Packit |
df99a1 |
if (rle)
|
|
Packit |
df99a1 |
usage += rlelength;
|
|
Packit |
df99a1 |
return usage;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::minborder(int minimum)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (border < minimum)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
if (border < minimum)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (bytes)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GBitmap tmp(*this, minimum);
|
|
Packit |
df99a1 |
bytes_per_row = tmp.bytes_per_row;
|
|
Packit |
df99a1 |
tmp.gbytes_data.swap(gbytes_data);
|
|
Packit |
df99a1 |
bytes = bytes_data;
|
|
Packit |
df99a1 |
tmp.bytes = 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
border = minimum;
|
|
Packit |
df99a1 |
gzerobuffer=zeroes(border + ncolumns + border);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#define NMONITORS 8
|
|
Packit |
df99a1 |
static GMonitor monitors[NMONITORS];
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::share()
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (!monitorptr)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
size_t x = (size_t)this;
|
|
Packit |
df99a1 |
monitorptr = &monitors[(x^(x>>5)) % NMONITORS];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----- gray levels
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::set_grays(int ngrays)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (ngrays<2 || ngrays>256)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.bad_levels") );
|
|
Packit |
df99a1 |
// set gray levels
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
grays = ngrays;
|
|
Packit |
df99a1 |
if (ngrays>2 && !bytes)
|
|
Packit |
df99a1 |
uncompress();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::change_grays(int ngrays)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
// set number of grays
|
|
Packit |
df99a1 |
int ng = ngrays - 1;
|
|
Packit |
df99a1 |
int og = grays - 1;
|
|
Packit |
df99a1 |
set_grays(ngrays);
|
|
Packit |
df99a1 |
// setup conversion table
|
|
Packit |
df99a1 |
unsigned char conv[256];
|
|
Packit |
df99a1 |
for (int i=0; i<256; i++)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (i > og)
|
|
Packit |
df99a1 |
conv[i] = ng;
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
conv[i] = (i*ng+og/2)/og;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// perform conversion
|
|
Packit |
df99a1 |
for (int row=0; row
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char *p = (*this)[row];
|
|
Packit |
df99a1 |
for (int n=0; n
|
|
Packit |
df99a1 |
p[n] = conv[ p[n] ];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::binarize_grays(int threshold)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
if (bytes)
|
|
Packit |
df99a1 |
for (int row=0; row
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char *p = (*this)[row];
|
|
Packit |
df99a1 |
for(unsigned char const * const pend=p+ncolumns;p
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
*p = (*p>threshold) ? 1 : 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
grays = 2;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ----- additive blitting
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#undef min
|
|
Packit |
df99a1 |
#undef max
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static inline int
|
|
Packit |
df99a1 |
min(int x, int y)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return (x < y ? x : y);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static inline int
|
|
Packit |
df99a1 |
max(int x, int y)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
return (x > y ? x : y);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::blit(const GBitmap *bm, int x, int y)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Check boundaries
|
|
Packit |
df99a1 |
if ((x >= ncolumns) ||
|
|
Packit |
df99a1 |
(y >= nrows) ||
|
|
Packit |
df99a1 |
(x + (int)bm->columns() < 0) ||
|
|
Packit |
df99a1 |
(y + (int)bm->rows() < 0) )
|
|
Packit |
df99a1 |
return;
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Perform blit
|
|
Packit |
df99a1 |
GMonitorLock lock1(monitor());
|
|
Packit |
df99a1 |
GMonitorLock lock2(bm->monitor());
|
|
Packit |
df99a1 |
if (bm->bytes)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (!bytes_data)
|
|
Packit |
df99a1 |
uncompress();
|
|
Packit |
df99a1 |
// Blit from bitmap
|
|
Packit |
df99a1 |
const unsigned char *srow = bm->bytes + bm->border;
|
|
Packit |
df99a1 |
unsigned char *drow = bytes_data + border + y*bytes_per_row + x;
|
|
Packit |
df99a1 |
for (int sr = 0; sr < bm->nrows; sr++)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (sr+y>=0 && sr+y
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int sc = max(0, -x);
|
|
Packit |
df99a1 |
int sc1 = min(bm->ncolumns, ncolumns-x);
|
|
Packit |
df99a1 |
while (sc < sc1)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
drow[sc] += srow[sc];
|
|
Packit |
df99a1 |
sc += 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
srow += bm->bytes_per_row;
|
|
Packit |
df99a1 |
drow += bytes_per_row;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (bm->rle)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (!bytes_data)
|
|
Packit |
df99a1 |
uncompress();
|
|
Packit |
df99a1 |
// Blit from rle
|
|
Packit |
df99a1 |
const unsigned char *runs = bm->rle;
|
|
Packit |
df99a1 |
unsigned char *drow = bytes_data + border + y*bytes_per_row + x;
|
|
Packit |
df99a1 |
int sr = bm->nrows - 1;
|
|
Packit |
df99a1 |
drow += sr * bytes_per_row;
|
|
Packit |
df99a1 |
int sc = 0;
|
|
Packit |
df99a1 |
char p = 0;
|
|
Packit |
df99a1 |
while (sr >= 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const int z = read_run(runs);
|
|
Packit |
df99a1 |
if (sc+z > bm->ncolumns)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.lost_sync") );
|
|
Packit |
df99a1 |
int nc = sc + z;
|
|
Packit |
df99a1 |
if (p && sr+y>=0 && sr+y
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (sc + x < 0)
|
|
Packit |
df99a1 |
sc = min(-x, nc);
|
|
Packit |
df99a1 |
while (sc < nc && sc + x
|
|
Packit |
df99a1 |
drow[sc++] += 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
sc = nc;
|
|
Packit |
df99a1 |
p = 1 - p;
|
|
Packit |
df99a1 |
if (sc >= bm->ncolumns)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
p = 0;
|
|
Packit |
df99a1 |
sc = 0;
|
|
Packit |
df99a1 |
drow -= bytes_per_row;
|
|
Packit |
df99a1 |
sr -= 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::blit(const GBitmap *bm, int xh, int yh, int subsample)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// Use code when no subsampling is necessary
|
|
Packit |
df99a1 |
if (subsample == 1)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
blit(bm, xh, yh);
|
|
Packit |
df99a1 |
return;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Check boundaries
|
|
Packit |
df99a1 |
if ((xh >= ncolumns * subsample) ||
|
|
Packit |
df99a1 |
(yh >= nrows * subsample) ||
|
|
Packit |
df99a1 |
(xh + (int)bm->columns() < 0) ||
|
|
Packit |
df99a1 |
(yh + (int)bm->rows() < 0) )
|
|
Packit |
df99a1 |
return;
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Perform subsampling blit
|
|
Packit |
df99a1 |
GMonitorLock lock1(monitor());
|
|
Packit |
df99a1 |
GMonitorLock lock2(bm->monitor());
|
|
Packit |
df99a1 |
if (bm->bytes)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (!bytes_data)
|
|
Packit |
df99a1 |
uncompress();
|
|
Packit |
df99a1 |
// Blit from bitmap
|
|
Packit |
df99a1 |
int dr, dr1, zdc, zdc1;
|
|
Packit |
df99a1 |
euclidian_ratio(yh, subsample, dr, dr1);
|
|
Packit |
df99a1 |
euclidian_ratio(xh, subsample, zdc, zdc1);
|
|
Packit |
df99a1 |
const unsigned char *srow = bm->bytes + bm->border;
|
|
Packit |
df99a1 |
unsigned char *drow = bytes_data + border + dr*bytes_per_row;
|
|
Packit |
df99a1 |
for (int sr = 0; sr < bm->nrows; sr++)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (dr>=0 && dr
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int dc = zdc;
|
|
Packit |
df99a1 |
int dc1 = zdc1;
|
|
Packit |
df99a1 |
for (int sc=0; sc < bm->ncolumns; sc++)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (dc>=0 && dc
|
|
Packit |
df99a1 |
drow[dc] += srow[sc];
|
|
Packit |
df99a1 |
if (++dc1 >= subsample)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
dc1 = 0;
|
|
Packit |
df99a1 |
dc += 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// next line in source
|
|
Packit |
df99a1 |
srow += bm->bytes_per_row;
|
|
Packit |
df99a1 |
// next line fraction in destination
|
|
Packit |
df99a1 |
if (++dr1 >= subsample)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
dr1 = 0;
|
|
Packit |
df99a1 |
dr += 1;
|
|
Packit |
df99a1 |
drow += bytes_per_row;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if (bm->rle)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (!bytes_data)
|
|
Packit |
df99a1 |
uncompress();
|
|
Packit |
df99a1 |
// Blit from rle
|
|
Packit |
df99a1 |
int dr, dr1, zdc, zdc1;
|
|
Packit |
df99a1 |
euclidian_ratio(yh+bm->nrows-1, subsample, dr, dr1);
|
|
Packit |
df99a1 |
euclidian_ratio(xh, subsample, zdc, zdc1);
|
|
Packit |
df99a1 |
const unsigned char *runs = bm->rle;
|
|
Packit |
df99a1 |
unsigned char *drow = bytes_data + border + dr*bytes_per_row;
|
|
Packit |
df99a1 |
int sr = bm->nrows -1;
|
|
Packit |
df99a1 |
int sc = 0;
|
|
Packit |
df99a1 |
char p = 0;
|
|
Packit |
df99a1 |
int dc = zdc;
|
|
Packit |
df99a1 |
int dc1 = zdc1;
|
|
Packit |
df99a1 |
while (sr >= 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int z = read_run(runs);
|
|
Packit |
df99a1 |
if (sc+z > bm->ncolumns)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.lost_sync") );
|
|
Packit |
df99a1 |
int nc = sc + z;
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
if (dr>=0 && dr
|
|
Packit |
df99a1 |
while (z>0 && dc
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int zd = subsample - dc1;
|
|
Packit |
df99a1 |
if (zd > z)
|
|
Packit |
df99a1 |
zd = z;
|
|
Packit |
df99a1 |
if (p && dc>=0)
|
|
Packit |
df99a1 |
drow[dc] += zd;
|
|
Packit |
df99a1 |
z -= zd;
|
|
Packit |
df99a1 |
dc1 += zd;
|
|
Packit |
df99a1 |
if (dc1 >= subsample)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
dc1 = 0;
|
|
Packit |
df99a1 |
dc += 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// next fractional row
|
|
Packit |
df99a1 |
sc = nc;
|
|
Packit |
df99a1 |
p = 1 - p;
|
|
Packit |
df99a1 |
if (sc >= bm->ncolumns)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
sc = 0;
|
|
Packit |
df99a1 |
dc = zdc;
|
|
Packit |
df99a1 |
dc1 = zdc1;
|
|
Packit |
df99a1 |
p = 0;
|
|
Packit |
df99a1 |
sr -= 1;
|
|
Packit |
df99a1 |
if (--dr1 < 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
dr1 = subsample - 1;
|
|
Packit |
df99a1 |
dr -= 1;
|
|
Packit |
df99a1 |
drow -= bytes_per_row;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ------ load bitmaps
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
unsigned int
|
|
Packit |
df99a1 |
GBitmap::read_integer(char &c, ByteStream &bs)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned int x = 0;
|
|
Packit |
df99a1 |
// eat blank before integer
|
|
Packit |
df99a1 |
while (c==' ' || c=='\t' || c=='\r' || c=='\n' || c=='#')
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (c=='#')
|
|
Packit |
df99a1 |
do { } while (bs.read(&c,1) && c!='\n' && c!='\r');
|
|
Packit |
df99a1 |
c = 0;
|
|
Packit |
df99a1 |
bs.read(&c, 1);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// check integer
|
|
Packit |
df99a1 |
if (c<'0' || c>'9')
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.not_int") );
|
|
Packit |
df99a1 |
// eat integer
|
|
Packit |
df99a1 |
while (c>='0' && c<='9')
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
x = x*10 + c - '0';
|
|
Packit |
df99a1 |
c = 0;
|
|
Packit |
df99a1 |
bs.read(&c, 1);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return x;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::read_pbm_text(ByteStream &bs)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char *row = bytes_data + border;
|
|
Packit |
df99a1 |
row += (nrows-1) * bytes_per_row;
|
|
Packit |
df99a1 |
for (int n = nrows-1; n>=0; n--)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
for (int c = 0; c
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
char bit = 0;
|
|
Packit |
df99a1 |
bs.read(&bit,1);
|
|
Packit |
df99a1 |
while (bit==' ' || bit=='\t' || bit=='\r' || bit=='\n')
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
bit=0;
|
|
Packit |
df99a1 |
bs.read(&bit,1);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (bit=='1')
|
|
Packit |
df99a1 |
row[c] = 1;
|
|
Packit |
df99a1 |
else if (bit=='0')
|
|
Packit |
df99a1 |
row[c] = 0;
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.bad_PBM") );
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
row -= bytes_per_row;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::read_pgm_text(ByteStream &bs, int maxval)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char *row = bytes_data + border;
|
|
Packit |
df99a1 |
row += (nrows-1) * bytes_per_row;
|
|
Packit |
df99a1 |
char lookahead = '\n';
|
|
Packit |
df99a1 |
GTArray<unsigned char> ramp(0, maxval);
|
|
Packit |
df99a1 |
for (int i=0; i<=maxval; i++)
|
|
Packit |
df99a1 |
ramp[i] = (i
|
|
Packit |
df99a1 |
for (int n = nrows-1; n>=0; n--)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
for (int c = 0; c
|
|
Packit |
df99a1 |
row[c] = ramp[(int)read_integer(lookahead, bs)];
|
|
Packit |
df99a1 |
row -= bytes_per_row;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::read_pbm_raw(ByteStream &bs)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char *row = bytes_data + border;
|
|
Packit |
df99a1 |
row += (nrows-1) * bytes_per_row;
|
|
Packit |
df99a1 |
for (int n = nrows-1; n>=0; n--)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char acc = 0;
|
|
Packit |
df99a1 |
unsigned char mask = 0;
|
|
Packit |
df99a1 |
for (int c = 0; c
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (!mask)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
bs.read(&acc, 1);
|
|
Packit |
df99a1 |
mask = (unsigned char)0x80;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (acc & mask)
|
|
Packit |
df99a1 |
row[c] = 1;
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
row[c] = 0;
|
|
Packit |
df99a1 |
mask >>= 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
row -= bytes_per_row;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::read_pgm_raw(ByteStream &bs, int maxval)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int maxbin = (maxval>255) ? 65536 : 256;
|
|
Packit |
df99a1 |
GTArray<unsigned char> ramp(0, maxbin-1);
|
|
Packit |
df99a1 |
for (int i=0; i
|
|
Packit |
df99a1 |
ramp[i] = (i
|
|
Packit |
df99a1 |
unsigned char *bramp = ramp;
|
|
Packit |
df99a1 |
unsigned char *row = bytes_data + border;
|
|
Packit |
df99a1 |
row += (nrows-1) * bytes_per_row;
|
|
Packit |
df99a1 |
for (int n = nrows-1; n>=0; n--)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (maxbin > 256)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
for (int c = 0; c
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char x[2];
|
|
Packit |
df99a1 |
bs.read((void*)&x, 2);
|
|
Packit |
df99a1 |
row[c] = bramp[x[0]*256+x[1]];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
for (int c = 0; c
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char x;
|
|
Packit |
df99a1 |
bs.read((void*)&x, 1);
|
|
Packit |
df99a1 |
row[c] = bramp[x];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
row -= bytes_per_row;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::read_rle_raw(ByteStream &bs)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// interpret runs data
|
|
Packit |
df99a1 |
unsigned char h;
|
|
Packit |
df99a1 |
unsigned char p = 0;
|
|
Packit |
df99a1 |
unsigned char *row = bytes_data + border;
|
|
Packit |
df99a1 |
int n = nrows - 1;
|
|
Packit |
df99a1 |
row += n * bytes_per_row;
|
|
Packit |
df99a1 |
int c = 0;
|
|
Packit |
df99a1 |
while (n >= 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
bs.read(&h, 1);
|
|
Packit |
df99a1 |
int x = h;
|
|
Packit |
df99a1 |
if (x >= (int)RUNOVERFLOWVALUE)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
bs.read(&h, 1);
|
|
Packit |
df99a1 |
x = h + ((x - (int)RUNOVERFLOWVALUE) << 8);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (c+x > ncolumns)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.lost_sync") );
|
|
Packit |
df99a1 |
while (x-- > 0)
|
|
Packit |
df99a1 |
row[c++] = p;
|
|
Packit |
df99a1 |
p = 1 - p;
|
|
Packit |
df99a1 |
if (c >= ncolumns)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
c = 0;
|
|
Packit |
df99a1 |
p = 0;
|
|
Packit |
df99a1 |
row -= bytes_per_row;
|
|
Packit |
df99a1 |
n -= 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ------ save bitmaps
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::save_pbm(ByteStream &bs, int raw)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// check arguments
|
|
Packit |
df99a1 |
if (grays > 2)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.cant_make_PBM") );
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
// header
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GUTF8String head;
|
|
Packit |
df99a1 |
head.format("P%c\n%d %d\n", (raw ? '4' : '1'), ncolumns, nrows);
|
|
Packit |
df99a1 |
bs.writall((void*)(const char *)head, head.length());
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// body
|
|
Packit |
df99a1 |
if(raw)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if(!rle)
|
|
Packit |
df99a1 |
compress();
|
|
Packit |
df99a1 |
const unsigned char *runs=rle;
|
|
Packit |
df99a1 |
const unsigned char * const runs_end=rle+rlelength;
|
|
Packit |
df99a1 |
const int count=(ncolumns+7)>>3;
|
|
Packit |
df99a1 |
unsigned char *buf;
|
|
Packit |
df99a1 |
GPBuffer<unsigned char> gbuf(buf,count);
|
|
Packit |
df99a1 |
while(runs
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
rle_get_bitmap(ncolumns,runs,buf,false);
|
|
Packit |
df99a1 |
bs.writall(buf,count);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (!bytes)
|
|
Packit |
df99a1 |
uncompress();
|
|
Packit |
df99a1 |
const unsigned char *row = bytes + border;
|
|
Packit |
df99a1 |
int n = nrows - 1;
|
|
Packit |
df99a1 |
row += n * bytes_per_row;
|
|
Packit |
df99a1 |
while (n >= 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char eol='\n';
|
|
Packit |
df99a1 |
for (int c=0; c
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char bit= (row[c] ? '1' : '0');
|
|
Packit |
df99a1 |
bs.write((void*)&bit, 1);
|
|
Packit |
df99a1 |
c += 1;
|
|
Packit |
df99a1 |
if (c==ncolumns || (c&(int)RUNMSBMASK)==0)
|
|
Packit |
df99a1 |
bs.write((void*)&eol, 1);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// next row
|
|
Packit |
df99a1 |
row -= bytes_per_row;
|
|
Packit |
df99a1 |
n -= 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::save_pgm(ByteStream &bs, int raw)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// checks
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
if (!bytes)
|
|
Packit |
df99a1 |
uncompress();
|
|
Packit |
df99a1 |
// header
|
|
Packit |
df99a1 |
GUTF8String head;
|
|
Packit |
df99a1 |
head.format("P%c\n%d %d\n%d\n", (raw ? '5' : '2'), ncolumns, nrows, grays-1);
|
|
Packit |
df99a1 |
bs.writall((void*)(const char *)head, head.length());
|
|
Packit |
df99a1 |
// body
|
|
Packit |
df99a1 |
const unsigned char *row = bytes + border;
|
|
Packit |
df99a1 |
int n = nrows - 1;
|
|
Packit |
df99a1 |
row += n * bytes_per_row;
|
|
Packit |
df99a1 |
while (n >= 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (raw)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
for (int c=0; c
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
char x = grays - 1 - row[c];
|
|
Packit |
df99a1 |
bs.write((void*)&x, 1);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char eol='\n';
|
|
Packit |
df99a1 |
for (int c=0; c
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
head.format("%d ", grays - 1 - row[c]);
|
|
Packit |
df99a1 |
bs.writall((void*)(const char *)head, head.length());
|
|
Packit |
df99a1 |
c += 1;
|
|
Packit |
df99a1 |
if (c==ncolumns || (c&0x1f)==0)
|
|
Packit |
df99a1 |
bs.write((void*)&eol, 1);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
row -= bytes_per_row;
|
|
Packit |
df99a1 |
n -= 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::save_rle(ByteStream &bs)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// checks
|
|
Packit |
df99a1 |
if (ncolumns==0 || nrows==0)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.not_init") );
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
if (grays > 2)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.cant_make_PBM") );
|
|
Packit |
df99a1 |
// header
|
|
Packit |
df99a1 |
GUTF8String head;
|
|
Packit |
df99a1 |
head.format("R4\n%d %d\n", ncolumns, nrows);
|
|
Packit |
df99a1 |
bs.writall((void*)(const char *)head, head.length());
|
|
Packit |
df99a1 |
// body
|
|
Packit |
df99a1 |
if (rle)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
bs.writall((void*)rle, rlelength);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char *runs = 0;
|
|
Packit |
df99a1 |
GPBuffer<unsigned char> gruns(runs);
|
|
Packit |
df99a1 |
int size = encode(runs,gruns);
|
|
Packit |
df99a1 |
bs.writall((void*)runs, size);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ------ runs
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::makerows(
|
|
Packit |
df99a1 |
int nrows, const int ncolumns, unsigned char *runs, unsigned char *rlerows[])
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
while (nrows-- > 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
rlerows[nrows] = runs;
|
|
Packit |
df99a1 |
int c;
|
|
Packit |
df99a1 |
for(c=0;c
|
|
Packit |
df99a1 |
EMPTY_LOOP;
|
|
Packit |
df99a1 |
if (c > ncolumns)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.lost_sync2") );
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::rle_get_bitmap (
|
|
Packit |
df99a1 |
const int ncolumns,
|
|
Packit |
df99a1 |
const unsigned char *&runs,
|
|
Packit |
df99a1 |
unsigned char *bitmap,
|
|
Packit |
df99a1 |
const bool invert )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const int obyte_def=invert?0xff:0;
|
|
Packit |
df99a1 |
const int obyte_ndef=invert?0:0xff;
|
|
Packit |
df99a1 |
int mask=0x80,obyte=0;
|
|
Packit |
df99a1 |
for(int c=ncolumns;c > 0 ;)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int x=read_run(runs);
|
|
Packit |
df99a1 |
c-=x;
|
|
Packit |
df99a1 |
while((x--)>0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if(!(mask>>=1))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
*(bitmap++) = obyte^obyte_def;
|
|
Packit |
df99a1 |
obyte=0;
|
|
Packit |
df99a1 |
mask=0x80;
|
|
Packit |
df99a1 |
for(;x>=8;x-=8)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
*(bitmap++)=obyte_def;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if(c>0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int x=read_run(runs);
|
|
Packit |
df99a1 |
c-=x;
|
|
Packit |
df99a1 |
while((x--)>0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
obyte|=mask;
|
|
Packit |
df99a1 |
if(!(mask>>=1))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
*(bitmap++)=obyte^obyte_def;
|
|
Packit |
df99a1 |
obyte=0;
|
|
Packit |
df99a1 |
mask=0x80;
|
|
Packit |
df99a1 |
for(;(x>8);x-=8)
|
|
Packit |
df99a1 |
*(bitmap++)=obyte_ndef;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if(mask != 0x80)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
*(bitmap++)=obyte^obyte_def;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
GBitmap::rle_get_bits(int rowno, unsigned char *bits) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
if (!rle)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
if (rowno<0 || rowno>=nrows)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
if (!rlerows)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const_cast<GPBuffer<unsigned char *> &>(grlerows).resize(nrows);
|
|
Packit |
df99a1 |
makerows(nrows,ncolumns,rle,const_cast<unsigned char **>(rlerows));
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
int n = 0;
|
|
Packit |
df99a1 |
int p = 0;
|
|
Packit |
df99a1 |
int c = 0;
|
|
Packit |
df99a1 |
unsigned char *runs = rlerows[rowno];
|
|
Packit |
df99a1 |
while (c < ncolumns)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const int x=read_run(runs);
|
|
Packit |
df99a1 |
if ((c+=x)>ncolumns)
|
|
Packit |
df99a1 |
c = ncolumns;
|
|
Packit |
df99a1 |
while (n
|
|
Packit |
df99a1 |
bits[n++] = p;
|
|
Packit |
df99a1 |
p = 1-p;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return n;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
GBitmap::rle_get_runs(int rowno, int *rlens) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
if (!rle)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
if (rowno<0 || rowno>=nrows)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
if (!rlerows)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const_cast<GPBuffer<unsigned char *> &>(grlerows).resize(nrows);
|
|
Packit |
df99a1 |
makerows(nrows,ncolumns,rle,const_cast<unsigned char **>(rlerows));
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
int n = 0;
|
|
Packit |
df99a1 |
int d = 0;
|
|
Packit |
df99a1 |
int c = 0;
|
|
Packit |
df99a1 |
unsigned char *runs = rlerows[rowno];
|
|
Packit |
df99a1 |
while (c < ncolumns)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const int x=read_run(runs);
|
|
Packit |
df99a1 |
if (n>0 && !x)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
n--;
|
|
Packit |
df99a1 |
d = d-rlens[n];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
rlens[n++] = (c+=x)-d;
|
|
Packit |
df99a1 |
d = c;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return n;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
GBitmap::rle_get_rect(GRect &rect) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
if (!rle)
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
int area = 0;
|
|
Packit |
df99a1 |
unsigned char *runs = rle;
|
|
Packit |
df99a1 |
rect.xmin = ncolumns;
|
|
Packit |
df99a1 |
rect.ymin = nrows;
|
|
Packit |
df99a1 |
rect.xmax = 0;
|
|
Packit |
df99a1 |
rect.ymax = 0;
|
|
Packit |
df99a1 |
int r = nrows;
|
|
Packit |
df99a1 |
while (--r >= 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int p = 0;
|
|
Packit |
df99a1 |
int c = 0;
|
|
Packit |
df99a1 |
int n = 0;
|
|
Packit |
df99a1 |
while (c < ncolumns)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const int x=read_run(runs);
|
|
Packit |
df99a1 |
if(x)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (p)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (c < rect.xmin)
|
|
Packit |
df99a1 |
rect.xmin = c;
|
|
Packit |
df99a1 |
if ((c += x) > rect.xmax)
|
|
Packit |
df99a1 |
rect.xmax = c-1;
|
|
Packit |
df99a1 |
n += x;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
c += x;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
p = 1-p;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
area += n;
|
|
Packit |
df99a1 |
if (n)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
rect.ymin = r;
|
|
Packit |
df99a1 |
if (r > rect.ymax)
|
|
Packit |
df99a1 |
rect.ymax = r;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (area==0)
|
|
Packit |
df99a1 |
rect.clear();
|
|
Packit |
df99a1 |
return area;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// ------ helpers
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int
|
|
Packit |
df99a1 |
GBitmap::encode(unsigned char *&pruns,GPBuffer<unsigned char> &gpruns) const
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// uncompress rle information
|
|
Packit |
df99a1 |
if (nrows==0 || ncolumns==0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
gpruns.resize(0);
|
|
Packit |
df99a1 |
return 0;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (!bytes)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char *runs;
|
|
Packit |
df99a1 |
GPBuffer<unsigned char> gruns(runs,rlelength);
|
|
Packit |
df99a1 |
memcpy((void*)runs, rle, rlelength);
|
|
Packit |
df99a1 |
gruns.swap(gpruns);
|
|
Packit |
df99a1 |
return rlelength;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
gpruns.resize(0);
|
|
Packit |
df99a1 |
// create run array
|
|
Packit |
df99a1 |
int pos = 0;
|
|
Packit |
df99a1 |
int maxpos = 1024 + ncolumns + ncolumns;
|
|
Packit |
df99a1 |
unsigned char *runs;
|
|
Packit |
df99a1 |
GPBuffer<unsigned char> gruns(runs,maxpos);
|
|
Packit |
df99a1 |
// encode bitmap as rle
|
|
Packit |
df99a1 |
const unsigned char *row = bytes + border;
|
|
Packit |
df99a1 |
int n = nrows - 1;
|
|
Packit |
df99a1 |
row += n * bytes_per_row;
|
|
Packit |
df99a1 |
while (n >= 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if (maxpos < pos+ncolumns+ncolumns+2)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
maxpos += 1024 + ncolumns + ncolumns;
|
|
Packit |
df99a1 |
gruns.resize(maxpos);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
unsigned char *runs_pos=runs+pos;
|
|
Packit |
df99a1 |
const unsigned char * const runs_pos_start=runs_pos;
|
|
Packit |
df99a1 |
append_line(runs_pos,row,ncolumns);
|
|
Packit |
df99a1 |
pos+=(size_t)runs_pos-(size_t)runs_pos_start;
|
|
Packit |
df99a1 |
row -= bytes_per_row;
|
|
Packit |
df99a1 |
n -= 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// return result
|
|
Packit |
df99a1 |
gruns.resize(pos);
|
|
Packit |
df99a1 |
gpruns.swap(gruns);
|
|
Packit |
df99a1 |
return pos;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::decode(unsigned char *runs)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
// initialize pixel array
|
|
Packit |
df99a1 |
if (nrows==0 || ncolumns==0)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.not_init") );
|
|
Packit |
df99a1 |
bytes_per_row = ncolumns + border;
|
|
Packit |
df99a1 |
if (runs==0)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.null_arg") );
|
|
Packit |
df99a1 |
int npixels = nrows * bytes_per_row + border;
|
|
Packit |
df99a1 |
if (!bytes_data)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
gbytes_data.resize(npixels);
|
|
Packit |
df99a1 |
bytes = bytes_data;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
gbytes_data.clear();
|
|
Packit |
df99a1 |
gzerobuffer=zeroes(bytes_per_row + border);
|
|
Packit |
df99a1 |
// interpret runs data
|
|
Packit |
df99a1 |
int c, n;
|
|
Packit |
df99a1 |
unsigned char p = 0;
|
|
Packit |
df99a1 |
unsigned char *row = bytes_data + border;
|
|
Packit |
df99a1 |
n = nrows - 1;
|
|
Packit |
df99a1 |
row += n * bytes_per_row;
|
|
Packit |
df99a1 |
c = 0;
|
|
Packit |
df99a1 |
while (n >= 0)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int x = read_run(runs);
|
|
Packit |
df99a1 |
if (c+x > ncolumns)
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.lost_sync2") );
|
|
Packit |
df99a1 |
while (x-- > 0)
|
|
Packit |
df99a1 |
row[c++] = p;
|
|
Packit |
df99a1 |
p = 1 - p;
|
|
Packit |
df99a1 |
if (c >= ncolumns)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
c = 0;
|
|
Packit |
df99a1 |
p = 0;
|
|
Packit |
df99a1 |
row -= bytes_per_row;
|
|
Packit |
df99a1 |
n -= 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
// Free rle data possibly attached to this bitmap
|
|
Packit |
df99a1 |
grle.resize(0);
|
|
Packit |
df99a1 |
grlerows.resize(0);
|
|
Packit |
df99a1 |
rlelength = 0;
|
|
Packit |
df99a1 |
#ifndef NDEBUG
|
|
Packit |
df99a1 |
check_border();
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
class GBitmap::ZeroBuffer : public GPEnabled
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
public:
|
|
Packit |
df99a1 |
ZeroBuffer(const unsigned int zerosize);
|
|
Packit |
df99a1 |
unsigned char *zerobuffer;
|
|
Packit |
df99a1 |
GPBuffer<unsigned char> gzerobuffer;
|
|
Packit |
df99a1 |
};
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GBitmap::ZeroBuffer::ZeroBuffer(const unsigned int zerosize)
|
|
Packit |
df99a1 |
: gzerobuffer(zerobuffer,zerosize)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
gzerobuffer.clear();
|
|
Packit |
df99a1 |
GBitmap::zerobuffer=zerobuffer;
|
|
Packit |
df99a1 |
GBitmap::zerosize=zerosize;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static const unsigned char static_zerobuffer[]=
|
|
Packit |
df99a1 |
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 32
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 64
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 96
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 128
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 160
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 192
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 234
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 256
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 288
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 320
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 352
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 384
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 416
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 448
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 480
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 512
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 544
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 576
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 608
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 640
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 672
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 704
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 736
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 768
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 800
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 832
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 864
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 896
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 928
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 960
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 992
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+32
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+64
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+96
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+128
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+160
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+192
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+234
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+256
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+288
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+320
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+352
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+384
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+416
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+448
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+480
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+512
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+544
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+576
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+608
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+640
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+672
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+704
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+736
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+768
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+800
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+832
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+864
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+896
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+928
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+960
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 1024+992
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+32
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+64
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+96
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+128
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+160
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+192
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+234
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+256
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+288
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+320
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+352
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+384
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+416
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+448
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+480
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+512
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+544
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+576
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+608
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+640
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+672
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+704
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+736
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+768
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+800
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+832
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+864
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+896
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+928
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+960
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 2048+992
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+32
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+64
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+96
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+128
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+160
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+192
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+234
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+256
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+288
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+320
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+352
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+384
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+416
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+448
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+480
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+512
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+544
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+576
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+608
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+640
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+672
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+704
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+736
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+768
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+800
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+832
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+864
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+896
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+928
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+960
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 3072+992
|
|
Packit |
df99a1 |
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // 4096
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
int GBitmap::zerosize = sizeof(static_zerobuffer);
|
|
Packit |
df99a1 |
unsigned char *GBitmap::zerobuffer=const_cast<unsigned char *>(static_zerobuffer);
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GBitmap::ZeroBuffer>
|
|
Packit |
df99a1 |
GBitmap::zeroes(int required)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(&monitors[0]); // any monitor would do
|
|
Packit |
df99a1 |
static GP<GBitmap::ZeroBuffer> gzerobuffer;
|
|
Packit |
df99a1 |
if (zerosize < required)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int z;
|
|
Packit |
df99a1 |
for(z=zerosize;z
|
|
Packit |
df99a1 |
EMPTY_LOOP;
|
|
Packit |
df99a1 |
z=(z+0xfff)&(~0xfff);
|
|
Packit |
df99a1 |
gzerobuffer=new GBitmap::ZeroBuffer((unsigned int)z);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return gzerobuffer;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
// Fills a bitmap with the given value
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::fill(unsigned char value)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
for(unsigned int y=0; y
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
unsigned char* bm_y = (*this)[y];
|
|
Packit |
df99a1 |
for(unsigned int x=0; x
|
|
Packit |
df99a1 |
bm_y[x] = value;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::append_long_run(unsigned char *&data, int count)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
while (count > MAXRUNSIZE)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
data[0] = data[1] = 0xff;
|
|
Packit |
df99a1 |
data[2] = 0;
|
|
Packit |
df99a1 |
data += 3;
|
|
Packit |
df99a1 |
count -= MAXRUNSIZE;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if (count < RUNOVERFLOWVALUE)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
data[0] = count;
|
|
Packit |
df99a1 |
data += 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
data[0] = (count>>8) + GBitmap::RUNOVERFLOWVALUE;
|
|
Packit |
df99a1 |
data[1] = (count & 0xff);
|
|
Packit |
df99a1 |
data += 2;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::append_line(unsigned char *&data,const unsigned char *row,
|
|
Packit |
df99a1 |
const int rowlen,bool invert)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const unsigned char *rowend=row+rowlen;
|
|
Packit |
df99a1 |
bool p=!invert;
|
|
Packit |
df99a1 |
while(row
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
int count=0;
|
|
Packit |
df99a1 |
if ((p=!p))
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if(*row)
|
|
Packit |
df99a1 |
for(++count,++row;(row
|
|
Packit |
df99a1 |
EMPTY_LOOP;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
else if(!*row)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
for(++count,++row;(row
|
|
Packit |
df99a1 |
EMPTY_LOOP;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
append_run(data,count);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#if 0
|
|
Packit |
df99a1 |
static inline int
|
|
Packit |
df99a1 |
GetRowTDLRNR(
|
|
Packit |
df99a1 |
GBitmap &bit,const int row, const unsigned char *&startptr,
|
|
Packit |
df99a1 |
const unsigned char *&stopptr)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
stopptr=(startptr=bit[row])+bit.columns();
|
|
Packit |
df99a1 |
return 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static inline int
|
|
Packit |
df99a1 |
GetRowTDLRNR(
|
|
Packit |
df99a1 |
GBitmap &bit,const int row, const unsigned char *&startptr,
|
|
Packit |
df99a1 |
const unsigned char *&stopptr)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
stopptr=(startptr=bit[row])+bit.columns();
|
|
Packit |
df99a1 |
return 1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
static inline int
|
|
Packit |
df99a1 |
GetRowTDRLNR(
|
|
Packit |
df99a1 |
GBitmap &bit,const int row, const unsigned char *&startptr,
|
|
Packit |
df99a1 |
const unsigned char *&stopptr)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
startptr=(stopptr=bit[row]-1)+bit.columns();
|
|
Packit |
df99a1 |
return -1;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
#endif // 0
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
GP<GBitmap>
|
|
Packit |
df99a1 |
GBitmap::rotate(int count)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
GP<GBitmap> newbitmap=this;
|
|
Packit |
df99a1 |
count = count & 3;
|
|
Packit |
df99a1 |
if(count)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
if( count & 0x01 )
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
newbitmap = new GBitmap(ncolumns, nrows);
|
|
Packit |
df99a1 |
}else
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
newbitmap = new GBitmap(nrows, ncolumns);
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
GMonitorLock lock(monitor());
|
|
Packit |
df99a1 |
if (!bytes_data)
|
|
Packit |
df99a1 |
uncompress();
|
|
Packit |
df99a1 |
GBitmap &dbitmap = *newbitmap;
|
|
Packit |
df99a1 |
dbitmap.set_grays(grays);
|
|
Packit |
df99a1 |
switch(count)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
case 3: // rotate 90 counter clockwise
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const int lastrow = dbitmap.rows()-1;
|
|
Packit |
df99a1 |
for(int y=0; y
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const unsigned char *r=operator[] (y);
|
|
Packit |
df99a1 |
for(int x=0,xnew=lastrow;xnew>=0; x++,xnew--)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
dbitmap[xnew][y] = r[x];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
case 2: // rotate 180 counter clockwise
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const int lastrow = dbitmap.rows()-1;
|
|
Packit |
df99a1 |
const int lastcolumn = dbitmap.columns()-1;
|
|
Packit |
df99a1 |
for(int y=0,ynew=lastrow;ynew>=0; y++,ynew--)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const unsigned char *r=operator[] (y);
|
|
Packit |
df99a1 |
unsigned char *d=dbitmap[ynew];
|
|
Packit |
df99a1 |
for(int xnew=lastcolumn;xnew>=0; r++,--xnew)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
d[xnew] = *r;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
case 1: // rotate 270 counter clockwise
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const int lastcolumn = dbitmap.columns()-1;
|
|
Packit |
df99a1 |
for(int y=0,ynew=lastcolumn;ynew>=0;y++,ynew--)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const unsigned char *r=operator[] (y);
|
|
Packit |
df99a1 |
for(int x=0; x
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
dbitmap[x][ynew] = r[x];
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
break;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
if(grays == 2)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
compress();
|
|
Packit |
df99a1 |
dbitmap.compress();
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
return newbitmap;
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#ifndef NDEBUG
|
|
Packit |
df99a1 |
void
|
|
Packit |
df99a1 |
GBitmap::check_border() const
|
|
Packit |
df99a1 |
{int col ;
|
|
Packit |
df99a1 |
if (bytes)
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
const unsigned char *p = (*this)[-1];
|
|
Packit |
df99a1 |
for (col=-border; col
|
|
Packit |
df99a1 |
if (p[col])
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.zero_damaged") );
|
|
Packit |
df99a1 |
for (int row=0; row
|
|
Packit |
df99a1 |
{
|
|
Packit |
df99a1 |
p = (*this)[row];
|
|
Packit |
df99a1 |
for (col=-border; col<0; col++)
|
|
Packit |
df99a1 |
if (p[col])
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.left_damaged") );
|
|
Packit |
df99a1 |
for (col=ncolumns; col
|
|
Packit |
df99a1 |
if (p[col])
|
|
Packit |
df99a1 |
G_THROW( ERR_MSG("GBitmap.right_damaged") );
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
|
|
Packit |
df99a1 |
#ifdef HAVE_NAMESPACES
|
|
Packit |
df99a1 |
}
|
|
Packit |
df99a1 |
# ifndef NOT_USING_DJVU_NAMESPACE
|
|
Packit |
df99a1 |
using namespace DJVU;
|
|
Packit |
df99a1 |
# endif
|
|
Packit |
df99a1 |
#endif
|
|
Packit |
df99a1 |
|