📄 kfaximage.cpp.svn-base
字号:
strips[0].size = value; if (count == 2) strips[1].size = 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].size = (ftype == 3) ? get2(buf, endian) : get4(buf, endian); } break; case 283: /* YResolution */ if (!file.seek(value) || file.read(SC(buf), 8) != 8) goto realbad; yres = get4(buf, endian) / get4(buf+4, endian); break; case 292: /* T4Options */ t4opt = value; break; case 293: /* T6Options */ /* later */ break; case 296: /* ResolutionUnit */ if (value == 3) yres = (yres * 254) / 100; /* *2.54 */ break; } } IFDoff = get4(dp, endian); free(dir); dir = NULL; if (comp == 5) { // compression type 5 is LZW compression // XXX kfaxerror(i18n("Due to patent reasons LZW (Lempel-Ziv & Welch) " "compressed Fax files cannot be loaded yet.\n")); goto bad; } if (comp < 2 || comp > 4) { kfaxerror(i18n("This version can only handle Fax files\n")); goto bad; } pn = AppendImageNode(FAX_TIFF); pn->nstrips = nstrips; pn->rowsperstrip = nstrips > 1 ? rowsperstrip : iheight; pn->strips = strips; pn->size = QSize(iwidth,iheight); pn->inverse = inverse; pn->lsbfirst = lsbfirst; pn->orient = orient; pn->dpi.setY(yres); pn->vres = (yres > 150) ? 1:0; /* arbitrary threshold for fine resolution */ if (comp == 2) pn->expander = MHexpand; else if (comp == 3) pn->expander = (t4opt & 1) ? g32expand : g31expand; else pn->expander = g4expand; } while (IFDoff); file.close(); return 1;#undef UC}/* report error and remove bad file from the list */voidKFaxImage::badfile(pagenode *pn){ kfaxerror(i18n("%1: Bad Fax File", filename())); FreeImage(pn);}/* rearrange input bits into t16bits lsb-first chunks */static voidnormalize(pagenode *pn, int revbits, int swapbytes, size_t length){ t32bits *p = (t32bits *) pn->data; kDebug() << "normalize = " << ((revbits<<1)|swapbytes) << endl; switch ((revbits<<1)|swapbytes) { case 0: break; case 1: for ( ; length; length -= 4) { t32bits t = *p; *p++ = ((t & 0xff00ff00) >> 8) | ((t & 0x00ff00ff) << 8); } break; case 2: for ( ; length; length -= 4) { t32bits t = *p; t = ((t & 0xf0f0f0f0) >> 4) | ((t & 0x0f0f0f0f) << 4); t = ((t & 0xcccccccc) >> 2) | ((t & 0x33333333) << 2); *p++ = ((t & 0xaaaaaaaa) >> 1) | ((t & 0x55555555) << 1); } break; case 3: for ( ; length; length -= 4) { t32bits t = *p; t = ((t & 0xff00ff00) >> 8) | ((t & 0x00ff00ff) << 8); t = ((t & 0xf0f0f0f0) >> 4) | ((t & 0x0f0f0f0f) << 4); t = ((t & 0xcccccccc) >> 2) | ((t & 0x33333333) << 2); *p++ = ((t & 0xaaaaaaaa) >> 1) | ((t & 0x55555555) << 1); } }}/* get compressed data into memory */unsigned char *KFaxImage::getstrip(pagenode *pn, int strip){ size_t offset, roundup; unsigned char *Data; union { t16bits s; unsigned char b[2]; } so;#define ShortOrder so.b[1] so.s = 1; /* XXX */ QFile file(filename()); if (!file.open(QIODevice::ReadOnly)) { badfile(pn); return NULL; } if (pn->strips == NULL) { offset = 0; pn->length = file.size(); } else if (strip < pn->nstrips) { offset = pn->strips[strip].offset; pn->length = pn->strips[strip].size; } else { kfaxerror( i18n("Trying to expand too many strips.") ); return NULL; } /* round size to full boundary plus t32bits */ roundup = (pn->length + 7) & ~3; Data = (unsigned char *) malloc(roundup); /* clear the last 2 t32bits, to force the expander to terminate even if the file ends in the middle of a fax line */ *((t32bits *) Data + roundup/4 - 2) = 0; *((t32bits *) Data + roundup/4 - 1) = 0; /* we expect to get it in one gulp... */ if (!file.seek(offset) || (size_t) file.read((char *)Data, pn->length) != pn->length) { badfile(pn); free(Data); return NULL; } file.close(); pn->data = (t16bits *) Data; if (pn->strips == NULL && memcmp(Data, FAXMAGIC, sizeof(FAXMAGIC)-1) == 0) { /* handle ghostscript / PC Research fax file */ if (Data[24] != 1 || Data[25] != 0){ kfaxerror( i18n("Only the first page of the PC Research multipage file will be shown.") ); } pn->length -= 64; pn->vres = Data[29]; pn->data += 32; roundup -= 64; } normalize(pn, !pn->lsbfirst, ShortOrder, roundup); if (pn->size.height() == 0) pn->size.setHeight( G3count(pn, pn->expander == g32expand) ); if (pn->size.height() == 0) { kfaxerror( i18n("No fax found in file.") ); badfile(pn); free(Data); return NULL; } if (pn->strips == NULL) pn->rowsperstrip = pn->size.height(); return Data;}static voiddrawline(pixnum *run, int LineNum, pagenode *pn){ t32bits *p, *p1; /* p - current line, p1 - low-res duplicate */ pixnum *r; /* pointer to run-lengths */ t32bits pix; /* current pixel value */ t32bits acc; /* pixel accumulator */ int nacc; /* number of valid bits in acc */ int tot; /* total pixels in line */ int n; LineNum += pn->stripnum * pn->rowsperstrip; if (LineNum >= pn->size.height()) { if (LineNum == pn->size.height()) kError() << "Height exceeded\n"; return; } p = (t32bits *) pn->image.scanLine(LineNum*(2-pn->vres)); p1 =(t32bits *)( pn->vres ? 0 : pn->image.scanLine(1+LineNum*(2-pn->vres))); r = run; acc = 0; nacc = 0; pix = pn->inverse ? ~0 : 0; tot = 0; while (tot < pn->size.width()) { n = *r++; tot += n; /* Watch out for buffer overruns, e.g. when n == 65535. */ if (tot > pn->size.width()) break; if (pix) acc |= (~(t32bits)0 >> nacc); else if (nacc) acc &= (~(t32bits)0 << (32 - nacc)); else acc = 0; if (nacc + n < 32) { nacc += n; pix = ~pix; continue; } *p++ = acc; if (p1) *p1++ = acc; n -= 32 - nacc; while (n >= 32) { n -= 32; *p++ = pix; if (p1) *p1++ = pix; } acc = pix; nacc = n; pix = ~pix; } if (nacc) { *p++ = acc; if (p1) *p1++ = acc; }}intKFaxImage::GetPartImage(pagenode *pn, int n){ unsigned char *Data = getstrip(pn, n); if (Data == 0) return 3; pn->stripnum = n; (*pn->expander)(pn, drawline); free(Data); return 1;}int KFaxImage::GetImage(pagenode *pn){ if (!pn->image.isNull()) return 1; int i; if (pn->strips == 0) { kDebug() << "Loading RAW fax file " << m_filename << " size=" << pn->size << endl; /* raw file; maybe we don't have the height yet */ unsigned char *Data = getstrip(pn, 0); if (Data == 0){ return 0; } if (!NewImage(pn, pn->size.width(), (pn->vres ? 1:2) * pn->size.height())) return 0; (*pn->expander)(pn, drawline); } else { /* multi-strip tiff */ kDebug() << "Loading MULTI STRIP TIFF fax file " << m_filename << endl; if (!NewImage(pn, pn->size.width(), (pn->vres ? 1:2) * pn->size.height())) return 0; pn->stripnum = 0; kDebug() << "has " << pn->nstrips << " strips.\n"; for (i = 0; i < pn->nstrips; i++){ int k = GetPartImage(pn, i); if ( k == 3 ){ FreeImage(pn); kfaxerror( i18n("Fax G3 format not yet supported.") ); return k; } } } // byte-swapping the image on little endian machines#if defined(Q_BYTE_ORDER) && (Q_BYTE_ORDER == Q_LITTLE_ENDIAN) for (int y=pn->image.height()-1; y>=0; --y) { quint32 *source = (quint32 *) pn->image.scanLine(y); quint32 *dest = source; for (int x=(pn->bytes_per_line/4)-1; x>=0; --x) { quint32 dv = 0, sv = *source; for (int bit=32; bit>0; --bit) { dv <<= 1; dv |= sv&1; sv >>= 1; } *dest = dv; ++dest; ++source; } }#endif kDebug() << filename() << "\n\tsize = " << pn->size << "\n\tDPI = " << pn->dpi << "\n\tresolution = " << (pn->vres ? "fine" : "normal") << endl; return 1;}#include "kfaximage.moc"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -