summaryrefslogtreecommitdiff
Side-by-side diff
Diffstat (more/less context) (show whitespace changes)
-rw-r--r--noncore/apps/opie-reader/CDrawBuffer.cpp211
-rw-r--r--noncore/apps/opie-reader/plucker.cpp579
2 files changed, 790 insertions, 0 deletions
diff --git a/noncore/apps/opie-reader/CDrawBuffer.cpp b/noncore/apps/opie-reader/CDrawBuffer.cpp
new file mode 100644
index 0000000..2ceb2d5
--- a/dev/null
+++ b/noncore/apps/opie-reader/CDrawBuffer.cpp
@@ -0,0 +1,211 @@
+
+#include "CDrawBuffer.h"
+#include "FontControl.h"
+#include <qfontmetrics.h>
+#include <qpainter.h>
+
+void CDrawBuffer::setright(CDrawBuffer& rhs, int f)
+{
+ int i;
+// qDebug("Trying 1:%d:%s", f, (const char*)toQString(rhs.data()));
+ len = rhs.len;
+ m_maxstyle = rhs.m_maxstyle;
+ m_ascent = rhs.m_ascent;
+ m_descent = rhs.m_descent;
+ m_lineSpacing = rhs.m_lineSpacing;
+ while (!segs.isEmpty()) segs.erase(0);
+ for (CList<textsegment>::iterator iter = rhs.segs.begin(); iter != rhs.segs.end(); )
+ {
+ CList<textsegment>::iterator next = iter;
+ iter++;
+ if (iter == rhs.segs.end() || iter->start > f)
+ {
+ int st = next->start-f;
+ if (st < 0) st = 0;
+ segs.push_back(textsegment(st,next->style));
+ }
+ }
+ for (i = f; rhs[i] != '\0'; i++) (*this)[i-f] = rhs[i];
+ (*this)[i-f] = '\0';
+ len = i;
+// qDebug("Tried 1");
+}
+
+CDrawBuffer& CDrawBuffer::operator=(CDrawBuffer& rhs)
+{
+ int i;
+// qDebug("Trying 2");
+ len = rhs.len;
+ m_maxstyle = rhs.m_maxstyle;
+ m_ascent = rhs.m_ascent;
+ m_descent = rhs.m_descent;
+ m_lineSpacing = rhs.m_lineSpacing;
+ while (!segs.isEmpty()) segs.erase(0);
+ for (CList<textsegment>::iterator iter = rhs.segs.begin(); iter != rhs.segs.end(); iter++)
+ {
+ segs.push_back(*iter);
+ }
+ for (i = 0; rhs[i] != '\0'; i++) (*this)[i] = rhs[i];
+ (*this)[i] = '\0';
+ len = i;
+// qDebug("Tried 2");
+ return *this;
+}
+
+CDrawBuffer& CDrawBuffer::operator=(const tchar*sztmp)
+{
+ int i;
+ while (!segs.isEmpty()) segs.erase(0);
+ segs.push_back(textsegment(0, CStyle()));
+ for (i = 0; sztmp[i] != '\0'; i++) (*this)[i] = sztmp[i];
+ (*this)[i] = '\0';
+ len = i;
+ return *this;
+}
+
+void CDrawBuffer::empty()
+{
+ len = 0;
+ (*this)[0] = 0;
+ while (!segs.isEmpty()) segs.erase(0);
+ segs.push_back(textsegment(0,CStyle()));
+ m_maxstyle = m_ascent = m_descent = m_lineSpacing = 0;
+}
+
+void CDrawBuffer::addch(tchar ch, CStyle _style/* = ucFontBase*/)
+{
+ if (len == 0)
+ {
+ int thissize = fc->getsize(_style);
+ m_maxstyle = thissize;
+ m_ascent = fc->ascent(_style);
+ m_descent = fc->descent(_style);
+ m_lineSpacing = fc->lineSpacing(_style);
+ segs.first().start = 0;
+ segs.first().style = _style;
+ }
+ else if (_style != segs.last().style)
+ {
+ int thissize = fc->getsize(_style);
+ if (thissize > m_maxstyle)
+ {
+ m_maxstyle = thissize;
+ m_ascent = fc->ascent(_style);
+ m_descent = fc->descent(_style);
+ m_lineSpacing = fc->lineSpacing(_style);
+ }
+ segs.push_back(textsegment(len, _style));
+ }
+ (*this)[len++] = ch;
+}
+
+void CDrawBuffer::truncate(int n)
+{
+ len = n;
+ (*this)[n] = 0;
+}
+
+int CDrawBuffer::width(int numchars = -1)
+{
+ int currentx = 0, end = 0;
+ QString text = toQString(data());
+ CList<textsegment>::iterator textstart = segs.begin();
+ CList<textsegment>::iterator textend = textstart;
+ do
+ {
+ textend++;
+ end = (textend != segs.end()) ? textend->start : length();
+ if (numchars >= 0 && end > numchars)
+ {
+ end = numchars;
+ }
+ CStyle currentstyle = textstart->style;
+ QFont f(fc->name(), fc->getsize(currentstyle), (currentstyle.isBold()) ? QFont::Bold : QFont::Normal, (currentstyle.isItalic()) );
+ QString str = text.mid(textstart->start, end-textstart->start);
+ QFontMetrics fm(f);
+ currentx += fm.width(str);
+ textstart = textend;
+ }
+ while (textend != segs.end() && end != numchars);
+ return currentx;
+}
+
+void CDrawBuffer::render(QPainter* _p, int _y, bool _bMono, int _charWidth, int scwidth)
+{
+ int currentx = 0;
+ QString text = toQString(data());
+ CList<textsegment>::iterator textstart = segs.begin();
+ StyleType align = textstart->style.getJustify();
+ switch (align)
+ {
+ case CStyle::m_AlignRight:
+ {
+// int linelength = width();
+ currentx = scwidth - width();
+ }
+ break;
+ case CStyle::m_AlignCentre:
+ {
+// int linelength = width();
+ currentx = (scwidth - width())/2;
+ }
+ break;
+ case CStyle::m_AlignJustify:
+ case CStyle::m_AlignLeft:
+ break;
+ }
+ CList<textsegment>::iterator textend = textstart;
+ do
+ {
+ textend++;
+ int end = (textend != segs.end()) ? textend->start : length();
+ CStyle currentstyle = textstart->style;
+ QFont f(fc->name(), fc->getsize(currentstyle), (currentstyle.isBold()) ? QFont::Bold : QFont::Normal, (currentstyle.isItalic()) );
+ _p->setFont(f);
+ QString str = text.mid(textstart->start, end-textstart->start);
+ _p->setPen(QColor(currentstyle.Red(), currentstyle.Green(), currentstyle.Blue()));
+ if (_bMono)
+ {
+ for (int i = 0; i < str.length(); i++)
+ {
+ _p->drawText( currentx + i*_charWidth, _y, QString(str[i]));
+ }
+ currentx += str.length()*_charWidth;
+ }
+ else
+ {
+ _p->drawText( currentx, _y, str);
+ QFontMetrics fm(f);
+ currentx += fm.width(str);
+ }
+ textstart = textend;
+ }
+ while (textend != segs.end());
+}
+
+CStyle CDrawBuffer::laststyle()
+{
+ return segs.last().style;
+}
+
+bool CDrawBuffer::isLink(int numchars, size_t& tgt)
+{
+ int end = 0;
+ CStyle currentstyle;
+ CList<textsegment>::iterator textstart = segs.begin();
+ CList<textsegment>::iterator textend = textstart;
+ do
+ {
+ textend++;
+ end = (textend != segs.end()) ? textend->start : length();
+ if (numchars >= 0 && end > numchars)
+ {
+ end = numchars;
+ }
+ currentstyle = textstart->style;
+ textstart = textend;
+ }
+ while (textend != segs.end() && end != numchars);
+ tgt = currentstyle.getData();
+ return currentstyle.getLink();
+}
diff --git a/noncore/apps/opie-reader/plucker.cpp b/noncore/apps/opie-reader/plucker.cpp
new file mode 100644
index 0000000..ddda4bc
--- a/dev/null
+++ b/noncore/apps/opie-reader/plucker.cpp
@@ -0,0 +1,579 @@
+#include <stdio.h>
+#include <string.h>
+#include <qmessagebox.h>
+#include "plucker.h"
+
+#include "Aportis.h"
+
+CPlucker::CPlucker() : expandedtextbuffer(NULL), compressedtextbuffer(NULL) { /*printf("constructing:%x\n",fin);*/ }
+
+
+int CPlucker::openfile(const char *src)
+{
+ if (!Cpdb::openfile(src))
+ {
+ return -1;
+ }
+
+//printf("Okay %u\n", 4);
+
+ if (memcmp(&head.type, "DataPlkr", 8) != 0) return -1;
+
+// qDebug("Cool - this IS plucker");
+
+ textlength = 0;
+ for (int recptr = 1; recptr < ntohs(head.recordList.numRecords); recptr++)
+ {
+ CPlucker_dataRecord thisHdr;
+ gotorecordnumber(recptr);
+ fread(&thisHdr, 1, sizeof(thisHdr), fin);
+ if (thisHdr.type < 2) textlength += htons(thisHdr.size);
+ }
+
+ gotorecordnumber(0);
+ fread(&hdr0, 1, sizeof(hdr0), fin);
+//printf("Okay %u\n", 5);
+ buffersize = 32*1024;
+ compressedtextbuffer = new UInt8[buffersize];
+ expandedtextbuffer = new UInt8[buffersize];
+
+// qDebug("Total number of records:%u", ntohs(head.recordList.numRecords));
+
+ unsigned int nrecs = ntohs(hdr0.nRecords);
+// qDebug("Version %u, no. res %u", ntohs(hdr0.version), nrecs);
+ for (unsigned int i = 0; i < 4*nrecs; i++)
+ {
+ UInt8 id;
+ fread(&id, 1, sizeof(id), fin);
+// qDebug("%x", id);
+ }
+ home();
+ return 0;
+}
+
+int CPlucker::bgetch()
+{
+ int ch = EOF;
+ if (bufferpos >= buffercontent)
+ {
+ if (bufferrec >= ntohs(head.recordList.numRecords) - 1) return EOF;
+// qDebug("Passing through %u", currentpos);
+ if (!expand(bufferrec+1)) return EOF;
+ mystyle.unset();
+ }
+
+ if (bufferpos == m_nextPara)
+ {
+ UInt16 attr = m_ParaAttrs[m_nextParaIndex];
+ m_nextParaIndex++;
+ if (m_nextParaIndex == m_nParas)
+ {
+ m_nextPara = -1;
+ }
+ else
+ {
+ m_nextPara += m_ParaOffsets[m_nextParaIndex];
+ }
+// qDebug("New paragraph");
+ ch = 10;
+ }
+ else
+ {
+ currentpos++;
+ ch = expandedtextbuffer[bufferpos++];
+ }
+ return ch;
+}
+
+int CPlucker::getch()
+{
+ int ch = bgetch();
+ while (ch == 0)
+ {
+ ch = bgetch();
+// qDebug("Function:%x", ch);
+ switch (ch)
+ {
+ case 0x38:
+ ch = 10;
+ break;
+ case 0x0a:
+ case 0x0c:
+ {
+ unsigned long ln = 0;
+ int skip = ch & 7;
+ for (int i = 0; i < 2; i++)
+ {
+ int ch = bgetch();
+ ln = (ln << 8) + ch;
+// qDebug("ch:%d, ln:%u", ch, ln);
+ }
+ if (skip == 2)
+ {
+ ln <<= 16;
+ }
+ else
+ {
+ for (int i = 0; i < 2; i++)
+ {
+ int ch = bgetch();
+ ln = (ln << 8) + ch;
+// qDebug("ch:%d, ln:%u", ch, ln);
+ }
+ }
+// qDebug("ln:%u", ln);
+ mystyle.setLink(true);
+ mystyle.setData(ln);
+ mystyle.setColour(255, 0, 0);
+ ch = bgetch();
+ }
+ break;
+ case 0x08:
+ ch = bgetch();
+ mystyle.setColour(0, 0, 0);
+ mystyle.setLink(false);
+ mystyle.setData(0);
+ break;
+ case 0x40:
+ mystyle.setItalic();
+ ch = bgetch();
+ break;
+ case 0x48:
+ mystyle.unsetItalic();
+ ch = bgetch();
+ break;
+ case 0x11:
+ {
+ ch = bgetch();
+ qDebug("Font:%d",ch);
+ switch (ch)
+ {
+ case 0:
+ mystyle.unsetBold();
+ mystyle.setFontSize(0);
+ break;
+ case 1:
+ mystyle.setBold();
+ mystyle.setFontSize(1);
+ break;
+ case 2:
+ mystyle.setBold();
+ mystyle.setFontSize(1);
+ break;
+ case 3:
+// mystyle.setBold();
+ mystyle.setFontSize(1);
+ break;
+ case 4:
+// mystyle.setBold();
+ mystyle.setFontSize(1);
+ break;
+ case 5:
+ mystyle.setBold();
+ mystyle.setFontSize(0);
+ break;
+ case 6:
+ mystyle.setBold();
+ mystyle.setFontSize(0);
+ break;
+ case 7:
+ mystyle.setBold();
+ mystyle.setFontSize(0);
+ break;
+ case 8: // should be fixed width
+ mystyle.unsetBold();
+ mystyle.setFontSize(0);
+ break;
+ default:
+ mystyle.unsetBold();
+ mystyle.setFontSize(0);
+ break;
+ }
+ ch = bgetch();
+ }
+ break;
+ case 0x29:
+ ch = bgetch();
+ switch (ch)
+ {
+ case 0:
+ mystyle.setLeftJustify();
+// qDebug("left");
+ break;
+ case 1:
+ mystyle.setRightJustify();
+// qDebug("right");
+ break;
+ case 2:
+ mystyle.setCentreJustify();
+// qDebug("centre");
+ break;
+ case 3:
+ mystyle.setFullJustify();
+// qDebug("full");
+ break;
+
+ }
+ ch = bgetch();
+ break;
+ case 0x53:
+ {
+ int r = bgetch();
+ int g = bgetch();
+ int b = bgetch();
+ mystyle.setColour(r,g,b);
+ ch = bgetch();
+ }
+ break;
+ case 0x1a:
+/*
+ {
+ UInt16 ir = bgetch();
+ ir = (ir << 8) + bgetch();
+ expandimg(ir);
+ }
+ ch = bgetch();
+ break;
+*/
+ case 0x33:
+ case 0x22:
+ case 0x5c:
+ case 0x60:
+ case 0x68:
+ case 0x70:
+ case 0x78:
+ case 0x83:
+ case 0x85:
+ default:
+ qDebug("Function:%x NOT IMPLEMENTED", ch);
+ {
+ int skip = ch & 7;
+ for (int i = 0; i < skip; i++)
+ {
+ ch = bgetch();
+ qDebug("Arg %d, %d", i, ch);
+ }
+ ch = bgetch();
+ }
+ }
+ }
+ return ch;
+}
+
+void CPlucker::getch(int& ch, CStyle& sty)
+{
+ ch = getch();
+ sty = mystyle;
+}
+
+unsigned int CPlucker::locate()
+{
+ return currentpos;
+/*
+ UInt16 thisrec = 1;
+ unsigned long locpos = 0;
+ gotorecordnumber(thisrec);
+ CPlucker_dataRecord thisHdr;
+ while (thisrec < bufferrec)
+ {
+ fread(&thisHdr, 1, sizeof(thisHdr), fin);
+ if (thisHdr.type < 2) locpos += htons(thisHdr.size);
+ thisrec++;
+ gotorecordnumber(thisrec);
+ }
+ return locpos+bufferpos;
+*/
+}
+
+void CPlucker::locate(unsigned int n)
+{
+ UInt16 thisrec = 0;
+ unsigned long locpos = 0;
+ unsigned long bs = 0;
+ CPlucker_dataRecord thisHdr;
+ do
+ {
+ thisrec++;
+ locpos += bs;
+ gotorecordnumber(thisrec);
+ fread(&thisHdr, 1, sizeof(thisHdr), fin);
+ if (thisHdr.type < 2)
+ {
+ bs = htons(thisHdr.size);
+ }
+ else
+ {
+ bs = 0;
+ }
+ } while (locpos + bs < n);
+ currentpos = locpos;
+ expand(thisrec);
+ while (currentpos < n && bufferpos < buffercontent) bgetch();
+}
+
+bool CPlucker::hyperlink(unsigned int n)
+{
+ UInt16 tuid = (n >> 16);
+ n &= 0xffff;
+ UInt16 thisrec = 1;
+ currentpos = 0;
+ gotorecordnumber(thisrec);
+ CPlucker_dataRecord thisHdr;
+ while (1)
+ {
+ fread(&thisHdr, 1, sizeof(thisHdr), fin);
+ if (tuid <= htons(thisHdr.uid)) break;
+ if (thisHdr.type < 2) currentpos += htons(thisHdr.size);
+// qDebug("hyper-cp:%u", currentpos);
+ thisrec++;
+ gotorecordnumber(thisrec);
+ }
+ if (thisHdr.type > 1)
+ {
+ QMessageBox::information(NULL,
+ QString("OpieReader"),
+ QString("External links\nnot yet supported")
+ );
+ return false;
+ }
+ else
+ {
+ expand(thisrec);
+ while (bufferpos < n && bufferpos < buffercontent) getch();
+ }
+ return true;
+}
+
+bool CPlucker::expand(int thisrec)
+{
+ mystyle.unset();
+ size_t reclen = recordlength(thisrec);
+ gotorecordnumber(thisrec);
+ CPlucker_dataRecord thisHdr;
+ while (1)
+ {
+ fread(&thisHdr, 1, sizeof(thisHdr), fin);
+// qDebug("This (%d) type is %d, uid is %u", thisrec, thisHdr.type, ntohs(thisHdr.uid));
+ if (thisHdr.type < 2) break;
+ qDebug("Skipping paragraph of type %d", thisHdr.type);
+ if (++thisrec >= ntohs(head.recordList.numRecords) - 1) return false;
+ reclen = recordlength(thisrec);
+ gotorecordnumber(thisrec);
+ }
+ m_nParas = ntohs(thisHdr.nParagraphs);
+// qDebug("It has %u paragraphs and is %u bytes", htons(thisHdr.nParagraphs), htons(thisHdr.size));
+ uid = ntohs(thisHdr.uid);
+ for (int i = 0; i < m_nParas; i++)
+ {
+ UInt16 ubytes, attrs;
+ fread(&ubytes, 1, sizeof(ubytes), fin);
+ fread(&attrs, 1, sizeof(attrs), fin);
+ m_ParaOffsets[i] = ntohs(ubytes);
+ m_ParaAttrs[i] = ntohs(attrs);
+// qDebug("Bytes %u, Attr %x", ntohs(ubytes), attrs);
+ }
+ if (m_nParas > 0)
+ {
+ m_nextPara = m_ParaOffsets[0];
+// qDebug("First offset = %u", m_nextPara);
+ m_nextParaIndex = 0;
+ }
+ else
+ {
+ m_nextPara = -1;
+ }
+
+ reclen -= sizeof(thisHdr)+4*m_nParas;
+
+ buffercontent = htons(thisHdr.size);
+
+ if (thisHdr.type == 0)
+ {
+ fread(expandedtextbuffer, reclen, sizeof(char), fin);
+ }
+ else
+ {
+ fread(compressedtextbuffer, reclen, sizeof(char), fin);
+ switch (ntohs(hdr0.version))
+ {
+ case 2:
+ UnZip(reclen, expandedtextbuffer, buffercontent);
+ break;
+ case 1:
+ UnDoc(reclen, expandedtextbuffer, buffercontent);
+ break;
+ }
+ }
+ bufferpos = 0;
+ bufferrec = thisrec;
+// qDebug("BC:%u, HS:%u", buffercontent, ntohs(thisHdr.size));
+ return true;
+}
+
+void CPlucker::UnZip(size_t reclen, UInt8* tgtbuffer, UInt16 bsize)
+{
+ z_stream zstream;
+ memset(&zstream,sizeof(zstream),0);
+ zstream.next_in = compressedtextbuffer;
+ zstream.next_out = tgtbuffer;
+ zstream.avail_out = bsize;
+ zstream.avail_in = reclen;
+
+ int keylen = 0;
+
+ zstream.zalloc = Z_NULL;
+ zstream.zfree = Z_NULL;
+ zstream.opaque = Z_NULL;
+
+// printf("Initialising\n");
+
+ inflateInit(&zstream);
+ int err = 0;
+ do {
+ if ( zstream.avail_in == 0 && 0 < keylen ) {
+ zstream.next_in = compressedtextbuffer + keylen;
+ zstream.avail_in = reclen - keylen;
+ keylen = 0;
+ }
+ zstream.next_out = tgtbuffer;
+ zstream.avail_out = bsize;
+
+ err = inflate( &zstream, Z_SYNC_FLUSH );
+
+ } while ( err == Z_OK );
+
+ inflateEnd(&zstream);
+}
+
+void CPlucker::UnDoc(size_t reclen, UInt8* tgtbuffer, UInt16 bsize)
+{
+// UInt16 headerSize;
+ UInt16 docSize;
+ UInt16 i;
+ UInt16 j;
+ UInt16 k;
+
+ UInt8 *inBuf = compressedtextbuffer;
+ UInt8 *outBuf = tgtbuffer;
+
+// headerSize = sizeof( Header ) + record->paragraphs * sizeof( Paragraph );
+ docSize = reclen;
+
+ j = 0;
+ k = 0;
+ while ( j < docSize ) {
+ i = 0;
+ while ( i < bsize && j < docSize ) {
+ UInt16 c;
+
+ c = (UInt16) inBuf[ j++ ];
+ if ( 0 < c && c < 9 ) {
+ while ( 0 < c-- )
+ outBuf[ i++ ] = inBuf[ j++ ];
+ }
+ else if ( c < 0x80 )
+ outBuf[ i++ ] = c;
+ else if ( 0xc0 <= c ) {
+ outBuf[ i++ ] = ' ';
+ outBuf[ i++ ] = c ^ 0x80;
+ }
+ else {
+ Int16 m;
+ Int16 n;
+
+ c <<= 8;
+ c += inBuf[ j++ ];
+
+ m = ( c & 0x3fff ) >> COUNT_BITS;
+ n = c & ( ( 1 << COUNT_BITS ) - 1 );
+ n += 2;
+
+ do {
+ outBuf[ i ] = outBuf[ i - m ];
+ i++;
+ } while ( 0 < n-- );
+ }
+ }
+ k += bsize;
+ }
+}
+
+void CPlucker::home()
+{
+ currentpos = 0;
+ expand(1);
+}
+
+CList<Bkmk>* CPlucker::getbkmklist()
+{
+/*
+ CPlucker_dataRecord thisHdr;
+
+ for (int i = 1; i < ntohs(head.recordList.numRecords); i++)
+ {
+ gotorecordnumber(i);
+ fread(&thisHdr, 1, sizeof(thisHdr), fin);
+ if (thisHdr.type == 8)
+ {
+ UInt16 n;
+ fread(&n, 1, sizeof(n), fin);
+ n = ntohs(n);
+ qDebug("Found %u bookmarks", n);
+ }
+ qDebug("Found:%d, %u", i , thisHdr.type);
+ }
+*/
+ return NULL;
+}
+
+void CPlucker::expandimg(UInt16 tgt)
+{
+ qDebug("Image:%u", tgt);
+ CPlucker_dataRecord thisHdr;
+ size_t reclen;
+ UInt16 thisrec = 0;
+ do
+ {
+ thisrec++;
+ reclen = recordlength(thisrec);
+ gotorecordnumber(thisrec);
+ qDebug("thisrec:%u.%u", ftell(fin),thisrec);
+ fread(&thisHdr, 1, sizeof(thisHdr), fin);
+ }
+ while (ntohs(thisHdr.uid) != tgt);
+
+ reclen -= sizeof(thisHdr);
+
+ UInt16 imgsize = htons(thisHdr.size);
+ UInt8* imgbuffer = new UInt8[imgsize];
+
+ qDebug("type:%u", thisHdr.type);
+
+ if (thisHdr.type == 2)
+ {
+ qDebug("Not compressed:%u.%u", ftell(fin),reclen);
+ fread(imgbuffer, reclen, sizeof(char), fin);
+ qDebug("Not compressed:%u.%u", ftell(fin),reclen);
+ }
+ else
+ {
+ qDebug("Compressed");
+ fread(compressedtextbuffer, reclen, sizeof(char), fin);
+ switch (ntohs(hdr0.version))
+ {
+ case 2:
+ UnZip(reclen, imgbuffer, imgsize);
+ break;
+ case 1:
+ UnDoc(reclen, imgbuffer, imgsize);
+ break;
+ }
+ }
+ FILE* imgfile = fopen("/home/tim/newreader/imagefile.tbmp", "w");
+ if (imgfile != NULL)
+ {
+ fwrite(imgbuffer, 1, imgsize, imgfile);
+ fclose(imgfile);
+ }
+ delete [] imgbuffer;
+}