?? imgtiff.cpp
字號:
/********************************************************************** * File: imgtiff.c (Formerly tiff.c) * Description: Max format image reader/writer. * Author: Ray Smith * Created: Mon Jun 11 14:00:21 BST 1990 * * (C) Copyright 1990, Hewlett-Packard Ltd. ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** http://www.apache.org/licenses/LICENSE-2.0 ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. * **********************************************************************/#include "mfcpch.h" //precompiled headers#ifdef __MSW32__#include <io.h>#else#include <unistd.h>#endif/*** Include automatically generated configuration file if running autoconf*/#ifdef HAVE_CONFIG_H#include "config_auto.h"#if defined(MOTOROLA_BYTE_ORDER) || defined(WORDS_BIGENDIAN)#define __MOTO__ // Big-endian.#endif#endif#include "fileerr.h"#include "imgerrs.h"#include "img.h"#include "bitstrm.h"#include "tprintf.h"#include "serialis.h"#include "imgtiff.h"#define INTEL 0x4949#define MOTO 0x4d4d/************************************************************************* * NOTE ON BIG-ENDIAN vs LITTLE-ENDIAN * * Intel machines store numbers with LSByte in the left position. * Motorola (and PA_RISC) machines use the opposite byte ordering. * * This code is written so that: * a) it will compile and run on EITHER machine type AND * b) the program (on either machine) will process tiff file written in either * Motorola or Intel format. * * The code is compiled with a __NATIVE__ define which is either MOTO or INTEL. * MOTO and INTEL are defined (above) to be the value of the first two bytes of * a tiff file in either format. (This identifies the filetype). * * Subsequent reads and writes normally just reverse the byte order if the * machine type (__NATIVE__) is not equal to the filetype determined from the * first two bytes of the tiff file. * * A special case is the "value" field of the tag structure. This can contain * EITHER a 16bit or a 32bit value. According to the "type" field. The 4 cases * of machine type / file type combinations need to be treated differently in * the case of 16 bit values *************************************************************************/#define ENTRIES 19 /*no of entries */#define START 8 /*start of tag table */typedef struct{ uinT16 tag; //entry tag uinT16 type; uinT32 length; inT32 value;} TIFFENTRY; //tiff tag entrytypedef struct myrational{ inT32 top; inT32 bottom;} MYRATIONAL; //type 5//statics for the run length codes#define EOL_CODE 0x800#define EOL_MASK 0xfff#define EOL_LENGTH 12 //12 bits#define SHORT_CODE_SIZE 64 //no of short codes#define LONG_CODE_SIZE 40 //no of long codesstatic uinT16 short_white_codes[SHORT_CODE_SIZE] = { 0xac, 0x38, 0xe, 0x1, 0xd, 0x3, 0x7, 0xf, 0x19, 0x5, 0x1c, 0x2, 0x4, 0x30, 0xb, 0x2b, 0x15, 0x35, 0x72, 0x18, 0x8, 0x74, 0x60, 0x10, 0xa, 0x6a, 0x64, 0x12, 0xc, 0x40, 0xc0, 0x58, 0xd8, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x20, 0xa0, 0x50, 0xd0, 0x4a, 0xca, 0x2a, 0xaa, 0x24, 0xa4, 0x1a, 0x9a, 0x5a, 0xda, 0x52, 0xd2, 0x4c, 0xcc, 0x2c};static uinT8 short_white_lengths[SHORT_CODE_SIZE] = { 8, 6, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8};static uinT16 short_black_codes[SHORT_CODE_SIZE] = { 0x3b0, 0x2, 0x3, 0x1, 0x6, 0xc, 0x4, 0x18, 0x28, 0x8, 0x10, 0x50, 0x70, 0x20, 0xe0, 0x30, 0x3a0, 0x60, 0x40, 0x730, 0xb0, 0x1b0, 0x760, 0xa0, 0x740, 0xc0, 0x530, 0xd30, 0x330, 0xb30, 0x160, 0x960, 0x560, 0xd60, 0x4b0, 0xcb0, 0x2b0, 0xab0, 0x6b0, 0xeb0, 0x360, 0xb60, 0x5b0, 0xdb0, 0x2a0, 0xaa0, 0x6a0, 0xea0, 0x260, 0xa60, 0x4a0, 0xca0, 0x240, 0xec0, 0x1c0, 0xe40, 0x140, 0x1a0, 0x9a0, 0xd40, 0x340, 0x5a0, 0x660, 0xe60};static uinT8 short_black_lengths[SHORT_CODE_SIZE] = { 10, 3, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 7, 8, 8, 9, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12};static uinT16 long_white_codes[LONG_CODE_SIZE] = { 0x1b, 0x9, 0x3a, 0x76, 0x6c, 0xec, 0x26, 0xa6, 0x16, 0xe6, 0x66, 0x166, 0x96, 0x196, 0x56, 0x156, 0xd6, 0x1d6, 0x36, 0x136, 0xb6, 0x1b6, 0x32, 0x132, 0xb2, 0x6, 0x1b2, 0x80, 0x180, 0x580, 0x480, 0xc80, 0x280, 0xa80, 0x680, 0xe80, 0x380, 0xb80, 0x780, 0xf80};static uinT8 long_white_lengths[LONG_CODE_SIZE] = { 5, 5, 6, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12};static uinT16 long_black_codes[LONG_CODE_SIZE] = { 0x3c0, 0x130, 0x930, 0xda0, 0xcc0, 0x2c0, 0xac0, 0x6c0, 0x16c0, 0xa40, 0x1a40, 0x640, 0x1640, 0x9c0, 0x19c0, 0x5c0, 0x15c0, 0xdc0, 0x1dc0, 0x940, 0x1940, 0x540, 0x1540, 0xb40, 0x1b40, 0x4c0, 0x14c0, 0x80, 0x180, 0x580, 0x480, 0xc80, 0x280, 0xa80, 0x680, 0xe80, 0x380, 0xb80, 0x780, 0xf80};static uinT8 long_black_lengths[LONG_CODE_SIZE] = { 10, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12};/********************************************************************** * open_tif_image * * Read the header of a tif format image and prepare to read the rest. **********************************************************************/inT8 open_tif_image( //read header int fd, //file to read inT32 *xsize, //size of image inT32 *ysize, inT8 *bpp, //bits per pixel inT8 *photo, //interpretation inT32 *res //resolution ) { inT16 filetype; inT32 start; //start of tiff directory inT16 entries; //no of tiff entries inT32 imagestart; //location of image in file inT32 resoffset; //location of res TIFFENTRY tiffentry; //tag table entry BOOL8 compressed; //compression control MYRATIONAL resinfo; //resolution BOOL8 strips = false; //if in strips *xsize = -1; //illegal values *ysize = -1; *bpp = -1; *res = -1; resoffset = -1; if (read (fd, (char *) &filetype, sizeof filetype) != sizeof filetype || (filetype != INTEL && filetype != MOTO)) { BADIMAGEFORMAT.error ("read_tif_image", TESSLOG, "Filetype"); return -1; } lseek (fd, 4L, 0); if (read (fd, (char *) &start, sizeof start) != sizeof start) { READFAILED.error ("read_tif_image", TESSLOG, "Start of tag table"); return -1; } if (filetype != __NATIVE__) start = reverse32 (start); if (start <= 0) { BADIMAGEFORMAT.error ("read_tif_image", TESSLOG, "Start of tag table"); return -1; } lseek (fd, start, 0); if (read (fd, (char *) &entries, sizeof (inT16)) != sizeof (inT16)) { BADIMAGEFORMAT.error ("read_tif_image", TESSLOG, "Size of tag table"); return -1; } if (filetype != __NATIVE__) entries = reverse16 (entries); // printf("No of tiff directory entries=%d\n",entries); imagestart = 0; compressed = FALSE; for (; entries-- > 0;) { if (read (fd, (char *) &tiffentry, sizeof tiffentry) != sizeof tiffentry) { BADIMAGEFORMAT.error ("read_tif_image", TESSLOG, "Tag table entry"); return -1; } if (filetype != __NATIVE__) { tiffentry.type = reverse16 (tiffentry.type); tiffentry.tag = reverse16 (tiffentry.tag); tiffentry.length = reverse32 (tiffentry.length); } if (tiffentry.type != 3) { //Full 32bit value if (filetype != __NATIVE__) tiffentry.value = reverse32 (tiffentry.value); } else { /* A 16bit value in 4 bytes - handle with care. SEE NOTE at start of file */ if (__NATIVE__ == MOTO) { if (filetype == MOTO) //MOTO file on MOTO Machine tiffentry.value = tiffentry.value >> 16; else //INTEL file on MOTO Machine tiffentry.value = reverse32 (tiffentry.value); } else { //INTEL Machine if (filetype == MOTO) //MOTO file on INTEL Machine tiffentry.value = reverse16 ((uinT16) tiffentry.value); //INTEL file on INTEL Machine NO ACTION NEEDED } //Clear top 2 MSBytes tiffentry.value &= 0x0000ffff; } // printf("Tag=%x, Type=%x, Length=%x, value=%x\n", // tiffentry.tag,tiffentry.type,tiffentry.length,tiffentry.value); switch (tiffentry.tag) { case 0x101: *ysize = tiffentry.value; break; case 0x100: *xsize = tiffentry.value; break; case 0x102: if (tiffentry.length == 1) *bpp = (inT8) tiffentry.value; else *bpp = 24; break; case 0x111: imagestart = tiffentry.value; strips = tiffentry.length > 1; break; case 0x103: if (tiffentry.value == 3) { compressed = TRUE; } else if (tiffentry.value != 1) { BADIMAGEFORMAT.error ("read_tif_image", TESSLOG, "Compression"); return -1; } break; case 0x11a: case 0x11b: //resolution resoffset = tiffentry.value; break; case 0x106: *photo = (inT8) tiffentry.value; break; } //endswitch } if (*xsize <= 0 || *ysize <= 0 || *bpp > 24 || imagestart <= 0) { BADIMAGEFORMAT.error ("read_tif_image", TESSLOG, "Vital tag"); return -1; } tprintf ("Image has %d bit%c per pixel and size (%d,%d)\n", *bpp, *bpp == 1 ? ' ' : 's', *xsize, *ysize); if (resoffset >= 0) { lseek (fd, resoffset, 0); if (read (fd, (char *) &resinfo, sizeof (resinfo)) != sizeof (resinfo)) { READFAILED.error ("read_tif_image", TESSLOG, "Resolution"); return -1; } if (filetype != __NATIVE__) { resinfo.top = reverse32 (resinfo.top); resinfo.bottom = reverse32 (resinfo.bottom); } *res = resinfo.top / resinfo.bottom; tprintf ("Resolution=%d\n", *res); } lseek (fd, (long) imagestart, 0); if (strips) { if (read (fd, (char *) &imagestart, sizeof (imagestart)) != sizeof (imagestart)) { READFAILED.error ("read_tif_image", TESSLOG, "Strip offset"); return -1; } if (filetype != __NATIVE__) imagestart = reverse32 (imagestart); //indirection lseek (fd, (long) imagestart, 0); } return compressed ? -2 : 0;}/********************************************************************** * read_tif_image * * Read a whole tif image into memory. **********************************************************************/inT8 read_tif_image( //read whole image int fd, //file to read uinT8 *pixels, //pixels of image inT32 xsize, //size of image inT32 ysize, inT8 bpp, //bits per pixel inT32 //bytes per line ) { inT32 xindex; //indices in image inT32 yindex; inT32 length; //short length inT32 biglength; //extender uinT8 *lengths; //current lengths uinT16 *codes; //current codes uinT16 codeword; //current code word IMAGELINE imageline; //current line IMAGE image; //dummy image
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -