📄 kfaximage.cpp
字号:
/* This file is part of KDE FAX image library Copyright (c) 2005 Helge Deller <deller@kde.org> based on Frank D. Cringle's viewfax package Copyright (C) 1990, 1995 Frank D. Cringle. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License version 2 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.*/#include <config.h>#include <stdlib.h>#include <qimage.h>#include <qfile.h>#include <kglobal.h>#include <klocale.h>#include "faxexpand.h"#include "kfaximage.h"#include "kdebug.h"static const char FAXMAGIC[] = "\000PC Research, Inc\000\000\000\000\000\000";static const char littleTIFF[] = "\x49\x49\x2a\x00";static const char bigTIFF[] = "\x4d\x4d\x00\x2a";KFaxImage::KFaxImage( const QString &filename, QObject *parent, const char *name ) : QObject(parent){ setObjectName(QLatin1String(name)); KGlobal::locale()->insertCatalog( QString::fromLatin1("libkfaximage") ); loadImage(filename);}KFaxImage::~KFaxImage(){ }bool KFaxImage::loadImage( const QString &filename ){ reset(); m_filename = filename; m_errorString = QString::null; if (m_filename.isEmpty()) return false; int ok = notetiff(); if (!ok) { reset(); } return ok == 1;}void KFaxImage::reset(){ fax_init_tables(); qDeleteAll(m_pagenodes); m_pagenodes.clear(); // do not reset m_errorString and m_filename, since // they may be needed by calling application }QImage KFaxImage::page( int pageNr ){ if (pageNr < 0 || pageNr >= numPages()) { kDebug() << "KFaxImage::page() called with invalid page number\n"; return QImage(); } pagenode *pn = m_pagenodes.at(pageNr); GetImage(pn); return pn->image;}QPoint KFaxImage::page_dpi( int pageNr ){ if (pageNr < 0 || pageNr >= numPages()) { kDebug() << "KFaxImage::page_dpi() called with invalid page number\n"; return QPoint(0,0); } pagenode *pn = m_pagenodes.at(pageNr); GetImage(pn); return pn->dpi;}QSize KFaxImage::page_size( int pageNr ){ if (pageNr < 0 || pageNr >= numPages()) { kDebug() << "KFaxImage::page_size() called with invalid page number\n"; return QSize(0,0); } pagenode *pn = m_pagenodes.at(pageNr); GetImage(pn); return pn->size;}pagenode *KFaxImage::AppendImageNode(int type){ pagenode *pn = new pagenode(); if (pn) { pn->type = type; pn->expander = g31expand; pn->strips = NULL; pn->size = QSize(1728,2339); pn->vres = -1; pn->dpi = KFAX_DPI_FINE; m_pagenodes.append(pn); } return pn;}bool KFaxImage::NewImage(pagenode *pn, int w, int h){ pn->image = QImage( w, h, 1, 2, QImage::systemByteOrder() ); pn->image.setColor(0, qRgb(255,255,255)); pn->image.setColor(1, qRgb(0,0,0)); pn->data = (quint16*) pn->image.bits(); pn->bytes_per_line = pn->image.bytesPerLine(); pn->dpi = KFAX_DPI_FINE; return !pn->image.isNull();}void KFaxImage::FreeImage(pagenode *pn){ pn->image = QImage(); pn->data = NULL; pn->bytes_per_line = 0;}void KFaxImage::kfaxerror(const QString& error){ m_errorString = error; kError() << "kfaxerror: " << error << endl;}/* Enter an argument in the linked list of pages */pagenode *KFaxImage::notefile(int type){ pagenode *newnode = new pagenode(); newnode->type = type; newnode->size = QSize(1728,0); return newnode;}static t32bitsget4(unsigned char *p, QImage::Endian endian){ return (endian == QImage::BigEndian) ? (p[0]<<24)|(p[1]<<16)|(p[2]<<8)|p[3] : p[0]|(p[1]<<8)|(p[2]<<16)|(p[3]<<24);}static intget2(unsigned char *p, QImage::Endian endian){ return (endian == QImage::BigEndian) ? (p[0]<<8)|p[1] : p[0]|(p[1]<<8);}/* generate pagenodes for the images in a tiff file */intKFaxImage::notetiff(){#define SC(x) (char *)(x) unsigned char header[8]; QImage::Endian endian; t32bits IFDoff; pagenode *pn = NULL; QString str; QFile file(filename()); if (!file.open(QIODevice::ReadOnly)) { kfaxerror(i18n("Unable to open file for reading.")); return 0; } if (file.read(SC(header), 8) != 8) { kfaxerror(i18n("Unable to read file header (file too short).")); return 0; } if (memcmp(header, &littleTIFF, 4) == 0) endian = QImage::LittleEndian; else if (memcmp(header, &bigTIFF, 4) == 0) endian = QImage::BigEndian; else { maybe_RAW_FAX: kfaxerror(i18n("This is not a TIFF FAX file.")); // AppendImageNode(FAX_RAW); return 0; } IFDoff = get4(header+4, endian); if (IFDoff & 1) { goto maybe_RAW_FAX; } do { /* for each page */ unsigned char buf[8]; unsigned char *dir = NULL , *dp = NULL; int ndirent; pixnum iwidth = 1728; pixnum iheight = 2339; int inverse = false; int lsbfirst = 0; int t4opt = 0, comp = 0; int orient = TURN_NONE; int yres = 196; /* 98.0 */ struct strip *strips = NULL; unsigned int rowsperstrip = 0; t32bits nstrips = 1; if (!file.seek(IFDoff)) { realbad: kfaxerror( i18n("Invalid or incomplete TIFF file.") ); bad: if (strips) free(strips); if (dir) free(dir); file.close(); return 1; } if (file.read(SC(buf), 2) != 2) goto realbad; ndirent = get2(buf, endian); int len = 12*ndirent+4; dir = (unsigned char *) malloc(len); if (file.read(SC(dir), len) != len) goto realbad; for (dp = dir; ndirent; ndirent--, dp += 12) { /* for each directory entry */ int tag, ftype; t32bits count, value = 0; tag = get2(dp, endian); ftype = get2(dp+2, endian); count = get4(dp+4, endian); switch(ftype) { /* value is offset to list if count*size > 4 */ case 3: /* short */ value = get2(dp+8, endian); break; case 4: /* long */ value = get4(dp+8, endian); break; case 5: /* offset to rational */ value = get4(dp+8, endian); break; } switch(tag) { case 256: /* ImageWidth */ iwidth = value; break; case 257: /* ImageLength */ iheight = value; break; case 259: /* Compression */ comp = value; break; case 262: /* PhotometricInterpretation */ inverse ^= (value == 1); break; case 266: /* FillOrder */ lsbfirst = (value == 2); break; case 273: /* StripOffsets */ nstrips = count; strips = (struct strip *) malloc(count * sizeof *strips); if (count == 1 || (count == 2 && ftype == 3)) { strips[0].offset = value; if (count == 2) strips[1].offset = get2(dp+10, endian); break; } if (!file.seek(value)) goto realbad; for (count = 0; count < nstrips; count++) { if (file.read(SC(buf), (ftype == 3) ? 2 : 4) <= 0) goto realbad; strips[count].offset = (ftype == 3) ? get2(buf, endian) : get4(buf, endian); } break; case 274: /* Orientation */ switch(value) { default: /* row0 at top, col0 at left */ orient = 0; break; case 2: /* row0 at top, col0 at right */ orient = TURN_M; break; case 3: /* row0 at bottom, col0 at right */ orient = TURN_U; break; case 4: /* row0 at bottom, col0 at left */ orient = TURN_U|TURN_M; break; case 5: /* row0 at left, col0 at top */ orient = TURN_M|TURN_L; break; case 6: /* row0 at right, col0 at top */ orient = TURN_U|TURN_L; break; case 7: /* row0 at right, col0 at bottom */ orient = TURN_U|TURN_M|TURN_L; break; case 8: /* row0 at left, col0 at bottom */ orient = TURN_L; break; } break; case 278: /* RowsPerStrip */ rowsperstrip = value; break; case 279: /* StripByteCounts */ if (count != nstrips) { str = i18n("In file %1\nStripsPerImage tag 273=%2,tag279=%3\n", filename(), nstrips, count); kfaxerror(str); goto realbad; } if (count == 1 || (count == 2 && ftype == 3)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -