/* pcdtoppm - read PhotoCD files and produce PPM ** ** This is based on hpcdtoppm 0.6, see below for copyright. ** Basically all I did is rip out lots of features that duplicated ** pbmplus functionality, such as subrectangles and flipping. -JP */ /* hpcdtoppm (Hadmut's pcdtoppm) v0.6 * Copyright (c) 1992, 1993, 1994 by Hadmut Danisch (danisch@ira.uka.de). * Permission to use and distribute this software and its * documentation for noncommercial use and without fee is hereby granted, * provided that the above copyright notice appear in all copies and that * both that copyright notice and this permission notice appear in * supporting documentation. It is not allowed to sell this software in * any way. This software is not public domain. */ #include #include #include #include #include "ppm.h" /* define LONG_HELP or SHORT_HELP, if you want to have an options list if parameters are bad */ #define LONG_HELP /* define FASTHUFF for faster Huffman decoding with tables. ** this makes a little speedup, but needs about 768 KByte memory */ #define FASTHUFF /* define SMALLNAMES if the filenames of PhotoCD have small letters on your filesystem */ #define SMALLNAMES /* The separator between directory- and filenames */ #define DIRSEP '/' /** Error detection **/ #define error(x) eerror(x,__FILE__,__LINE__) /* ** Data Types ** Important: sBYTE must be a signed byte type ! ** If your compiler doesn't understand "signed", remove it. */ #ifndef sBYTE typedef signed char sBYTE; #endif typedef unsigned char uBYTE; /* signed and unsigned 32-bit-integers sINT and uINT must at least have 32 bit. If you don't have 32-bit-integers, take 64-bit and define the macro U_TOO_LONG !!! uINT and sINT must be suitable to the printf/scanf-format %d and %u and to the systemcalls as fread etc. */ #define uINT unsigned int #define sINT int /* #define uLONG unsigned long #define sLONG unsigned long */ /* #define U_TOO_LONG */ typedef uINT dim; typedef sINT sdim; /* Floating point data type and string for sscanf */ #define FLTPT double #define SSFLTPT "%lf" /* Default taken when no size parameter given, ** C_DEFAULT depends on your taste and video-hardware, */ #define S_DEFAULT S_Base16 #define C_DEFAULT C_LINEAR /* Maximum Black value of frame for cutting of the ** frame. If MAX_BLACK is n, a frame is detected, when ** all Luma values are within [ 0 .. (n-1) ] */ #define MAX_BLACK 1 /* Format definitions */ #define BaseW ((dim)768) #define BaseH ((dim)512) #define SECSIZE 0x800 #define SeHead 2 #define L_Head (1+SeHead) #define SeBase16 18 #define L_Base16 (1+SeBase16) #define SeBase4 72 #define L_Base4 (1+SeBase4) #define SeBase 288 #define L_Base (1+SeBase) #define neutrLum 128 #define neutrCh1 156 #define neutrCh2 137 /* Structures and definitions */ struct _implane {dim mwidth,mheight, iwidth,iheight; uBYTE *im,*mp; }; typedef struct _implane implane; #define nullplane ((implane *) 0) struct _sizeinfo {dim w,h; /* Image Resolution */ dim rdhoff,rdhlen, rdvoff, rdvlen; /* Size of Image in Memory */ dim imhoff,imhlen, imvoff, imvlen; /* Real Size of Image */ }; typedef struct _sizeinfo sizeinfo; /* Definitions for 64Base */ struct file32 { uBYTE x1,x2,x3,x4;}; struct file16 { uBYTE x1,x2;}; #define FILE32(x) ( (((uINT)x.x1)<<24) | (((uINT)x.x2)<<16) | (((uINT)x.x3)<<8) | (uINT)x.x4 ) #define FILE16(x) ( (((uINT)x.x1)<<8) | (uINT)x.x2 ) struct ic_header {char ic_name[0x28]; struct file16 val1; struct file16 val2; struct file32 off_descr; struct file32 off_fnames; struct file32 off_pointers; struct file32 off_huffman; }; struct ic_descr {struct file16 len; uBYTE color; uBYTE fill; /* Don't know */ struct file16 width; struct file16 height; struct file16 offset; struct file32 length; struct file32 off_pointers; struct file32 off_huffman; }; struct ic_fname {char fname[12]; struct file32 size; }; struct ic_entry {struct file16 fno; struct file32 offset; }; enum TURNS {T_NONE,T_RIGHT,T_LEFT,T_HEAD}; enum SIZES {S_UNSPEC,S_Base16,S_Base4,S_Base,S_4Base,S_16Base,S_64Base}; enum CORR {C_UNSPEC,C_LINEAR,C_DARK,C_BRIGHT }; enum ERRORS {E_NONE,E_READ,E_WRITE,E_INTERN,E_ARG,E_OPT,E_MEM,E_HUFF, E_SEQ,E_SEQ1,E_SEQ2,E_SEQ3,E_SEQ4,E_SEQ5,E_SEQ6,E_SEQ7, E_POS,E_IMP,E_OVSKIP,E_TCANT,E_CONFIG,E_FOPEN }; /**** Macros ****/ #define READBUF READ(sbuffer,sizeof(sbuffer)) #define EREADBUF {if(READBUF < 1) error(E_READ);} #define SKIP(p) { if (SKIPn(p)) error(E_READ);} #define SKIPr(p) { if (SKIPn(p)) return(E_READ);} #define TRIF(x,u,o,a,b,c) ((x)<(u)? (a) : ( (x)>(o)?(c):(b) )) #define xNORM(x) x=TRIF(x,0,255,0,x,255) #define NORM(x) { if(x<0) x=0; else if (x>255) x=255;} #ifndef MIN #define MIN(a,b) (((a) < (b)) ? (a) : (b)) #endif void SEEK(int); int SKIPn(int); int READ(uBYTE *,int); sINT RGB_BitSh1=8; sINT RGB_Maximum1=1023; sINT RGB_F_LL=1391; sINT RGB_F_C1=2271; sINT RGB_O_C1=-353784; sINT RGB_F_C2=1865; sINT RGB_O_C2=-255023; sINT RGB_F_G1=-441; sINT RGB_F_G2=-949; sINT RGB_O_G =199313; uBYTE RGB_corr0[]={ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27, 28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31, 32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39, 40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43, 44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51, 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55, 56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63, 64, 64, 64, 64, 65, 65, 65, 65, 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 69, 69, 69, 70, 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, 79, 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 82, 82, 82, 82, 83, 83, 83, 83, 84, 84, 84, 84, 85, 85, 85, 85, 86, 86, 86, 86, 87, 87, 87, 87, 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90, 90, 91, 91, 91, 91, 92, 92, 92, 92, 93, 93, 93, 93, 94, 94, 94, 94, 95, 95, 95, 95, 96, 96, 96, 96, 97, 97, 97, 97, 98, 98, 98, 98, 99, 99, 99, 99, 100,100,100,100,101,101,101,101,102,102,102,102,103,103,103,103, 104,104,104,104,105,105,105,105,106,106,106,106,107,107,107,107, 108,108,108,108,109,109,109,109,110,110,110,110,111,111,111,111, 112,112,112,112,113,113,113,113,114,114,114,114,115,115,115,115, 116,116,116,116,117,117,117,117,118,118,118,118,119,119,119,119, 120,120,120,120,121,121,121,121,122,122,122,122,123,123,123,123, 124,124,124,124,125,125,125,125,126,126,126,126,127,127,127,127, 128,128,128,128,129,129,129,129,130,130,130,130,131,131,131,131, 132,132,132,132,133,133,133,133,134,134,134,134,135,135,135,135, 136,136,136,136,137,137,137,137,138,138,138,138,139,139,139,139, 140,140,140,140,141,141,141,141,142,142,142,142,143,143,143,143, 144,144,144,144,145,145,145,145,146,146,146,146,147,147,147,147, 148,148,148,148,149,149,149,149,150,150,150,150,151,151,151,151, 152,152,152,152,153,153,153,153,154,154,154,154,155,155,155,155, 156,156,156,156,157,157,157,157,158,158,158,158,159,159,159,159, 160,160,160,160,161,161,161,161,162,162,162,162,163,163,163,163, 164,164,164,164,165,165,165,165,166,166,166,166,167,167,167,167, 168,168,168,168,169,169,169,169,170,170,170,170,171,171,171,171, 172,172,172,172,173,173,173,173,174,174,174,174,175,175,175,175, 176,176,176,176,177,177,177,177,178,178,178,178,179,179,179,179, 180,180,180,180,181,181,181,181,182,182,182,182,183,183,183,183, 184,184,184,184,185,185,185,185,186,186,186,186,187,187,187,187, 188,188,188,188,189,189,189,189,190,190,190,190,191,191,191,191, 192,192,192,192,193,193,193,193,194,194,194,194,195,195,195,195, 196,196,196,196,197,197,197,197,198,198,198,198,199,199,199,199, 200,200,200,200,201,201,201,201,202,202,202,202,203,203,203,203, 204,204,204,204,205,205,205,205,206,206,206,206,207,207,207,207, 208,208,208,208,209,209,209,209,210,210,210,210,211,211,211,211, 212,212,212,212,213,213,213,213,214,214,214,214,215,215,215,215, 216,216,216,216,217,217,217,217,218,218,218,218,219,219,219,219, 220,220,220,220,221,221,221,221,222,222,222,222,223,223,223,223, 224,224,224,224,225,225,225,225,226,226,226,226,227,227,227,227, 228,228,228,228,229,229,229,229,230,230,230,230,231,231,231,231, 232,232,232,232,233,233,233,233,234,234,234,234,235,235,235,235, 236,236,236,236,237,237,237,237,238,238,238,238,239,239,239,239, 240,240,240,240,241,241,241,241,242,242,242,242,243,243,243,243, 244,244,244,244,245,245,245,245,246,246,246,246,247,247,247,247, 248,248,248,248,249,249,249,249,250,250,250,250,251,251,251,251, 252,252,252,252,253,253,253,253,254,254,254,254,255,255,255,255 }; uBYTE RGB_corr1[]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 32, 32, 32, 32, 32, 32, 33, 33, 33, 33, 33, 33, 34, 34, 34, 34, 34, 34, 35, 35, 35, 35, 35, 35, 36, 36, 36, 36, 36, 36, 37, 37, 37, 37, 37, 37, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 40, 40, 40, 40, 40, 41, 41, 41, 41, 41, 41, 42, 42, 42, 42, 42, 43, 43, 43, 43, 43, 44, 44, 44, 44, 44, 45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 46, 47, 47, 47, 47, 47, 48, 48, 48, 48, 49, 49, 49, 49, 49, 50, 50, 50, 50, 50, 51, 51, 51, 51, 51, 52, 52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 54, 55, 55, 55, 55, 55, 56, 56, 56, 56, 57, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59, 60, 60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63, 63, 64, 64, 64, 64, 65, 65, 65, 65, 66, 66, 66, 66, 67, 67, 67, 67, 68, 68, 68, 68, 69, 69, 69, 69, 69, 70, 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, 73, 73, 73, 73, 74, 74, 74, 74, 75, 75, 75, 75, 76, 76, 76, 76, 77, 77, 77, 77, 78, 78, 78, 78, 79, 79, 79, 80, 80, 80, 80, 81, 81, 81, 81, 82, 82, 82, 83, 83, 83, 83, 84, 84, 84, 84, 85, 85, 85, 86, 86, 86, 86, 87, 87, 87, 87, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90, 91, 91, 91, 91, 92, 92, 92, 93, 93, 93, 94, 94, 94, 94, 95, 95, 95, 96, 96, 96, 96, 97, 97, 97, 98, 98, 98, 99, 99, 99, 99,100,100,100,101, 101,101,102,102,102,102,103,103,103,104,104,104,105,105,105,106, 106,106,107,107,107,107,108,108,108,109,109,109,110,110,110,111, 111,111,112,112,112,113,113,113,114,114,114,114,115,115,115,116, 116,116,117,117,117,118,118,118,119,119,119,120,120,120,121,121, 121,122,122,122,123,123,123,124,124,124,125,125,126,126,126,127, 127,127,128,128,128,129,129,129,130,130,130,131,131,131,132,132, 132,133,133,134,134,134,135,135,135,136,136,136,137,137,137,138, 138,139,139,139,140,140,140,141,141,141,142,142,143,143,143,144, 144,144,145,145,146,146,146,147,147,147,148,148,149,149,149,150, 150,150,151,151,152,152,152,153,153,153,154,154,155,155,155,156, 156,157,157,157,158,158,158,159,159,160,160,160,161,161,162,162, 162,163,163,164,164,164,165,165,166,166,166,167,167,168,168,168, 169,169,170,170,170,171,171,172,172,172,173,173,174,174,174,175, 175,176,176,177,177,177,178,178,179,179,179,180,180,181,181,182, 182,182,183,183,184,184,184,185,185,186,186,187,187,187,188,188, 189,189,190,190,190,191,191,192,192,193,193,193,194,194,195,195, 196,196,197,197,197,198,198,199,199,200,200,200,201,201,202,202, 203,203,204,204,204,205,205,206,206,207,207,208,208,209,209,209, 210,210,211,211,212,212,213,213,214,214,214,215,215,216,216,217, 217,218,218,219,219,220,220,220,221,221,222,222,223,223,224,224, 225,225,226,226,227,227,228,228,228,229,229,230,230,231,231,232, 232,233,233,234,234,235,235,236,236,237,237,238,238,239,239,240, 240,241,241,242,242,243,243,244,244,245,245,245,246,246,247,247, 248,248,249,249,250,250,251,251,252,252,253,253,254,254,255,255 }; uBYTE RGB_corr2[]={ 0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 40, 41, 42, 42, 43, 44, 45, 45, 46, 46, 47, 48, 48, 49, 50, 50, 51, 51, 52, 53, 53, 54, 54, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 63, 63, 64, 64, 65, 65, 66, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 73, 73, 73, 74, 74, 75, 75, 76, 76, 76, 77, 77, 78, 78, 79, 79, 79, 80, 80, 81, 81, 81, 82, 82, 83, 83, 83, 84, 84, 85, 85, 85, 86, 86, 86, 87, 87, 88, 88, 88, 89, 89, 89, 90, 90, 91, 91, 91, 92, 92, 92, 93, 93, 93, 94, 94, 95, 95, 95, 96, 96, 96, 97, 97, 97, 98, 98, 98, 99, 99, 99,100,100,100,101,101,101, 102,102,102,103,103,103,104,104,104,104,105,105,105,106,106,106, 107,107,107,108,108,108,109,109,109,109,110,110,110,111,111,111, 112,112,112,112,113,113,113,114,114,114,114,115,115,115,116,116, 116,116,117,117,117,118,118,118,118,119,119,119,120,120,120,120, 121,121,121,121,122,122,122,123,123,123,123,124,124,124,124,125, 125,125,126,126,126,126,127,127,127,127,128,128,128,128,129,129, 129,129,130,130,130,130,131,131,131,131,132,132,132,132,133,133, 133,133,134,134,134,134,135,135,135,135,136,136,136,136,137,137, 137,137,138,138,138,138,139,139,139,139,140,140,140,140,140,141, 141,141,141,142,142,142,142,143,143,143,143,143,144,144,144,144, 145,145,145,145,146,146,146,146,146,147,147,147,147,148,148,148, 148,148,149,149,149,149,150,150,150,150,150,151,151,151,151,152, 152,152,152,152,153,153,153,153,153,154,154,154,154,155,155,155, 155,155,156,156,156,156,156,157,157,157,157,157,158,158,158,158, 159,159,159,159,159,160,160,160,160,160,161,161,161,161,161,162, 162,162,162,162,163,163,163,163,163,164,164,164,164,164,165,165, 165,165,165,166,166,166,166,166,167,167,167,167,167,168,168,168, 168,168,169,169,169,169,169,170,170,170,170,170,171,171,171,171, 171,171,172,172,172,172,172,173,173,173,173,173,174,174,174,174, 174,174,175,175,175,175,175,176,176,176,176,176,177,177,177,177, 177,177,178,178,178,178,178,179,179,179,179,179,179,180,180,180, 180,180,181,181,181,181,181,181,182,182,182,182,182,183,183,183, 183,183,183,184,184,184,184,184,184,185,185,185,185,185,186,186, 186,186,186,186,187,187,187,187,187,187,188,188,188,188,188,189, 189,189,189,189,189,190,190,190,190,190,190,191,191,191,191,191, 191,192,192,192,192,192,192,193,193,193,193,193,193,194,194,194, 194,194,194,195,195,195,195,195,195,196,196,196,196,196,196,197, 197,197,197,197,197,198,198,198,198,198,198,199,199,199,199,199, 199,200,200,200,200,200,200,201,201,201,201,201,201,201,202,202, 202,202,202,202,203,203,203,203,203,203,204,204,204,204,204,204, 205,205,205,205,205,205,205,206,206,206,206,206,206,207,207,207, 207,207,207,207,208,208,208,208,208,208,209,209,209,209,209,209, 210,210,210,210,210,210,210,211,211,211,211,211,211,211,212,212, 212,212,212,212,213,213,213,213,213,213,213,214,214,214,214,214, 214,215,215,215,215,215,215,215,216,216,216,216,216,216,216,217, 217,217,217,217,217,217,218,218,218,218,218,218,219,219,219,219, 219,219,219,220,220,220,220,220,220,220,221,221,221,221,221,221, 221,222,222,222,222,222,222,222,223,223,223,223,223,223,223,224, 224,224,224,224,224,224,225,225,225,225,225,225,225,226,226,226, 226,226,226,226,227,227,227,227,227,227,227,228,228,228,228,228, 228,228,229,229,229,229,229,229,229,230,230,230,230,230,230,230, 231,231,231,231,231,231,231,231,232,232,232,232,232,232,232,233, 233,233,233,233,233,233,234,234,234,234,234,234,234,234,235,235, 235,235,235,235,235,236,236,236,236,236,236,236,237,237,237,237, 237,237,237,237,238,238,238,238,238,238,238,239,239,239,239,239, 239,239,239,240,240,240,240,240,240,240,241,241,241,241,241,241, 241,241,242,242,242,242,242,242,242,243,243,243,243,243,243,243, 243,244,244,244,244,244,244,244,244,245,245,245,245,245,245,245, 246,246,246,246,246,246,246,246,247,247,247,247,247,247,247,247, 248,248,248,248,248,248,248,248,249,249,249,249,249,249,249,249, 250,250,250,250,250,250,250,250,251,251,251,251,251,251,251,252, 252,252,252,252,252,252,252,253,253,253,253,253,253,253,253,254, 254,254,254,254,254,254,254,255,255,255,255,255,255,255,255,255 }; sINT dithtab[]={ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 3, 3, 4, 5, 5, 6, 7, 8, 8, 9, 10, 11, 12, 13, 14, 15, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 29, 30, 31, 32, 34, 35, 36, 37, 39, 40, 42, 43, 44, 46, 47, 49, 50, 51, 53, 54, 56, 57, 59, 60, 62, 64, 65, 67, 68, 70, 71, 73, 75, 76, 78, 80, 81, 83, 85, 86, 88, 90, 91, 93, 95, 96, 98, 100,102,103,105,107,109,110,112,114,116,117,119,121,123,124,126, 128,130,131,133,135,137,138,140,142,144,145,147,149,151,152,154, 156,157,159,161,163,164,166,168,169,171,173,174,176,178,179,181, 183,184,186,187,189,190,192,194,195,197,198,200,201,203,204,206, 207,208,210,211,213,214,215,217,218,219,221,222,223,224,226,227, 228,229,230,231,233,234,235,236,237,238,239,240,241,242,243,243, 244,245,246,247,248,248,249,250,250,251,252,252,253,253,254,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, }; uBYTE sbuffer[SECSIZE]; enum TURNS turn = T_NONE; enum SIZES size = S_UNSPEC; enum CORR corrmode = C_UNSPEC; sINT do_overskip,do_sharp; sINT do_rep,do_crop; sINT bufpos=0; char *pcdname=0; static FILE *fin=0; /* static char *dir64=0; */ static implane Luma, Chroma1,Chroma2; static implane *PLuma,*PChroma1,*PChroma2; static sINT emulate_seek=0; static sINT print_pos; static char dir64[512]; static void get_dir64(void); #define PrintPos(x) {if(print_pos) pm_message("file-offset: %8d = %8x (hex) = %d (sec)",(x),(x),(x)/0x800);} /* Forwards. */ void eerror(enum ERRORS e,char *file,int line); void cropit(sizeinfo *si,implane *l,implane *c1,implane *c2); void shrink(sizeinfo *si,implane *l,implane *c1,implane *c2); void colconvert(sizeinfo *si,implane *l,implane *c1,implane *c2); void clearimpl(implane *l,sINT n); void halve(implane *p); void interpolate(implane *p); sINT Skip4Base(void); void planealloc(implane *p, dim width, dim height); void pastein(implane *gross, dim xpos,dim xw, dim ypos,dim yh, implane *klein, enum TURNS ori); void typecheck(void); void readhqt(sINT n); void readhqtx(sINT n); void decode(sizeinfo *si,int fak,implane *f,implane *f1,implane *f2,sINT autosync); void decodex(FILE **fp, int tag , struct ic_descr *descr,sizeinfo *si,int fak,implane *f,sINT autosync); enum ERRORS readplain(sizeinfo *si,int fak,implane *l,implane *c1,implane *c2); void write_ppm(dim w,dim h, uBYTE *rptr,sdim rzeil,sdim rpix, uBYTE *gptr,sdim gzeil,sdim gpix, uBYTE *bptr,sdim bzeil,sdim bpix); void writepicture(sizeinfo *si, implane *r,implane *g,implane *b, enum TURNS t); static void f_1 (dim,dim,sINT,sINT); static void f_3 (dim,dim,sINT); static void f_4 (dim,dim,sINT); static void f_5 (dim,dim); static void f_6 (dim,dim); static void parseargs(int,char**); static void checkin(void); static void sizecontrol(sizeinfo *,dim,dim,dim sMASK); #define X(a,b) ((a == b) ? "->" : " ") void eerror(enum ERRORS e,char *file,int line) { switch(e) {case E_NONE: return; case E_IMP: pm_message("Sorry, Not yet implemented. [%s:%d]",file,line); break; case E_READ: pm_message("Error while reading."); break; case E_WRITE: pm_message("Error while writing."); break; case E_INTERN: pm_message("Internal error. [%s:%d]",file,line); break; case E_ARG: pm_message("Error in Arguments!"); pm_message(""); #ifdef SHORT_HELP pm_message("Usage: pcdtoppm [options] pcd-file"); pm_message(" ( - means stdin )"); pm_message("Opts: [ -> = Default ]"); pm_message(""); pm_message(" [-x] [-s] [-i]"); pm_message(" [-crop] [-pos] [-rep]"); pm_message(" [-n] [-r] [-l] [-h] [-a]"); pm_message(" [-c0] [-c-] [-c+]"); pm_message(" [-C d s] [-1] [-2] [-3] [-4] [-5] [-6]"); #endif #ifdef LONG_HELP pm_message("Usage: pcdtoppm [options] pcd-file"); pm_message(" ( - means stdin )"); pm_message("Opts: [ -> = Default ]"); pm_message(""); pm_message(" -x Overskip mode (tries to improve color quality.)"); pm_message(" -s Apply simple sharpness-operator on the Luma-channel."); pm_message(" -i Give some (buggy) information from fileheader."); pm_message(" -crop Try to cut off the black frame."); pm_message(" -pos Print file position of image to stderr."); pm_message(" -rep Try to jump over defects in the Huffman Code."); pm_message(""); pm_message(" %s -c0 don't correct (linear).", X(C_DEFAULT,C_LINEAR)); pm_message(" %s -c- correct darker.", X(C_DEFAULT,C_DARK)); pm_message(" %s -c+ correct brighter.", X(C_DEFAULT,C_BRIGHT)); pm_message(""); pm_message(" %s -1 Extract 128x192 from Image file.", X(S_DEFAULT,S_Base16)); pm_message(" %s -2 Extract 256x384 from Image file.", X(S_DEFAULT,S_Base4)); pm_message(" %s -3 Extract 512x768 from Image file.", X(S_DEFAULT,S_Base)); pm_message(" %s -4 Extract 1024x1536 from Image file.", X(S_DEFAULT,S_4Base)); pm_message(" %s -5 Extract 2048x3072 from Image file.", X(S_DEFAULT,S_16Base)); pm_message(" %s -6 Extract 4096x6144 from Image file and 64Base-Directory.", X(S_DEFAULT,S_64Base)); pm_message(""); #endif break; case E_OPT: pm_message("These Options are not allowed together.");break; case E_MEM: pm_message("Not enough memory !"); break; case E_HUFF: pm_message("Error in Huffman-Code-Table"); break; case E_SEQ: pm_message("Error in Huffman-Sequence, try option -rep"); break; case E_SEQ1: pm_message("Error1 in Huffman-Sequence, try option -rep"); break; case E_SEQ2: pm_message("Error2 in Huffman-Sequence, try option -rep"); break; case E_SEQ3: pm_message("Error3 in Huffman-Sequence, try option -rep"); break; case E_SEQ4: pm_message("Error4 in Huffman-Sequence, try option -rep"); break; case E_SEQ5: pm_message("Error5 in Huffman-Sequence, try option -rep"); break; case E_SEQ6: pm_message("Error6 in Huffman-Sequence, try option -rep"); break; case E_SEQ7: pm_message("Error7 in Huffman-Sequence, try option -rep"); break; case E_POS: pm_message("Error in file-position"); break; case E_OVSKIP: pm_message("Can't read this resolution in overskip-mode"); break; case E_CONFIG: pm_message("Something is wrong with your configuration [see %s:%d]",file,line); pm_message("Edit the source and recompile..."); break; case E_TCANT: pm_message("Sorry, can't determine orientation for this file."); pm_message("Please give orientation parameters. ");break; case E_FOPEN: pm_message("Can't open file"); break; default: pm_message("Unknown error %d ??? [%s:%d]",e,file,line);break; } exit(9); } static uBYTE *RGB_corr=0; static sINT T_L[256],T_R[256],T_G[256],T_g[256],T_B[256]; #define slen 3072 static void initcorr(void) { switch(corrmode) {case C_LINEAR: RGB_corr=RGB_corr0; break; case C_DARK: RGB_corr=RGB_corr1; break; case C_BRIGHT: RGB_corr=RGB_corr2; break; default: error(E_INTERN); } } static void initctable(void) {sINT i; static sINT init=0; if(init) return; init=1; initcorr(); for(i=0;i<256;i++) { T_L[i] = i * RGB_F_LL; T_R[i] = i * RGB_F_C2 + RGB_O_C2; T_G[i] = i * RGB_F_G1; T_g[i] = i * RGB_F_G2 + RGB_O_G; T_B[i] = i * RGB_F_C1 + RGB_O_C1; } } static void ycctorgb(implane *l,implane *c1,implane *c2) {dim x,y,w,h; uBYTE *pl,*pc1,*pc2; sINT red,green,blue; sINT L; initctable(); w=l->iwidth; h=l->iheight; for(y=0;yim + y * l->mwidth; pc1= c1->im + y * c1->mwidth; pc2= c2->im + y * c2->mwidth; for(x=0;x>RGB_BitSh1; green= (L + T_G[*pc1] + T_g[*pc2] )>>RGB_BitSh1; blue = (L + T_B[*pc1] )>>RGB_BitSh1; red = TRIF(red, 0,RGB_Maximum1,0,red, RGB_Maximum1); green = TRIF(green,0,RGB_Maximum1,0,green,RGB_Maximum1); blue = TRIF(blue ,0,RGB_Maximum1,0,blue, RGB_Maximum1); *(pl++ )=RGB_corr[red]; *(pc1++)=RGB_corr[green]; *(pc2++)=RGB_corr[blue]; } } } #undef BitShift static void sharpit(implane *l) {sINT x,y,h,w,mw,akk; uBYTE f1[slen],f2[slen],*old,*akt,*ptr,*work,*help,*optr=0; if((!l) || (!l->im)) error(E_INTERN); if(l->iwidth > slen) error(E_INTERN); old=f1; akt=f2; h=l->iheight; w=l->iwidth; mw=l->mwidth; for(y=1;yim+ y*mw; optr=ptr-mw; work=akt; *(work++)= *(ptr++); for(x=1;x1) for(x=0;xim+=d*p->mwidth; p->iheight-=d;}} #define cru(p,d) {if(p) {p->iheight-=d;}} #define crl(p,d) {if(p) {p->im+=d; p->iwidth-=d;}} #define crr(p,d) {if(p) {p->iwidth-=d;}} void cropit(sizeinfo *si,implane *l,implane *c1,implane *c2) {dim x,y,s,w,h; sINT nl,nr,no,nu; uBYTE *ptr; if(si->imvlen || si->imhlen) error(E_INTERN); w=si->rdhlen; h=si->rdvlen; if((!l) || (l->iwidth != w) || (l->iheight != h)) error(E_INTERN); if((!c1) || (c1->iwidth != w) || (c1->iheight != h)) error(E_INTERN); if((!c2) || (c2->iwidth != w) || (c2->iheight != h)) error(E_INTERN); for(y=0,no=0;yim)+y*(l->mwidth); xim)+y*(l->mwidth); xmwidth; for(x=0,nl=0;xim)+x; yim)+x; yimvlen=h; si->imhlen=w; } void shrink(sizeinfo *si,implane *l,implane *c1,implane *c2) {dim w,h; w=si->rdhlen; h=si->rdvlen; if((!l) || (l->iwidth != w) || (l->iheight != h)) error(E_INTERN); if((!c1) || (c1->iwidth != w) || (c1->iheight != h)) error(E_INTERN); if((!c2) || (c2->iwidth != w) || (c2->iheight != h)) error(E_INTERN); if((!si->imvlen) && (!si->imhlen)) /* no subrectangle given */ {si->imvlen=si->rdvlen; si->imhlen=si->rdhlen; return; } if (si->imvlen>h || si->imvlen<1 ) error(E_INTERN); if (si->imvoff> si->rdvlen - si->imvlen) error(E_INTERN); if (si->imhlen>w || si->imhlen<1 ) error(E_INTERN); if (si->imhoff> si->rdhlen - si->imhlen) error(E_INTERN); cro(l ,si->imvoff); cro(c1,si->imvoff); cro(c2,si->imvoff); cru(l ,si->rdvlen - si->imvoff - si->imvlen); cru(c1,si->rdvlen - si->imvoff - si->imvlen); cru(c2,si->rdvlen - si->imvoff - si->imvlen); crl(l ,si->imhoff); crl(c1,si->imhoff); crl(c2,si->imhoff); crr(l ,si->rdhlen - si->imhoff - si->imhlen); crr(c1,si->rdhlen - si->imhoff - si->imhlen); crr(c2,si->rdhlen - si->imhoff - si->imhlen); } void colconvert(sizeinfo *si,implane *l,implane *c1,implane *c2) { #define w (si->rdhlen) #define h (si->rdvlen) if((!l ) || ( l->iwidth != w ) || ( l->iheight != h) || (! l->im)) error(E_INTERN); if((!c1) || (c1->iwidth != w ) || (c1->iheight != h) || (!c1->im)) error(E_INTERN); if((!c2) || (c2->iwidth != w ) || (c2->iheight != h) || (!c2->im)) error(E_INTERN); if (do_crop) cropit(si,l,c1,c2); else shrink(si,l,c1,c2); if (do_sharp) sharpit(l); ycctorgb(l,c1,c2); #undef w #undef h } void clearimpl(implane *l,sINT n) { dim x,y; uBYTE *ptr; ptr=l->im; for (x=0;xmwidth;x++) for (y=0; ymheight;y++) *(ptr++)=n; } void halve(implane *p) {dim w,h,x,y; uBYTE *optr,*nptr; if ((!p) || (!p->im)) error(E_INTERN); w=p->iwidth/=2; h=p->iheight/=2; for(y=0;yim) + y*(p->mwidth); optr=(p->im) + 2*y*(p->mwidth); for(x=0;xim)) error(E_INTERN); w=p->iwidth; h=p->iheight; if(p->mwidth < 2*w ) error(E_INTERN); if(p->mheight < 2*h ) error(E_INTERN); p->iwidth=2*w; p->iheight=2*h; for(y=0;yim+ yi*p->mwidth + (w-1); nptr=p->im+2*yi*p->mwidth + (2*w - 2); nptr[0]=nptr[1]=optr[0]; for(x=1;x>1; } } for(y=0;yim + 2*y*p->mwidth; nptr=optr+p->mwidth; uptr=nptr+p->mwidth; for(x=0;x>1; nptr[1]=(((sINT)optr[0])+((sINT)optr[2])+((sINT)uptr[0])+((sINT)uptr[2])+2)>>2; nptr+=2; optr+=2; uptr+=2; } *(nptr++)=(((sINT)*(optr++))+((sINT)*(uptr++))+1)>>1; *(nptr++)=(((sINT)*(optr++))+((sINT)*(uptr++))+1)>>1; } optr=p->im + (2*h-2)*p->mwidth; nptr=p->im + (2*h-1)*p->mwidth; for(x=0;x30); } sINT Skip4Base(void) {sINT cd_offset,cd_offhelp; cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ; SEEK(cd_offset+3); EREADBUF; cd_offhelp=((((sINT)sbuffer[510])<<8)|sbuffer[511]) + 1; cd_offset+=cd_offhelp; SEEK(cd_offset); EREADBUF; while(!testbegin()) {cd_offset++; EREADBUF; } return cd_offset; } void planealloc(implane *p, dim width, dim height) { p->iwidth=p->iheight=0; p->mwidth=width; p->mheight=height; p->mp = ( p->im = ( uBYTE * ) malloc (width*height*sizeof(uBYTE)) ); if(!(p->im)) error(E_MEM); } static void pastequer(implane *gross,dim px,dim py,implane *klein) {dim x,y; uBYTE *von,*nach; if(px+klein->iwidth > gross->iwidth) error(E_INTERN); if(py+klein->iheight > gross->iheight) error(E_INTERN); for(y=0;yiheight;y++) { von=klein->im + y * klein->mwidth; nach=gross->im + (y+py) * gross->mwidth + px; for(x=0;xiwidth;x++) *(nach++)=*(von++); } } static void pastehead(implane *gross,dim px,dim py,implane *klein) {dim x,y; uBYTE *von,*nach; if(px+klein->iwidth > gross->iwidth) error(E_INTERN); if(py+klein->iheight > gross->iheight) error(E_INTERN); for(y=0;yiheight;y++) { von= klein->im + (klein->iheight-1-y) * klein->mwidth + (klein->iwidth - 1); nach=gross->im + (y+py) * gross->mwidth + px; for(x=0;xiwidth;x++) *(nach++)=*(von--); } } static void pastelinks(implane *gross,dim px,dim py,implane *klein) {dim x,y; uBYTE *von,*nach; if(px+klein->iheight > gross->iwidth) error(E_INTERN); if(py+klein->iwidth > gross->iheight) error(E_INTERN); for(y=0;yiwidth;y++) { von=klein->im + klein->iwidth - 1 - y; nach=gross->im + (y+py) * gross->mwidth + px; for(x=0;xiheight;x++,von+=klein->mwidth) *(nach++)=*(von); } } static void pasterechts(implane *gross,dim px,dim py,implane *klein) {dim x,y; uBYTE *von,*nach; if(px+klein->iheight > gross->iwidth) error(E_INTERN); if(py+klein->iwidth > gross->iheight) error(E_INTERN); for(y=0;yiwidth;y++) { von=klein->im + (klein->iheight-1)*klein->mwidth + y; nach=gross->im + (y+py) * gross->mwidth + px; for(x=0;xiheight;x++,von-=klein->mwidth) *(nach++)=*(von); } } void pastein(implane *gross, dim xpos,dim xw, dim ypos,dim yh, implane *klein, enum TURNS ori) { switch (ori) { case T_NONE: pastequer(gross,xpos+(xw-klein->iwidth)/2,ypos+(yh-klein->iheight)/2,klein); break; case T_LEFT: pastelinks(gross,xpos+(xw-klein->iheight)/2,ypos+(yh-klein->iwidth)/2,klein); break; case T_RIGHT:pasterechts(gross,xpos+(xw-klein->iheight)/2,ypos+(yh-klein->iwidth)/2,klein); break; case T_HEAD: pastehead(gross,xpos+(xw-klein->iwidth)/2,ypos+(yh-klein->iheight)/2,klein); break; default: error(E_INTERN); } } /* Test Data types for their size an whether they are signed / unsigned */ void typecheck(void) { sBYTE sbyte; uBYTE ubyte; sINT sint; uINT uint; if(sizeof(sBYTE) != 1) error(E_CONFIG); sbyte=126; sbyte++; sbyte++; if(sbyte > 126 ) error(E_CONFIG); if(sizeof(uBYTE) != 1) error(E_CONFIG); ubyte=126; ubyte++; ubyte++; if(ubyte < 126 ) error(E_CONFIG); #ifdef U_TOO_LONG if(sizeof(sINT) < 4) error(E_CONFIG); if(sizeof(uINT) < 4) error(E_CONFIG); #else if(sizeof(sINT) != 4) error(E_CONFIG); if(sizeof(uINT) != 4) error(E_CONFIG); #endif sint=1; sint--; sint--; if(sint>1) error(E_CONFIG); uint=1; uint--; uint--; if(uint<1) error(E_CONFIG); } struct pcdquad { uBYTE len,highseq,lowseq,key;}; struct pcdhqt { uBYTE entries; struct pcdquad entry[256];}; struct myhqt { uINT seq,mask,len; uBYTE key; }; static struct myhqt myhuff0[256],myhuff1[256],myhuff2[256]; static sINT myhufflen0=0,myhufflen1=0,myhufflen2=0; static void readhqtsub(struct pcdhqt *quelle,struct myhqt *ziel,sINT *anzahl) #define E ((uINT) 1) {sINT i; struct pcdquad *sub; struct myhqt *help; *anzahl=(quelle->entries)+1; for(i=0;i<*anzahl;i++) {sub = (struct pcdquad *)(((uBYTE *)quelle)+1+i*sizeof(*sub)); help=ziel+i; help->seq = (((uINT) sub->highseq) << 24) |(((uINT) sub->lowseq) << 16); help->len = ((uINT) sub->len) +1; help->key = sub->key; if(help->len > 16) error(E_HUFF); help->mask = ~ ( (E << (32-help->len)) -1); } #undef E } void readhqt(sINT n) { uBYTE *ptr; EREADBUF; ptr = sbuffer; readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0); if(n<2) return; ptr+= 1 + 4* myhufflen0; readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1); if(n<3) return; ptr+= 1 + 4* myhufflen1; readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2); } void readhqtx(sINT n) { uBYTE *ptr; ptr = sbuffer; readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0); if(n<2) return; ptr+= 1 + 4* myhufflen0; readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1); if(n<3) return; ptr+= 1 + 4* myhufflen1; readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2); } #ifdef FASTHUFF static struct myhqt *HTAB0[0x10000],*HTAB1[0x10000],*HTAB2[0x10000]; static void inithuff(sINT hlen,struct myhqt *ptr,struct myhqt *TAB[]) {sINT i,n; sINT seq,len; struct myhqt *help; for(i=0;i<0x10000;i++) TAB[i]=0; for(n=0;nseq)>>16; len=help->len; for(i=0;i<(1<<(16-len));i++) TAB[seq | i] = help; } } #endif static char *pn[]={"Luma Channel","Chroma1 Channel","Chroma2 Channel"}; void decode(sizeinfo *si,int fak,implane *f,implane *f1,implane *f2,sINT autosync) {dim w,h,hoff,hlen,hende,voff,vlen,vende,anfang,ende; sINT htlen,sum,do_inform,part; uINT sreg,maxwidth; uINT inh,n,zeile,segment,ident; struct myhqt *hp; uBYTE *nptr; uBYTE *lptr; #define nextbuf { nptr=sbuffer; if(READBUF<1) { if(!do_rep) error(E_READ); \ pm_message("Read error"); \ return; } } #define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; } #ifdef U_TOO_LONG #define shiftreg(n) sreg = (sreg<< n ) & 0xffffffff; #else #define shiftreg(n) sreg<<=n; #endif #define shiftout(n){ shiftreg(n); inh-=n; \ while (inh<=24) \ {checkbuf; \ sreg |= ((uINT)(*(nptr++)))<<(24-inh);\ inh+=8;\ }\ } #define issync ((sreg & 0xffffff00) == 0xfffffe00) #define brutesync ((sreg & 0x00fff000) == 0x00fff000) #define seeksync { while (!brutesync) shiftout(8); while (!issync) shiftout(1);} #ifdef FASTHUFF struct myhqt **HTAB; HTAB=0; inithuff(myhufflen0,myhuff0,HTAB0); inithuff(myhufflen1,myhuff1,HTAB1); inithuff(myhufflen2,myhuff2,HTAB2); #define SETHUFF0 HTAB=HTAB0; #define SETHUFF1 HTAB=HTAB1; #define SETHUFF2 HTAB=HTAB2; #define FINDHUFF(x) {x=HTAB[sreg>>16];} #else sINT i; struct myhqt *htptr; htptr=0; #define SETHUFF0 { htlen=myhufflen0 ; htptr = myhuff0 ; } #define SETHUFF1 { htlen=myhufflen1 ; htptr = myhuff1 ; } #define SETHUFF2 { htlen=myhufflen2 ; htptr = myhuff2 ; } #define FINDHUFF(x) {for(i=0, x=htptr;(imask)!= x->seq); i++,x++); \ if(i>=htlen) x=0;} #endif anfang=ende=0; if(fak >= 0) {w =si->w *fak; h =si->h *fak; hoff=si->rdhoff*fak; if(hoff & 1 ) error(E_INTERN); /* Must be all even */ hlen=si->rdhlen*fak; if(hlen & 1 ) error(E_INTERN); hende=hlen+hoff; voff=si->rdvoff*fak; if(voff & 1 ) error(E_INTERN); vlen=si->rdvlen*fak; if(vlen & 1 ) error(E_INTERN); vende=vlen+voff; } else {fak = -fak; w =si->w /fak; h =si->h /fak; hoff=si->rdhoff/fak; if(hoff & 1 ) error(E_INTERN); /* Must be all even */ hlen=si->rdhlen/fak; if(hlen & 1 ) error(E_INTERN); hende=hlen+hoff; voff=si->rdvoff/fak; if(voff & 1 ) error(E_INTERN); vlen=si->rdvlen/fak; if(vlen & 1 ) error(E_INTERN); vende=vlen+voff; } if( f && ((! f->im) || ( f->iheight != vlen ) || (f->iwidth != hlen ))) error(E_INTERN); if( f1 && ((!f1->im) || (f1->iheight != vlen/2) || (f1->iwidth != hlen/2))) error(E_INTERN); if( f2 && ((!f2->im) || (f2->iheight != vlen/2) || (f2->iwidth != hlen/2))) error(E_INTERN); htlen=sreg=maxwidth=0; zeile=0; nextbuf; inh=32; lptr=0; part=do_inform=0; shiftout(16); shiftout(16); if(autosync) seeksync; if(!issync) { if(!do_rep) error(E_SEQ6); else {pm_message("image does not start with synchron mark, seeking..."); seeksync; do_inform=1; } } n=0; for(;;) { if (issync) {shiftout(24); ident=sreg>>16; shiftout(16); zeile=(ident>>1) & 0x1fff; segment=ident>>14; if(do_inform) {pm_message("synchron mark found line %d",zeile);do_inform=0;} if(lptr && (n!=maxwidth)) {if(!do_rep)error(E_SEQ1); else pm_message("line %d in %s: wrong length of last line (%d)",zeile,pn[part],n); } n=0; if(zeile==h) return; if(zeile >h) { if(!do_rep) error(E_SEQ2); else {pm_message("wrong line number %d, ignoring line",zeile); seeksync; n=maxwidth; do_inform=1; } } else switch(segment) { case 1: if(!do_rep) error(E_SEQ3); pm_message("abnormal line tag in %d, interpreting as Luma tag",zeile); case 0: maxwidth=w; if((!f) && autosync) {seeksync; n=maxwidth; break;} if(!f) error(E_SEQ7); if((zeile= vende)) {seeksync; n=maxwidth; break;} anfang=hoff; ende=hende; lptr=f->im + (zeile-voff)*f->mwidth; SETHUFF0; part=0; break; case 2: maxwidth=w>>1; if(!f1) return; /*if((!f1) && autosync) {seeksync; break;}*/ if((zeile= vende)) {seeksync; n=maxwidth; break;} anfang=hoff>>1; ende=hende>>1; lptr=f1->im + ((zeile-voff)>>1)*f1->mwidth; SETHUFF1; part=1; break; case 3: maxwidth=w>>1; if(!f2) return; /*if((!f2) && autosync) {seeksync; break;}*/ if((zeile= vende)) {seeksync; n=maxwidth; break;} anfang=hoff>>1; ende=hende>>1; lptr=f2->im + ((zeile-voff)>>1)*f2->mwidth; SETHUFF2; part=2; break; default:error(E_SEQ3); } } else { if(!lptr) error(E_SEQ6); if(n>maxwidth) { if (!do_rep) error(E_SEQ4); else { pm_message("missing synchron mark in %s line %d",pn[part],zeile); seeksync; do_inform=1; n=maxwidth; } } else {FINDHUFF(hp); if(!hp) { if(!do_rep) error(E_SEQ5); pm_message("unable to decode, ignoring rest of line"); seeksync; n=maxwidth; do_inform=1; } else {if((n>= anfang) && (nkey); NORM(sum); *(lptr++) = sum; } n++; shiftout(hp->len); } } } } #undef nextbuf #undef checkbuf #undef shiftout #undef issync #undef seeksync } /* Decode the 64Base files */ void decodex(FILE **fp, int tag , struct ic_descr *descr,sizeinfo *si,int fak,implane *f,sINT autosync) {dim w,h,hoff,hlen,hende,voff,vlen,vende,anfang,ende; sINT htlen,sum,do_inform,part; uINT sreg,maxwidth; uINT inh,n,pos,zeile,segment,ident,sector,offset,length; struct myhqt *hp; uBYTE *nptr; uBYTE *lptr; int bufcont; #define nextbuf { nptr=sbuffer; \ do\ {bufcont=fread(sbuffer,1,sizeof(sbuffer),*fp);\ if(bufcont<1)\ {if(feof(*fp)) fp++;\ else if(!do_rep) error(E_READ);\ else {pm_message("Read error"); return;}\ if(!*fp) return; }\ } while (bufcont<1); } #define checkbuf { if (nptr >= sbuffer + bufcont) nextbuf; } #ifdef U_TOO_LONG #define shiftreg(n) sreg = (sreg<< n ) & 0xffffffff; #else #define shiftreg(n) sreg<<=n; #endif #define shiftout(n){ shiftreg(n); inh-=n; \ while (inh<=24) \ {checkbuf; \ sreg |= ((uINT)(*(nptr++)))<<(24-inh);\ inh+=8;\ }\ } #define issync ((sreg & 0xffffff00) == 0xfffffe00) #define brutesync ((sreg & 0x00fff000) == 0x00fff000) #define seeksync { while ((!brutesync) && (bufcont>0)) shiftout(8); \ while ((!issync) && (bufcont>0)) shiftout(1);} #ifdef FASTHUFF struct myhqt **HTAB; HTAB=0; switch(tag) {case 0: inithuff(myhufflen0,myhuff0,HTAB0); break; case 1: inithuff(myhufflen1,myhuff1,HTAB1); break; case 2: inithuff(myhufflen2,myhuff2,HTAB2); break; default: error(E_INTERN); } #define SETHUFF0 HTAB=HTAB0; #define SETHUFF1 HTAB=HTAB1; #define SETHUFF2 HTAB=HTAB2; #define FINDHUFF(x) {x=HTAB[sreg>>16];} #else sINT i; struct myhqt *htptr; htptr=0; #define SETHUFF0 { htlen=myhufflen0 ; htptr = myhuff0 ; } #define SETHUFF1 { htlen=myhufflen1 ; htptr = myhuff1 ; } #define SETHUFF2 { htlen=myhufflen2 ; htptr = myhuff2 ; } #define FINDHUFF(x) {for(i=0, x=htptr;(imask)!= x->seq); i++,x++); \ if(i>=htlen) x=0;} #endif anfang=ende=0; maxwidth=FILE32(descr->length); h =FILE16(descr->height); offset =FILE16(descr->offset); length =FILE32(descr->length); if(fak >= 0) {w =si->w *fak; h =si->h *fak; hoff=si->rdhoff*fak; if(hoff & 1 ) error(E_INTERN); hlen=si->rdhlen*fak; if(hlen & 1 ) error(E_INTERN); hende=hlen+hoff; voff=si->rdvoff*fak; if(voff & 1 ) error(E_INTERN); vlen=si->rdvlen*fak; if(vlen & 1 ) error(E_INTERN); vende=vlen+voff; } else {fak = -fak; w =si->w /fak; h =si->h /fak; hoff=si->rdhoff/fak; if(hoff & 1 ) error(E_INTERN); hlen=si->rdhlen/fak; if(hlen & 1 ) error(E_INTERN); hende=hlen+hoff; voff=si->rdvoff/fak; if(voff & 1 ) error(E_INTERN); vlen=si->rdvlen/fak; if(vlen & 1 ) error(E_INTERN); vende=vlen+voff; } if(!f) error(E_INTERN); if((! f->im) || ( f->iheight != vlen ) || (f->iwidth != hlen )) error(E_INTERN); switch(tag) {case 0: SETHUFF0; break; case 1: SETHUFF1; break; case 2: SETHUFF2; break; default: error(E_INTERN); } htlen=sreg=0; zeile=0; nextbuf; inh=32; lptr=0; part=do_inform=0; shiftout(16); shiftout(16); if(autosync) seeksync; if(!issync) { if(!do_rep) error(E_SEQ6); else {pm_message("image does not start with synchron mark, seeking..."); seeksync; do_inform=1; } } n=pos=0; for(;;) {if (issync) {shiftout(24); ident=(sreg>>8) & 0xffffff; shiftout(24); segment=(ident>>20) & 0xf; zeile =(ident>>6 ) & 0x3fff; sector =(ident>>1 ) & 0x1f; if(segment != tag) {pm_message("falsches segment"); return;} if(do_inform) {pm_message("synchron mark found line %d",zeile);do_inform=0;} if(zeile < voff ) {n=maxwidth; seeksync; continue;} if(zeile >= vende) return; if(lptr && (n!=maxwidth)) {if(!do_rep)error(E_SEQ1); else pm_message("line %d in %s: wrong length of last line (%d)",zeile,pn[part],n); } n=0; if(zeile==h) return; if(zeile >h) { if(!do_rep) error(E_SEQ2); else {pm_message("wrong line number %d, ignoring line",zeile); seeksync; n=maxwidth; do_inform=1; } } else {switch(tag) {case 0: anfang=hoff; ende=hende; pos=offset + sector*length; if((pos>=ende) || (pos+length < anfang)) { n=maxwidth; seeksync; continue;} lptr=f->im + (zeile-voff)*f->mwidth + (pos>anfang?(pos-anfang):0) ; break; case 1: case 2: anfang=hoff; ende=hende; pos=(offset>>1) + sector*length; if((pos>=ende) || (pos+length < anfang)) { n=maxwidth; seeksync; continue;} lptr=f->im + (zeile-voff)*f->mwidth + (pos>anfang?(pos-anfang):0) ; break; default: error(E_INTERN); } } } else /* for if (issync) */ {if(!lptr) error(E_SEQ6); FINDHUFF(hp); if(!hp) { if(!do_rep) error(E_SEQ5); pm_message("unable to decode %08x, ignoring rest of line",sreg); seeksync; n=maxwidth; do_inform=1; } else {if((pos >= anfang) && (poskey); NORM(sum); *(lptr++) = sum; } n++; pos++; shiftout(hp->len); if(n==maxwidth) { if ((zeile >= vende -1) && (pos >= hende)) return; seeksync; } } } } #undef nextbuf #undef checkbuf #undef shiftout #undef issync #undef seeksync } enum ERRORS readplain(sizeinfo *si,int fak,implane *l,implane *c1,implane *c2) {dim i,w,h,hoff,hlen,voff,vlen; uBYTE *pl=0,*pc1=0,*pc2=0; if(fak >= 0) {w =si->w *fak; h =si->h *fak; hoff=si->rdhoff*fak; if(hoff & 1 ) error(E_INTERN); /* Must be all even */ hlen=si->rdhlen*fak; if(hlen & 1 ) error(E_INTERN); voff=si->rdvoff*fak; if(voff & 1 ) error(E_INTERN); vlen=si->rdvlen*fak; if(vlen & 1 ) error(E_INTERN); } else {fak = -fak; w =si->w /fak; h =si->h /fak; hoff=si->rdhoff/fak; if(hoff & 1 ) error(E_INTERN); /* Must be all even */ hlen=si->rdhlen/fak; if(hlen & 1 ) error(E_INTERN); voff=si->rdvoff/fak; if(voff & 1 ) error(E_INTERN); vlen=si->rdvlen/fak; if(vlen & 1 ) error(E_INTERN); } if(l) { if ((l->mwidthmheightim)) error(E_INTERN); l->iwidth=hlen; l->iheight=vlen; pl=l->im; } if(c1) { if ((c1->mwidth<(hlen>>1)) || (c1->mheight<(vlen>>1)) || (!c1->im)) error(E_INTERN); c1->iwidth=hlen>>1; c1->iheight=vlen>>1; pc1=c1->im; } if(c2) { if ((c2->mwidth<(hlen>>1)) || (c2->mheight<(vlen>>1)) || (!c2->im)) error(E_INTERN); c2->iwidth=hlen>>1; c2->iheight=vlen>>1; pc2=c2->im; } if(voff) SKIPr(w*3*(voff>>1)); for(i=0;i>1;i++) { if(pl) { if(hlen==w) {if(READ(pl,w)<1) return(E_READ); pl+= l->mwidth; if(READ(pl,w)<1) return(E_READ); pl+= l->mwidth; } else {SKIPr(hoff); if(READ(pl,hlen)<1) return(E_READ); pl+= l->mwidth; SKIPr(w-hlen); /* w - hlen - hoff + hoff */ if(READ(pl,hlen)<1) return(E_READ); pl+= l->mwidth; SKIPr(w-hoff-hlen); } } else SKIPr(2*w); if(pc1) { if(hlen==w) { if(READ(pc1,w>>1)<1) return(E_READ); pc1+= c1->mwidth; } else {SKIPr((hoff)>>1); if(READ(pc1,hlen>>1)<1) return(E_READ); pc1+= c1->mwidth; SKIPr((w-hoff-hlen)>>1); } } else SKIPr(w>>1); if(pc2) { if(hlen==w) { if(READ(pc2,w>>1)<1) return(E_READ); pc2+= c2->mwidth; } else {SKIPr((hoff)>>1); if(READ(pc2,hlen>>1)<1) return(E_READ); pc2+= c2->mwidth; SKIPr((w-hoff-hlen)>>1); } } else SKIPr(w>>1); } return E_NONE; } void write_ppm(dim w,dim h, uBYTE *rptr,sdim rzeil,sdim rpix, uBYTE *gptr,sdim gzeil,sdim gpix, uBYTE *bptr,sdim bzeil,sdim bpix) {register uBYTE *pr,*pg,*pb; dim x,y; pixel *pixrow; register pixel* pP; ppm_writeppminit(stdout,w,h,(pixval) 255, 0); pixrow = ppm_allocrow( w ); for(y=0;yimhlen; h=si->imvlen; if((!r) || (r->iwidth != w ) || (r->iheight != h) || (!r->im)) error(E_INTERN); if((!g) || (g->iwidth != w ) || (g->iheight != h) || (!g->im)) error(E_INTERN); if((!b) || (b->iwidth != w ) || (b->iheight != h) || (!b->im)) error(E_INTERN); switch(t) {case T_NONE: write_ppm(w,h,r->im,r->mwidth,1, g->im,g->mwidth,1, b->im,b->mwidth,1); break; case T_RIGHT:write_ppm(h,w,r->im + r->mwidth * ( r->iheight - 1) , 1 , -(r->mwidth), g->im + g->mwidth * ( g->iheight - 1) , 1 , -(g->mwidth), b->im + b->mwidth * ( b->iheight - 1) , 1 , -(b->mwidth)); break; case T_LEFT: write_ppm(h,w,r->im + r->iwidth - 1 , -1 , (r->mwidth), g->im + g->iwidth - 1 , -1 , (g->mwidth), b->im + b->iwidth - 1 , -1 , (b->mwidth)); break; case T_HEAD: write_ppm(w,h,r->im + r->iwidth - 1 + r->mwidth * ( r->iheight - 1) , -(r->mwidth) , -1, g->im + g->iwidth - 1 + g->mwidth * ( g->iheight - 1) , -(g->mwidth) , -1, b->im + b->iwidth - 1 + b->mwidth * ( b->iheight - 1) , -(b->mwidth) , -1); break; default:error(E_INTERN); } } struct ph1 {char id1[8]; uBYTE ww1[14]; char id2[20]; char id3[4*16+4]; short ww2; char id4[20]; uBYTE ww3[2*16+1]; char id5[4*16]; uBYTE idx[11*16]; } ; int main(int argc,char **argv) { ppm_init( &argc, argv ); typecheck(); do_overskip=do_sharp=0; do_rep=do_crop=0; print_pos=0; parseargs(argc,argv); if(size == S_UNSPEC) size = S_DEFAULT; if(corrmode == C_UNSPEC) corrmode = C_DEFAULT; if(do_overskip && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OVSKIP); if(print_pos && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OPT); if(strcmp(pcdname,"-")) { if(!(fin=pm_openr(pcdname))) error(E_FOPEN); emulate_seek=0; } else {pcdname=""; emulate_seek=1; /* 64Base can't be on stdin - need a suitable error message */ if (size == S_64Base) error(E_FOPEN); fin=stdin; } bufpos=0; checkin(); PLuma= &Luma; PChroma1= &Chroma1; PChroma2= &Chroma2; switch(size) { case S_Base16: f_1(BaseW/4,BaseH/4,L_Head,(L_Head+L_Base16)); break; case S_Base4: f_1(BaseW/2,BaseH/2,(L_Head+L_Base16),(L_Head+L_Base16+L_Base4)); break; case S_Base: f_3(BaseW,BaseH,(L_Head+L_Base16+L_Base4)); break; case S_4Base: f_4(BaseW*2,BaseH*2,(L_Head+L_Base16+L_Base4)); break; case S_16Base: f_5(BaseW*4,BaseH*4); break; case S_64Base: f_6(BaseW*8,BaseH*8); break; default: error(E_INTERN); } exit(0); } static void f_1(dim w,dim h,sINT normal,sINT overskip) {sizeinfo si; sizecontrol(&si,w,h,~3); planealloc(PLuma ,si.rdhlen,si.rdvlen); planealloc(PChroma1,si.rdhlen,si.rdvlen); planealloc(PChroma2,si.rdhlen,si.rdvlen); PrintPos(normal*SECSIZE); SEEK(normal+1); if(!do_overskip) { error(readplain(&si,1,PLuma,PChroma1,PChroma2)); interpolate(PChroma1); interpolate(PChroma2); } else { error(readplain(&si,1,PLuma,nullplane,nullplane)); SEEK(overskip+1); error(readplain(&si,2,nullplane,PChroma1,PChroma2)); } colconvert(&si,PLuma,PChroma1,PChroma2); /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */ writepicture(&si,PLuma,PChroma1,PChroma2,turn); } static void f_3(dim w,dim h,sINT normal) {sINT cd_offset,cd_offhelp; sizeinfo si; sizecontrol(&si,w,h,~3); PrintPos(normal*SECSIZE); SEEK(normal+1); if(!do_overskip) {planealloc(PLuma ,si.rdhlen,si.rdvlen); planealloc(PChroma1,si.rdhlen,si.rdvlen); planealloc(PChroma2,si.rdhlen,si.rdvlen); error(readplain(&si,1,PLuma,PChroma1,PChroma2)); interpolate(PChroma1); interpolate(PChroma2); } else {planealloc(PLuma, si.rdhlen, si.rdvlen); planealloc(PChroma1,2*si.rdhlen,2*si.rdvlen); planealloc(PChroma2,2*si.rdhlen,2*si.rdvlen); error(readplain(&si,1,PLuma,PChroma1,PChroma2)); interpolate(PChroma1); interpolate(PChroma2); interpolate(PChroma1); interpolate(PChroma2); cd_offset=Skip4Base(); SEEK(cd_offset+10); EREADBUF; cd_offhelp=(((uINT)sbuffer[2])<<8)|sbuffer[3]; SEEK(cd_offset+12); readhqt(3); SEEK(cd_offset+cd_offhelp); decode(&si,4,nullplane,PChroma1,PChroma2,1); halve(PChroma1); halve(PChroma2); } colconvert(&si,PLuma,PChroma1,PChroma2); /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */ writepicture(&si,PLuma,PChroma1,PChroma2,turn); } static void f_4(dim w,dim h,sINT normal) {sINT cd_offset,cd_offhelp; sizeinfo si; sizecontrol(&si,w,h,~3); planealloc(PLuma ,si.rdhlen,si.rdvlen); planealloc(PChroma1,si.rdhlen,si.rdvlen); planealloc(PChroma2,si.rdhlen,si.rdvlen); PrintPos((L_Head+L_Base16+L_Base4+L_Base)*SECSIZE); if(!do_overskip) {SEEK(L_Head+L_Base16+L_Base4+1); error(readplain(&si,-2,PLuma,PChroma1,PChroma2)); interpolate(PLuma); interpolate(PChroma1); interpolate(PChroma1); interpolate(PChroma2); interpolate(PChroma2); cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ; SEEK(cd_offset + 4); readhqt(1); SEEK(cd_offset + 5); decode(&si,1,PLuma,nullplane,nullplane,0); } else {SEEK(L_Head+L_Base16+L_Base4+1); error(readplain(&si,-2,PLuma,PChroma1,PChroma2)); interpolate(PLuma); interpolate(PChroma1); interpolate(PChroma1); interpolate(PChroma2); interpolate(PChroma2); cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ; SEEK(cd_offset + 4); readhqt(1); SEEK(cd_offset + 5); decode(&si,1,PLuma,nullplane,nullplane,0); cd_offset=bufpos; if(cd_offset % SECSIZE) error(E_POS); cd_offset/=SECSIZE; SEEK(cd_offset+10); EREADBUF; cd_offhelp=(((uINT)sbuffer[2])<<8)|sbuffer[3]; SEEK(cd_offset+12); readhqt(3); SEEK(cd_offset+cd_offhelp); decode(&si,2,nullplane,PChroma1,PChroma2,1); } colconvert(&si,PLuma,PChroma1,PChroma2); /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */ writepicture(&si,PLuma,PChroma1,PChroma2,turn); } static void f_5sub(dim w, dim h, sizeinfo *sip,int fak1,int fak2,int fak3,dim sMASK) {sINT cd_offset; sizecontrol(sip,w,h,sMASK); planealloc(PLuma ,sip->rdhlen,sip->rdvlen); planealloc(PChroma1,sip->rdhlen,sip->rdvlen); planealloc(PChroma2,sip->rdhlen,sip->rdvlen); SEEK(L_Head+L_Base16+L_Base4+1); error(readplain(sip,fak1,PLuma,PChroma1,PChroma2)); interpolate(PLuma); interpolate(PChroma1); interpolate(PChroma1); interpolate(PChroma2); interpolate(PChroma2); cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ; SEEK(cd_offset + 4); readhqt(1); SEEK(cd_offset + 5); decode(sip,fak2,PLuma,nullplane,nullplane,0); interpolate(PLuma); cd_offset=bufpos; if(cd_offset % SECSIZE) error(E_POS); PrintPos(cd_offset); cd_offset/=SECSIZE; SEEK(cd_offset+12); readhqt(3); SEEK(cd_offset+14); decode(sip,fak3,PLuma,PChroma1,PChroma2,0); } static void f_5(dim w,dim h) {sizeinfo si; f_5sub(w,h,&si,-4,-2,1,~7); interpolate(PChroma1); interpolate(PChroma2); colconvert(&si,PLuma,PChroma1,PChroma2); /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */ writepicture(&si,PLuma,PChroma1,PChroma2,turn); } static void f_6(dim w,dim h) {sizeinfo si; FILE *ic,*icr[10]; struct ic_header ic_h; struct ic_descr descr[3]; struct ic_fname names[10]; struct ic_entry efrom,eto; struct file16 namecount,descrcount; int i,j,nc,dc; char FN[300]; int first,last,ffrom,fto,foff; f_5sub(w,h,&si,-8,-4,-2,~15); interpolate(PLuma); interpolate(PChroma1); interpolate(PChroma2); get_dir64(); sprintf(FN,"%s%c%s",dir64,DIRSEP,"info.ic"); if(!(ic=pm_openr(FN))) error(E_FOPEN); if(fread(&ic_h,sizeof(ic_h),1,ic)<1) error(E_READ); /****************************************************************************/ /* layer descriptions */ /****************************************************************************/ if(fseek(ic,FILE32(ic_h.off_descr),0)) error(E_READ); if(fread(&descrcount,sizeof(descrcount),1,ic)<1) error(E_READ); dc=FILE16(descrcount); if((dc<1) || (dc>3)) error(E_SEQ); if((dc<3)) error(E_SEQ); if(fread(descr,sizeof(descr[0]),dc,ic)10)) error(E_SEQ); if((nc<3)) error(E_SEQ); if(fread(names,sizeof(names[0]),nc,ic)= 'A') && (names[i].fname[j]<= 'Z')) names[i].fname[j] += 'a'-'A'; } } #endif } /****************************************************************************/ /* Huffman-Tables */ /****************************************************************************/ if(fseek(ic,FILE32(ic_h.off_huffman),0)) error(E_READ); if(fread(sbuffer,1,sizeof(sbuffer),ic)<5) error(E_READ); readhqtx(3); /****************************************************************************/ /* Decode it */ /****************************************************************************/ for(i=0;i<3; i++) { first=si.rdvoff; last =si.rdvoff+si.rdvlen; if(!i) { /* luma */ if(last>=h) last=h-1; } else { /* chroma */ first/=2; last=(last+1)/2; if(last>=h/2) last=h/2-1; } if(fseek(ic,FILE32(descr[i].off_pointers)+ 6*4*first,0)) error(E_READ); if(fread(&efrom,sizeof(efrom),1,ic)<1) error(E_READ); if(fseek(ic,FILE32(descr[i].off_pointers)+ 6*4*last,0)) error(E_READ); if(fread(&eto ,sizeof(eto ),1,ic)<1) error(E_READ); ffrom=FILE16(efrom.fno); fto =FILE16(eto.fno); foff =FILE32(efrom.offset); for(j=ffrom;j<=fto;j++) {sprintf(FN,"%s%c%s",dir64,DIRSEP,names[j].fname); if(!(icr[j-ffrom]=pm_openr(FN))) error(E_FOPEN); } icr[j-ffrom]=0; if(fseek(icr[0],foff,0)) error(E_READ); switch (i) {case 0: decodex(icr,0,&descr[0],&si, 1,PLuma, 1); break; case 1: decodex(icr,1,&descr[1],&si,-2,PChroma1,1); break; case 2: decodex(icr,2,&descr[2],&si,-2,PChroma2,1); break; } for(j=ffrom;j<=fto;j++) pm_closer(icr[j-ffrom]); } pm_closer(ic); interpolate(PChroma1); interpolate(PChroma2); colconvert(&si,PLuma,PChroma1,PChroma2); writepicture(&si,PLuma,PChroma1,PChroma2,turn); } #define ASKIP { argc--; argv ++;} static void parseargs(int argc,char **argv) { char *opt; ASKIP; while((argc>0) && argv[0][0]=='-' && argv[0][1]) { opt= (*argv)+1; ASKIP; /**** additional options ****/ if(!strcmp(opt,"x")) { if (!do_overskip) do_overskip=1; else error(E_ARG); continue; } if(!strcmp(opt,"s")) { if (!do_sharp) do_sharp=1; else error(E_ARG); continue; } if(!strcmp(opt,"crop")) { if (!do_crop) do_crop=1; else error(E_ARG); continue; } if(!strcmp(opt,"pos")) { if (!print_pos) print_pos=1; else error(E_ARG); continue; } if(!strcmp(opt,"rep")) { if (!do_rep) do_rep=1; else error(E_ARG); continue; } /**** Color model options ****/ if(!strcmp(opt,"c0")) { if (corrmode == C_UNSPEC) corrmode = C_LINEAR; else error(E_ARG); continue; } if(!strcmp(opt,"c-")) { if (corrmode == C_UNSPEC) corrmode = C_DARK; else error(E_ARG); continue; } if(!strcmp(opt,"c+")) { if (corrmode == C_UNSPEC) corrmode = C_BRIGHT; else error(E_ARG); continue; } /**** Resolution options ****/ if((!strcmp(opt,"Base/16")) || (!strcmp(opt,"1")) || (!strcmp(opt,"128x192"))) { if (size == S_UNSPEC) size = S_Base16; else error(E_ARG); continue; } if((!strcmp(opt,"Base/4" )) || (!strcmp(opt,"2")) || (!strcmp(opt,"256x384"))) { if (size == S_UNSPEC) size = S_Base4; else error(E_ARG); continue; } if((!strcmp(opt,"Base" )) || (!strcmp(opt,"3")) || (!strcmp(opt,"512x768"))) { if (size == S_UNSPEC) size = S_Base; else error(E_ARG); continue; } if((!strcmp(opt,"4Base" )) || (!strcmp(opt,"4")) || (!strcmp(opt,"1024x1536"))) { if (size == S_UNSPEC) size = S_4Base; else error(E_ARG); continue; } if((!strcmp(opt,"16Base" )) || (!strcmp(opt,"5")) || (!strcmp(opt,"2048x3072"))) { if (size == S_UNSPEC) size = S_16Base; else error(E_ARG); continue; } if((!strcmp(opt,"64Base" )) || (!strcmp(opt,"6")) || (!strcmp(opt,"4096x6144"))) { if (size == S_UNSPEC) size = S_64Base; else error(E_ARG); /* if(argc<1) error(E_ARG); dir64=argv[0]; ASKIP; */ continue; } pm_message("unknown option: -%s",opt); error(E_ARG); } if(argc<1) error(E_ARG); pcdname= *argv; ASKIP; if(argc>0) error(E_ARG); } #undef ASKIP static void checkin(void) { SEEK(1); EREADBUF; switch(sbuffer[0xe02 & 0x7ff]&0x03) {case 0x00: turn=T_NONE; break; case 0x01: turn=T_LEFT; pm_message("rotating counter-clockwise"); break; case 0x02: turn=T_HEAD; pm_message("rotating upside-down"); break; case 0x03: turn=T_RIGHT; pm_message("rotating clockwise"); break; default: error(E_TCANT); } } /************************** file access functions **************/ int READ(uBYTE *ptr,int n) {int d; if(!n) return 1; bufpos+=n; for(;;) {d=fread((char *)ptr,1,n,fin); if(d<1) return 0; n-=d; if (!n) break; ptr+=d; } return 1; } static int friss(int n) {int d; while(n>0) { d= n>sizeof(sbuffer) ? sizeof(sbuffer) : n; n-=d; if(READ(sbuffer,d) !=1) return 1; } return 0; } void SEEK(int x) { x *= SECSIZE; if(xw=w; si->h=h; si->rdhlen=w; si->rdvlen=h; si->rdhoff=0; si->rdvoff=0; si->imhlen=0; si->imvlen=0; si->imhoff=0; si->imvoff=0; } /* Thanks to James Pearson for writing get_dir64 */ /* finds dir64 from the given input filename Had to change DIRSEP from a string to a character */ static void get_dir64(void) { char name[32]; char *n, *p, *d; d = dir64; /* find if input filename includes a path */ if ((p = strrchr(pcdname,DIRSEP)) == 0) p = pcdname; else { /* copy path to start of dir64 */ n = pcdname; p++; while (n < p) *d++ = *n++; } /* get first part of filename (the bit before .pcd) */ n = name; while (*p != '.' && *p != '\0') *n++ = *p++; *n = '\0'; /* construct path */ #ifdef SMALLNAMES sprintf(d,"..%cipe%c%s%c64base",DIRSEP,DIRSEP,name,DIRSEP); #else sprintf(d,"..%cIPE%c%s%c64BASE",DIRSEP,DIRSEP,name,DIRSEP); #endif }