Various bug fixes and large TIFF-related stuff

git-svn-id: svn://ultimatepp.org/upp/trunk@1618 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
rylek 2009-10-09 08:19:39 +00:00
parent 6912d67577
commit 1491b6b82e
2 changed files with 93 additions and 22 deletions

View file

@ -167,7 +167,7 @@ void LineDraw::Set(Draw& _draw, LineStyle pattern, Color color, int width, doubl
}
first = last = Null;
Size size = draw->GetPageSize();
clip = draw->GetPageSize(); // GetClip()
clip = draw->GetPaintRect();
max_rad = max(size.cx, size.cy);
vertices.Clear();
indices.Clear();
@ -607,7 +607,7 @@ void Plotter::Set(Draw& _draw, Sizef _scale, Pointf _delta, int reserve, double
void Plotter::Set(Draw& _draw, const Matrixf& matrix, int reserve, double meter)
{
Rect rc = _draw.GetPageSize(); //GetClip();
Rect rc = _draw.GetPaintRect();
if(reserve < 0)
reserve = DotsToPixels(_draw, -reserve);
rc.Inflate(reserve);
@ -1581,7 +1581,7 @@ void AreaTool::Paint()
{
if(!plotter.draw)
return;
if(!(plotter.clip.Intersects(plotter.draw->GetPageSize /*GetClip*/()))) {
if(!(plotter.clip.Intersects(plotter.draw->GetPaintRect()))) {
Clear();
return;
}
@ -2599,7 +2599,7 @@ public:
void TestWindow::Paint(Draw& draw)
{
draw.DrawRect(draw.GetClip(), LtCyan);
draw.DrawRect(draw.GetPaintRect(), LtCyan);
Plotter plotter(draw);
PathTool path;
path.Set(plotter, SolidLine);

View file

@ -540,8 +540,10 @@ struct TIFRaster::Data : public TIFFRGBAImage {
bool Create();
Raster::Info GetInfo();
Raster::Line GetLine(int i);
Raster::Line GetLine(int i, Raster *owner);
bool SeekPage(int page);
bool FetchPage();
void CloseTmpFile();
static void Warning(const char* module, const char* fmt, va_list ap);
static void Error(const char* module, const char* fmt, va_list ap);
@ -572,7 +574,11 @@ struct TIFRaster::Data : public TIFFRGBAImage {
int row_bytes;
int cache_size;
bool alpha;
bool page_open;
bool page_fetched;
bool page_error;
Vector<byte> imagebuf;
String tmpfile;
FileStream filebuffer;
struct Row {
Row() : x(0), size(0) {}
@ -820,16 +826,22 @@ TIFRaster::Data::Data(Stream& stream)
{
tiff = NULL;
page_index = 0;
cache_size = 0;
page_open = false;
page_fetched = false;
page_error = false;
}
TIFRaster::Data::~Data()
{
if(tiff)
if(tiff) {
if(page_open)
TIFFRGBAImageEnd(this);
CloseTmpFile();
TIFFClose(tiff);
}
}
bool TIFRaster::Data::Create()
{
tiff = TIFFStreamOpen("tiff@" + Format64((intptr_t)this), "r", &stream);
@ -868,15 +880,30 @@ bool TIFRaster::Data::Create()
return SeekPage(0);
}
bool TIFRaster::Data::SeekPage(int page)
bool TIFRaster::Data::SeekPage(int pgx)
{
TIFFSetDirectory(tiff, page_index = page);
if(page_open) {
TIFFRGBAImageEnd(this);
page_open = false;
}
ASSERT(pgx >= 0 && pgx < pages.GetCount());
page_index = pgx;
page_error = false;
TIFFSetDirectory(tiff, page_index);
CloseTmpFile();
char emsg[1024];
if(!TIFFRGBAImageBegin(this, tiff, 0, emsg)) {
TIFFError(TIFFFileName(tiff), emsg);
page_error = true;
return false;
}
page_open = true;
const Page& page = pages[page_index];
size = Size(page.width, page.height);
if(isContig) {
contig = put.contig;
put.contig = putContigRGB;
@ -922,19 +949,42 @@ bool TIFRaster::Data::SeekPage(int page)
}
skewfac = 8 / bitspersample;
}
size = Size(width, height);
row_bytes = (bpp * width + 31) >> 5 << 2;
page_fetched = false;
return true;
}
void TIFRaster::Data::CloseTmpFile()
{
if(filebuffer.IsOpen()) {
filebuffer.Close();
FileDelete(tmpfile);
}
tmpfile = Null;
}
bool TIFRaster::Data::FetchPage()
{
if(page_error)
return false;
if(page_fetched)
return true;
cache_size = 0;
rows.Clear();
int64 bytes = row_bytes * (int64)height;
String tmpfile;
if(bytes >= 100000000) {
if(bytes >= 1 << 28) {
tmpfile = GetTempFileName();
if(!filebuffer.Open(tmpfile, FileStream::CREATE))
if(!filebuffer.Open(tmpfile, FileStream::CREATE)) {
page_error = true;
return false;
}
filebuffer.SetSize(bytes);
if(filebuffer.IsError()) {
filebuffer.Close();
FileDelete(tmpfile);
page_error = true;
return false;
}
rows.Alloc(size.cy);
@ -946,23 +996,27 @@ bool TIFRaster::Data::SeekPage(int page)
bool res = TIFFRGBAImageGet(this, 0, width, height);
TIFFRGBAImageEnd(this);
page_open = false;
if(filebuffer.IsOpen()) {
Flush();
if(filebuffer.IsError() || !res) {
filebuffer.Close();
FileDelete(tmpfile);
page_error = true;
return false;
}
imagebuf.SetCount(size.cy * row_bytes);
filebuffer.Seek(0);
filebuffer.GetAll(imagebuf.Begin(), imagebuf.GetCount());
filebuffer.Close();
FileDelete(tmpfile);
// imagebuf.SetCount(size.cy * row_bytes);
// filebuffer.Seek(0);
// filebuffer.GetAll(imagebuf.Begin(), imagebuf.GetCount());
// filebuffer.Close();
// FileDelete(tmpfile);
}
// imagebuf.SetDotSize(pages[page_index].dot_size);
// dest_image.palette = palette;
// return dest_image;
page_fetched = true;
return true;
}
@ -978,6 +1032,23 @@ Raster::Info TIFRaster::Data::GetInfo()
return out;
}
Raster::Line TIFRaster::Data::GetLine(int line, Raster *raster)
{
if(!page_error && !page_fetched)
FetchPage();
if(page_error) {
byte *tmp = new byte[row_bytes];
memset(tmp, 0, row_bytes);
return Raster::Line(tmp, raster, true);
}
if(!imagebuf.IsEmpty())
return Raster::Line(&imagebuf[row_bytes * line], raster, false);
const byte *data = MapDown(0, line, row_bytes, raster);
byte *tmp = new byte[row_bytes];
memcpy(tmp, data, row_bytes);
return Raster::Line(tmp, raster, true);
}
TIFRaster::TIFRaster()
{
}
@ -1004,7 +1075,7 @@ Raster::Info TIFRaster::GetInfo()
Raster::Line TIFRaster::GetLine(int line)
{
return Raster::Line(&data->imagebuf[data->row_bytes * line], this, false);
return data->GetLine(line, this);
}
int TIFRaster::GetPaletteCount()
@ -1146,7 +1217,7 @@ void TIFEncoder::Data::Start(Size sz, int bpp_, const RGBA *palette)
TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, size.cx);
TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, size.cy);
TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, min<int>(bpp, 8));
TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_PACKBITS);
TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, bpp <= 8 ? PHOTOMETRIC_PALETTE : PHOTOMETRIC_RGB);
TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, bpp <= 8 ? 1 : bpp != 32 ? 3 : 4);
TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, 1);