home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume34 / hpcd2ppm / part01 < prev    next >
Encoding:
Text File  |  1992-12-18  |  49.1 KB  |  1,831 lines

  1. Newsgroups: comp.sources.misc
  2. From: danisch@ira.uka.de (Hadmut Danisch)
  3. Subject: v34i083:  hpcdtoppm - convert Photo-CD file into portable pixmap v0.3, Part01/01
  4. Message-ID: <1992Dec20.030512.815@sparky.imd.sterling.com>
  5. X-Md4-Signature: 6f5257558e937cb4463e9ab2977606f9
  6. Date: Sun, 20 Dec 1992 03:05:12 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: danisch@ira.uka.de (Hadmut Danisch)
  10. Posting-number: Volume 34, Issue 83
  11. Archive-name: hpcdtoppm/part01
  12. Environment: Photo-CD
  13.  
  14. Reads a Photo-CD Image file or Overview  file,  and  outputs
  15. portable  pixmap.   Image files you can find on the Photo-CD
  16. in photo_cd/images, they are named as  "imgnnnn.pcd",  where
  17. nnnn   is   a   4-digit-number.  The  Overview  file  is  at
  18. photo_cd/overview.pcd . If there is no ppm-file-name  given,
  19. output  will  be  printed  to  stdout.  hpcdtoppm stands for
  20. "Hadmut's pcdtoppm" to make it distinguishable in case some-
  21. one else is building the same thing and calling it pcdtoppm.
  22.  
  23. I still don't have enough information about the Photo-CD  to
  24. take  care  of *all* data structures. The information I have
  25. is quite vague and this  program was developed  by  starring
  26. at  the hex-dumps and the famous trial-and-error-method. :-)
  27. If anything doesn't  work,  please  send  me  a  report  and
  28. perhaps you could try to find out, why it doesn't work.
  29.  
  30. Hadmut Danisch <danisch@ira.uka.de>
  31. -----
  32. #! /bin/sh
  33. # This is a shell archive.  Remove anything before this line, then feed it
  34. # into a shell via "sh file" or similar.  To overwrite existing files,
  35. # type "sh file -c".
  36. # Contents:  README CHANGES Makefile.standalone Makefile.use_ppm
  37. #   README.TOO TODO hpcdtoppm.c hpcdtoppm.man simple_viewer
  38. # Wrapped by kent@sparky on Sat Dec 19 20:54:40 1992
  39. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  40. echo If this archive is complete, you will see the following message:
  41. echo '          "shar: End of archive 1 (of 1)."'
  42. if test -f 'README' -a "${1}" != "-c" ; then 
  43.   echo shar: Will not clobber existing file \"'README'\"
  44. else
  45.   echo shar: Extracting \"'README'\" \(2053 characters\)
  46.   sed "s/^X//" >'README' <<'END_OF_FILE'
  47. XThis is Version 0.3 of hpcdtoppm, Hadmut's pcd to ppm converter.
  48. XIt has this name to be distinguishable in case someone
  49. Xelse is producing a program also called pcdtoppm.
  50. X
  51. XRead the README.TOO !
  52. X
  53. XThis program converts Photo-CD-Images to the ppm-Format of
  54. Xpbmplus. You can compile the program in two ways:
  55. X
  56. X1. Use its own ppm-writing-routines. In this case
  57. X   you don't need ppm-includes or libraries. You
  58. X   have to define macro 'OWN_WRITE' in the source or
  59. X   by compiler-option. I am not sure, whether the
  60. X   format of the ppm-header is the same on non-unix
  61. X   machines. If you get problems with line-endings
  62. X   (things like CR, LF, CR/LF), modify the macro
  63. X   PPM_Header.
  64. X
  65. X2. You can use the trusted pbmplus-routines. In this case
  66. X   you need some files from the pbmplus package to compile:
  67. X
  68. X   ppm.h pgm.h pbm.h pbmplus.h libppm.a libpgm.a libpbm.a
  69. X
  70. X
  71. XIMPORTANT: Some older versions of the gcc have problems with
  72. Xoptimization. They produce buggy code. This code will not
  73. Xdie with 'segmentation fault' or something like that, it 
  74. Xjust produces damaged images. 
  75. X
  76. XI did not have detailed information of the file-format and
  77. Xi could test it only with a single Photo-CD with 24 Images.
  78. XMost of my information i got by starring at the hex-dumps
  79. Xof an image file. So i am not absolutly sure, whether it
  80. Xworks on all Photo-CDs, because there are some bytes in
  81. Xthe header which i don't understand. But it works on
  82. Xmy Photo-CD.
  83. X
  84. XNote that you will get a 24 bit image. You can view these
  85. Xfiles with xv, but if you have an 8-bit-screen you will
  86. Xsometimes have some color-defects (if you have an 1-bit-screen
  87. Xyou will often have a lot of color-defects :-). 
  88. XIt will also take some time to show with xv.
  89. X
  90. XYou can produce nice overview prints if you get the icontact
  91. Xprogram of Mark B. Hanson and put something like
  92. X
  93. Xdecode    pcd    hpcdtoppm -1 -a
  94. X
  95. Xin your ~/.icrc .
  96. X
  97. X
  98. XIf you compile the program on a machine other than
  99. XSPARC please send me a short email which machine
  100. Xyou are using, whether you had problems or which
  101. Xchanges you have made.
  102. X
  103. XHadmut  (danisch@ira.uka.de)
  104. X
  105. END_OF_FILE
  106.   if test 2053 -ne `wc -c <'README'`; then
  107.     echo shar: \"'README'\" unpacked with wrong size!
  108.   fi
  109.   # end of 'README'
  110. fi
  111. if test -f 'CHANGES' -a "${1}" != "-c" ; then 
  112.   echo shar: Will not clobber existing file \"'CHANGES'\"
  113. else
  114.   echo shar: Extracting \"'CHANGES'\" \(681 characters\)
  115.   sed "s/^X//" >'CHANGES' <<'END_OF_FILE'
  116. XChanges of hpcdtoppm:
  117. X
  118. Xv0.3:
  119. X- Additional Options -x, -a and -ycc
  120. X
  121. X- bcopy thrown out.
  122. X
  123. X- New datatype sBYTE for char. This fixes the problem with
  124. X  compilers which have the char unsigned. These got some
  125. X  'snow' in their pictures (merry christmas :-).
  126. X
  127. X- Address arithmetik bug fixed in writepicture
  128. X
  129. Xv0.2:
  130. X
  131. X- Small workaround for strange behavior of address-calculation
  132. X  of a c-compiler for NeXT.
  133. X
  134. X- Improved rounding for integer maths.
  135. X
  136. X- Thrown out floating arithmetic, changed color conversion to
  137. X  integer fixed point.
  138. X
  139. X- PPM-writing-routines added. You can choose whether you
  140. X  want to use pbmplus-routines or the included routines.
  141. X
  142. X- some ununused variables thrown out.
  143. X
  144. END_OF_FILE
  145.   if test 681 -ne `wc -c <'CHANGES'`; then
  146.     echo shar: \"'CHANGES'\" unpacked with wrong size!
  147.   fi
  148.   # end of 'CHANGES'
  149. fi
  150. if test -f 'Makefile.standalone' -a "${1}" != "-c" ; then 
  151.   echo shar: Will not clobber existing file \"'Makefile.standalone'\"
  152. else
  153.   echo shar: Extracting \"'Makefile.standalone'\" \(215 characters\)
  154.   sed "s/^X//" >'Makefile.standalone' <<'END_OF_FILE'
  155. XCC=     gcc
  156. XCOPTS=  -O4 
  157. X
  158. X# if you get problems with compilation of "signed",
  159. X# read the README.TOO and try something like -DsBYTE=char
  160. X
  161. X
  162. Xhpcdtoppm: hpcdtoppm.c 
  163. X    ${CC} ${COPTS} -DOWN_WRITE -o hpcdtoppm hpcdtoppm.c
  164. END_OF_FILE
  165.   if test 215 -ne `wc -c <'Makefile.standalone'`; then
  166.     echo shar: \"'Makefile.standalone'\" unpacked with wrong size!
  167.   fi
  168.   # end of 'Makefile.standalone'
  169. fi
  170. if test -f 'Makefile.use_ppm' -a "${1}" != "-c" ; then 
  171.   echo shar: Will not clobber existing file \"'Makefile.use_ppm'\"
  172. else
  173.   echo shar: Extracting \"'Makefile.use_ppm'\" \(282 characters\)
  174.   sed "s/^X//" >'Makefile.use_ppm' <<'END_OF_FILE'
  175. XCC=    gcc
  176. XCOPTS=    -O -g
  177. X
  178. X
  179. X
  180. X# if you get problems with compilation of "signed",
  181. X# read the README.TOO and try something like -DsBYTE=char
  182. X
  183. X
  184. X
  185. Xhpcdtoppm: hpcdtoppm.o 
  186. X    ${CC} -o hpcdtoppm hpcdtoppm.o -lm libppm.a libpgm.a libpbm.a
  187. X
  188. Xhpcdtoppm.o: hpcdtoppm.c
  189. X    ${CC} ${COPTS}  -c hpcdtoppm.c
  190. END_OF_FILE
  191.   if test 282 -ne `wc -c <'Makefile.use_ppm'`; then
  192.     echo shar: \"'Makefile.use_ppm'\" unpacked with wrong size!
  193.   fi
  194.   # end of 'Makefile.use_ppm'
  195. fi
  196. if test -f 'README.TOO' -a "${1}" != "-c" ; then 
  197.   echo shar: Will not clobber existing file \"'README.TOO'\"
  198. else
  199.   echo shar: Extracting \"'README.TOO'\" \(997 characters\)
  200.   sed "s/^X//" >'README.TOO' <<'END_OF_FILE'
  201. XHere are some additional informations for installing and use:
  202. X
  203. XI.   Several people had 'snowy' images with v0.1 and v0.2.
  204. X     This happens when the machine handles the standard
  205. X     type char unsigned. Therefore the datatype sBYTE
  206. X     was introduced as 'signed char'. If your compiler
  207. X     doesn't understand this, change sBYTE to such a datatype
  208. X     of your compiler or use a commandlineoption like
  209. X     -DsBYTE=char .
  210. XII.  Not every image contains all resolutions (especially images
  211. X     from demo disks). You can't extract resolutions which are
  212. X     not contained.
  213. X
  214. XIII. Some cdrom drives read more than the data sectors of the 
  215. X     PhotoCD files. They read additional sector headers etc.
  216. X     In this case to have to write a little conversion tool.
  217. X
  218. X     E.g.: Sony NEWS, model NWS-3720
  219. X           Write a simple filter program, which takes the file,
  220. X           cuts in slices of 0x920 size, takes out 0x800 data 
  221. X           with offset 8 of each slice and write them out in a new file.
  222. END_OF_FILE
  223.   if test 997 -ne `wc -c <'README.TOO'`; then
  224.     echo shar: \"'README.TOO'\" unpacked with wrong size!
  225.   fi
  226.   # end of 'README.TOO'
  227. fi
  228. if test -f 'TODO' -a "${1}" != "-c" ; then 
  229.   echo shar: Will not clobber existing file \"'TODO'\"
  230. else
  231.   echo shar: Extracting \"'TODO'\" \(356 characters\)
  232.   sed "s/^X//" >'TODO' <<'END_OF_FILE'
  233. XThings i want to do when i find time:
  234. X
  235. X
  236. X- Implement additional parameters for color decoding
  237. X
  238. X- Implement routines to decode only cut out subrectangle of higher
  239. X  resolutions.
  240. X
  241. X- Implement a 'fast lookup-table' for huffman decoding.
  242. X
  243. X- speedup.
  244. X
  245. X- Make a "small memory mode". This to extract the 
  246. X  high resolutions even if you have not enough 
  247. X  memory.
  248. X
  249. END_OF_FILE
  250.   if test 356 -ne `wc -c <'TODO'`; then
  251.     echo shar: \"'TODO'\" unpacked with wrong size!
  252.   fi
  253.   # end of 'TODO'
  254. fi
  255. if test -f 'hpcdtoppm.c' -a "${1}" != "-c" ; then 
  256.   echo shar: Will not clobber existing file \"'hpcdtoppm.c'\"
  257. else
  258.   echo shar: Extracting \"'hpcdtoppm.c'\" \(34342 characters\)
  259.   sed "s/^X//" >'hpcdtoppm.c' <<'END_OF_FILE'
  260. X/* hpcdtoppm (Hadmut's pcdtoppm) v0.3
  261. X*  Copyright (c) 1992 by Hadmut Danisch (danisch@ira.uka.de).
  262. X*  Permission to use and distribute this software and its
  263. X*  documentation for noncommercial use and without fee is hereby granted,
  264. X*  provided that the above copyright notice appear in all copies and that
  265. X*  both that copyright notice and this permission notice appear in
  266. X*  supporting documentation. It is not allowed to sell this software in 
  267. X*  any way. This software is not public domain.
  268. X*/
  269. X
  270. X
  271. X/* define OWN_WRITE either here or by compiler-option if you don't want to use
  272. X   the pbmplus-routines for writing */
  273. X#define xOWN_WRITE
  274. X
  275. X
  276. X/* define DEBUG for some debugging informations, just remove the x from xDEBUG */
  277. X#define xDEBUG
  278. X
  279. X/* define MELDUNG if you want to see what is happening and what takes time,
  280. X   just remove the x from xMeldung */
  281. X#define xMELDUNG
  282. X
  283. X
  284. X
  285. X
  286. X
  287. X#include <stdio.h>
  288. X
  289. X#ifndef OWN_WRITE
  290. X
  291. X#include "ppm.h"
  292. X
  293. X#else
  294. X
  295. X/* If the own routines are used, this is the size of the buffer in bytes.
  296. X   You can shrink if needed. */
  297. X#define own_BUsize 50000
  298. X
  299. X/* The header for the ppm-files */
  300. X#define PPM_Header "P6\n%d %d\n255\n"
  301. X
  302. X
  303. X#endif
  304. X
  305. X
  306. X/*
  307. X** Important: sBYTE must be a signed byte type !!!
  308. X**
  309. X*/
  310. X
  311. X#ifndef sBYTE
  312. Xtypedef   signed char sBYTE;
  313. X#endif
  314. X
  315. Xtypedef unsigned char uBYTE;
  316. Xtypedef unsigned long dim;
  317. X
  318. X#define BaseW ((dim)768)
  319. X#define BaseH ((dim)512)
  320. X
  321. X#define SECSIZE 0x800
  322. X
  323. X
  324. X
  325. X#define SeHead   2
  326. X#define L_Head   (1+SeHead)
  327. X
  328. X#define SeBase16 18
  329. X#define L_Base16 (1+SeBase16)
  330. X
  331. X#define SeBase4  72
  332. X#define L_Base4  (1+SeBase4)
  333. X
  334. X#define SeBase   288
  335. X#define L_Base   (1+SeBase)
  336. X
  337. X
  338. X
  339. X
  340. X
  341. X
  342. Xenum ERRORS { E_NONE,E_READ,E_WRITE,E_INTERN,E_ARG,E_OPT,E_MEM,E_HUFF,
  343. X             E_SEQ,E_SEQ1,E_SEQ2,E_SEQ3,E_SEQ4,E_SEQ5,E_SEQ6,E_SEQ7,E_POS,E_IMP,E_OVSKIP,
  344. X             E_TAUTO,E_TCANT };
  345. X
  346. Xenum TURNS  { T_NONE,T_RIGHT,T_LEFT,T_AUTO };
  347. X
  348. Xenum SIZES  { S_UNSPEC,S_Base16,S_Base4,S_Base,S_4Base,S_16Base,S_Over };
  349. X
  350. X/* Default taken when no size parameter given */
  351. X#define S_DEFAULT S_Base16
  352. X
  353. X
  354. X
  355. X
  356. X
  357. Xstruct _implane
  358. X {dim  mwidth,mheight,
  359. X       iwidth,iheight;
  360. X  uBYTE *im;
  361. X };
  362. Xtypedef struct _implane implane;
  363. X
  364. X#define nullplane ((implane *) 0)
  365. X
  366. X
  367. Xstatic enum ERRORS readplain();
  368. Xstatic void interpolate();
  369. Xstatic void halve();
  370. Xstatic void ycctorgb();
  371. Xstatic void writepicture();
  372. Xstatic void readlpt();
  373. Xstatic void readhqt();
  374. Xstatic void decode();
  375. Xstatic void clear();
  376. Xstatic void druckeid();
  377. Xstatic void sharpit();
  378. Xstatic long Skip4Base();
  379. X
  380. Xstatic FILE *fin=0,*fout=0;
  381. Xstatic char *pcdname=0,*ppmname=0;
  382. Xstatic char nbuf[100];
  383. Xstatic uBYTE sbuffer[SECSIZE];
  384. Xstatic int do_sharp,keep_ycc;
  385. X
  386. X
  387. X
  388. X
  389. X/* Using preprocessor for inline-procs */
  390. X#ifdef DEBUG
  391. X
  392. Xstatic long bufpos;
  393. X
  394. X#define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) error(E_READ);\
  395. X                  fprintf(stderr,"S-Position %x\n",ftell(fin)); }
  396. X#define RPRINT  {fprintf(stderr,"R-Position %x\n",ftell(fin));}
  397. X
  398. X#define READBUF   (bufpos=ftell(fin),fread(sbuffer,sizeof(sbuffer),1,fin))
  399. X
  400. X
  401. X#else
  402. X
  403. X#define SEEK(x) { if (fseek(fin,((x) * SECSIZE),0)) error(E_READ);}
  404. X#define RPRINT
  405. X#define READBUF   fread(sbuffer,sizeof(sbuffer),1,fin)
  406. X
  407. X#endif
  408. X
  409. X
  410. X#ifdef MELDUNG
  411. X#define melde(x) fprintf(stderr,x)
  412. X#else
  413. X#define melde(x)
  414. X#endif
  415. X
  416. X
  417. X
  418. X
  419. X
  420. X
  421. X
  422. X
  423. X#define EREADBUF {if(READBUF < 1) error(E_READ);}
  424. X
  425. X#define SKIP(n)  { if (fseek(fin,(n),1)) error(E_READ);}
  426. X#define SKIPr(n) { if (fseek(fin,(n),1)) return(E_READ);}
  427. X
  428. X
  429. X#define xTRIF(x,u,o,a,b,c) ((x)<(u)? (a) : ( (x)>(o)?(c):(b)  ))
  430. X#define xNORM(x) x=TRIF(x,0,255,0,x,255)
  431. X#define NORM(x) { if(x<0) x=0; else if (x>255) x=255;}
  432. X
  433. X
  434. X
  435. X
  436. X
  437. Xstatic void error(e)
  438. X  enum ERRORS e;
  439. X {
  440. X  
  441. X  switch(e)
  442. X   {case E_NONE:   return;
  443. X    case E_IMP:    fprintf(stderr,"Sorry, Not yet implemented.\n"); break;
  444. X    case E_READ:   fprintf(stderr,"Error while reading.\n"); break;
  445. X    case E_WRITE:  fprintf(stderr,"Error while writing.\n"); break;
  446. X    case E_INTERN: fprintf(stderr,"Internal error.\n"); break;
  447. X    case E_ARG:    fprintf(stderr,"Error in Arguments !\n\n"); 
  448. X                   fprintf(stderr,"Usage: hpcdtoppm [options] pcd-file [ppm-file]\n\n");
  449. X                   fprintf(stderr,"Opts:\n");
  450. X                   fprintf(stderr,"     -x Overskip mode (tries to improve color quality.)\n");
  451. X                   fprintf(stderr,"     -i Give some (buggy) informations from fileheader\n");
  452. X                   fprintf(stderr,"     -s Apply simple sharpness-operator on the Luma-channel\n");
  453. X                   fprintf(stderr,"     -d Show differential picture only \n\n");
  454. X                   fprintf(stderr,"     -r Rotate clockwise for portraits\n");
  455. X                   fprintf(stderr,"     -l Rotate counter-clockwise for portraits\n");
  456. X                   fprintf(stderr,"     -a Try to find out orientation automatically.\n");
  457. X                   fprintf(stderr,"        (Experimentally, please report if it doesn't work.)\n\n");
  458. X                   fprintf(stderr,"     -ycc suppress ycc to rgb conversion \n");
  459. X                   fprintf(stderr,"        (Experimentally, doesn't have deeper sense)\n\n");
  460. X                   fprintf(stderr,"     -0 Extract thumbnails from Overview file\n");
  461. X                   fprintf(stderr,"     -1 Extract  128x192  from Image file\n");
  462. X                   fprintf(stderr,"     -2 Extract  256x384  from Image file\n");
  463. X                   fprintf(stderr,"     -3 Extract  512x768  from Image file\n");
  464. X                   fprintf(stderr,"     -4 Extract 1024x1536 from Image file\n");
  465. X                   fprintf(stderr,"     -5 Extract 2048x3072 from Image file\n");
  466. X                   fprintf(stderr,"\n");
  467. X                   break;
  468. X    case E_OPT:    fprintf(stderr,"These Options are not allowed together.\n");break;
  469. X    case E_MEM:    fprintf(stderr,"Not enough memory !\n"); break;
  470. X    case E_HUFF:   fprintf(stderr,"Error in Huffman-Code-Table\n"); break;
  471. X    case E_SEQ:    fprintf(stderr,"Error in Huffman-Sequence\n"); break;
  472. X    case E_SEQ1:   fprintf(stderr,"Error1 in Huffman-Sequence\n"); break;
  473. X    case E_SEQ2:   fprintf(stderr,"Error2 in Huffman-Sequence\n"); break;
  474. X    case E_SEQ3:   fprintf(stderr,"Error3 in Huffman-Sequence\n"); break;
  475. X    case E_SEQ4:   fprintf(stderr,"Error4 in Huffman-Sequence\n"); break;
  476. X    case E_SEQ5:   fprintf(stderr,"Error5 in Huffman-Sequence\n"); break;
  477. X    case E_SEQ6:   fprintf(stderr,"Error6 in Huffman-Sequence\n"); break;
  478. X    case E_SEQ7:   fprintf(stderr,"Error7 in Huffman-Sequence\n"); break;
  479. X    case E_POS:    fprintf(stderr,"Error in file-position\n"); break;
  480. X    case E_OVSKIP: fprintf(stderr,"Can't read this resolution in overskip-mode\n"); break;
  481. X    case E_TAUTO:  fprintf(stderr,"Can't determine the orientation in overview mode\n");break;
  482. X    case E_TCANT:  fprintf(stderr,"Sorry, can't determine orientation for this file.\n");
  483. X                   fprintf(stderr,"Please give orientation parameters. \n");break;
  484. X    default:       fprintf(stderr,"Unknown error %d ???\n",e);break;
  485. X   }
  486. X  if(fin) fclose(fin);
  487. X  if(fout && ppmname) fclose(fout);
  488. X  exit(9);
  489. X }
  490. X
  491. X
  492. X
  493. X
  494. X
  495. X
  496. X
  497. X
  498. X
  499. Xstatic void planealloc(p,width,height)
  500. X  implane *p;
  501. X  dim width,height;
  502. X {
  503. X  p->iwidth=p->iheight=0;
  504. X  p->mwidth=width;
  505. X  p->mheight=height;
  506. X
  507. X  p->im = ( uBYTE * ) malloc  (width*height*sizeof(uBYTE));
  508. X  if(!(p->im)) error(E_MEM);
  509. X }
  510. X
  511. X
  512. X
  513. X
  514. Xvoid main(argc,argv)
  515. X  int argc;
  516. X  char **argv;
  517. X#define ASKIP { argc--; argv ++;}
  518. X{int bildnr;
  519. X char *opt;
  520. X dim w,h;
  521. X long cd_offset,cd_offhelp;
  522. X int do_info,do_diff,do_overskip;
  523. X
  524. X enum TURNS turn=T_NONE;
  525. X enum SIZES size=S_UNSPEC;
  526. X enum ERRORS eret;
  527. X implane Luma, Chroma1,Chroma2;
  528. X
  529. X do_info=do_diff=do_overskip=do_sharp=keep_ycc=0;
  530. X
  531. X ASKIP;
  532. X
  533. X while((argc>0) && **argv=='-')
  534. X  {
  535. X   opt= (*argv)+1;
  536. X   ASKIP;
  537. X
  538. X   if(!strcmp(opt,"r"))
  539. X    {if (turn == T_NONE) turn=T_RIGHT;
  540. X     else error(E_ARG);
  541. X     continue;
  542. X    }
  543. X
  544. X   if(!strcmp(opt,"l"))
  545. X    {if (turn == T_NONE) turn=T_LEFT;
  546. X     else error(E_ARG);
  547. X     continue;
  548. X    }
  549. X
  550. X    if(!strcmp(opt,"a"))
  551. X    {if (turn == T_NONE) turn=T_AUTO;
  552. X     else error(E_ARG);
  553. X     continue;
  554. X    }
  555. X
  556. X   if(!strcmp(opt,"i")) 
  557. X    { if (!do_info) do_info=1;
  558. X      else error(E_ARG);
  559. X      continue;
  560. X    }
  561. X
  562. X
  563. X   if(!strcmp(opt,"d")) 
  564. X    { if (!do_diff) do_diff=1;
  565. X      else error(E_ARG);
  566. X      continue;
  567. X    }
  568. X
  569. X   if(!strcmp(opt,"s")) 
  570. X    { if (!do_sharp) do_sharp=1;
  571. X      else error(E_ARG);
  572. X      continue;
  573. X    }
  574. X
  575. X
  576. X   if(!strcmp(opt,"x")) 
  577. X    { if (!do_overskip) do_overskip=1;
  578. X      else error(E_ARG);
  579. X      continue;
  580. X    }
  581. X
  582. X
  583. X   if(!strcmp(opt,"ycc")) 
  584. X    { if (!keep_ycc) keep_ycc=1;
  585. X      else error(E_ARG);
  586. X      continue;
  587. X    }
  588. X
  589. X
  590. X
  591. X   
  592. X   if((!strcmp(opt,"Base/16")) || (!strcmp(opt,"1"))  || (!strcmp(opt,"128x192")))
  593. X    { if (size == S_UNSPEC) size = S_Base16;
  594. X      else error(E_ARG);
  595. X      continue;
  596. X    }
  597. X   if((!strcmp(opt,"Base/4" )) || (!strcmp(opt,"2"))  || (!strcmp(opt,"256x384")))
  598. X    { if (size == S_UNSPEC) size = S_Base4;
  599. X      else error(E_ARG);
  600. X      continue;
  601. X    }
  602. X   if((!strcmp(opt,"Base"   )) || (!strcmp(opt,"3"))  || (!strcmp(opt,"512x768")))
  603. X    { if (size == S_UNSPEC) size = S_Base;
  604. X      else error(E_ARG);
  605. X      continue;
  606. X    }
  607. X   if((!strcmp(opt,"4Base"  )) || (!strcmp(opt,"4"))  || (!strcmp(opt,"1024x1536")))
  608. X    { if (size == S_UNSPEC) size = S_4Base;
  609. X      else error(E_ARG);
  610. X      continue;
  611. X    }
  612. X   if((!strcmp(opt,"16Base" )) || (!strcmp(opt,"5"))  || (!strcmp(opt,"2048x3072")))
  613. X    { if (size == S_UNSPEC) size = S_16Base;
  614. X      else error(E_ARG);
  615. X      continue;
  616. X    }
  617. X
  618. X   if((!strcmp(opt,"Overview" )) || (!strcmp(opt,"0"))  || (!strcmp(opt,"O")))
  619. X    { if (size == S_UNSPEC) size = S_Over;
  620. X      else error(E_ARG);
  621. X      continue;
  622. X    }
  623. X
  624. X  fprintf(stderr,"Unknown option: -%s\n",opt);
  625. X  error(E_ARG);
  626. X  }
  627. X
  628. X
  629. X
  630. X
  631. X  if(size==S_UNSPEC) size=S_DEFAULT;
  632. X
  633. X  if(argc<1) error(E_ARG);
  634. X  pcdname= *argv;
  635. X  ASKIP;
  636. X
  637. X  if(argc>0) 
  638. X   {ppmname= *argv;
  639. X    ASKIP;
  640. X   }
  641. X  
  642. X  if(argc>0) error(E_ARG);
  643. X  if((size==S_Over) && (!ppmname)) error(E_ARG);
  644. X  if(do_info && (size==S_Over)) error(E_OPT);
  645. X  if(do_overskip && do_diff) error(E_OPT);
  646. X  if(do_diff && (size != S_4Base) && (size != S_16Base)) error(E_OPT);
  647. X  if(do_overskip && (size != S_Base16) && (size != S_Base4) && (size != S_Base) && (size != S_4Base) ) error(E_OVSKIP);
  648. X  if((turn==T_AUTO)&&(size==S_Over)) error(E_TAUTO);
  649. X  
  650. X
  651. X
  652. X
  653. X
  654. X  if(!(fin=fopen(pcdname,"r"))) error(E_READ);
  655. X
  656. X  if(do_info || (turn==T_AUTO)) 
  657. X   { SEEK(1);
  658. X     EREADBUF;
  659. X   }
  660. X
  661. X  if(turn==T_AUTO)
  662. X   {
  663. X    switch(sbuffer[0xe02 & 0x7ff]&0x03)
  664. X     {case 0x00: turn=T_NONE;  break;
  665. X      case 0x01: turn=T_LEFT;  break;
  666. X      case 0x03: turn=T_RIGHT; break;
  667. X      default: error(E_TCANT);
  668. X     }
  669. X   }
  670. X
  671. X  if(do_info) druckeid();
  672. X
  673. X
  674. X
  675. X
  676. X
  677. X  switch(size)
  678. X   {
  679. X    case S_Base16: w=BaseW/4;
  680. X                   h=BaseH/4;
  681. X                   planealloc(&Luma   ,w,h);
  682. X                   planealloc(&Chroma1,w,h);
  683. X                   planealloc(&Chroma2,w,h);
  684. X
  685. X                   if(!do_overskip)
  686. X                     { SEEK(L_Head+1);
  687. X                       error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  688. X                       interpolate(&Chroma1);
  689. X                       interpolate(&Chroma2);
  690. X                     }
  691. X                   else
  692. X                     { SEEK(L_Head+1);
  693. X                       error(readplain(w,h,&Luma,nullplane,nullplane));
  694. X                       SEEK(L_Head+L_Base16+1);
  695. X                       error(readplain(2*w,2*h,nullplane,&Chroma1,&Chroma2));
  696. X                     }
  697. X                    
  698. X
  699. X                   ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  700. X                   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  701. X
  702. X                   if(!ppmname) fout=stdout;
  703. X                   else
  704. X                    {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  705. X            }
  706. X                   writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  707. X
  708. X                   break;
  709. X
  710. X    case S_Base4:  w=BaseW/2;
  711. X                   h=BaseH/2;
  712. X                   planealloc(&Luma   ,w,h);
  713. X                   planealloc(&Chroma1,w,h);
  714. X                   planealloc(&Chroma2,w,h);
  715. X
  716. X
  717. X
  718. X                  if(!do_overskip)
  719. X                     { SEEK(L_Head+L_Base16+1);
  720. X                       error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  721. X                       interpolate(&Chroma1);
  722. X                       interpolate(&Chroma2);
  723. X                     }
  724. X                   else
  725. X                     { SEEK(L_Head+L_Base16+1);
  726. X                       error(readplain(w,h,&Luma,nullplane,nullplane));
  727. X                       SEEK(L_Head+L_Base16+L_Base4+1); 
  728. X                       error(readplain(2*w,2*h,nullplane,&Chroma1,&Chroma2));
  729. X                     }
  730. X                   ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  731. X                   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  732. X
  733. X                   if(!ppmname) fout=stdout;
  734. X                   else
  735. X                    {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  736. X            }
  737. X                   writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  738. X
  739. X                   break;
  740. X
  741. X    case S_Base:   w=BaseW;
  742. X                   h=BaseH;
  743. X
  744. X                   if(!do_overskip)
  745. X                     { planealloc(&Luma   ,w,h);
  746. X                       planealloc(&Chroma1,w,h);
  747. X                       planealloc(&Chroma2,w,h);
  748. X                       SEEK(L_Head+L_Base16+L_Base4+1);
  749. X                       error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  750. X                       interpolate(&Chroma1);
  751. X                       interpolate(&Chroma2);
  752. X                     }
  753. X                   else
  754. X                     { planealloc(&Luma   ,  w,  h);
  755. X                       planealloc(&Chroma1,2*w,2*h);
  756. X                       planealloc(&Chroma2,2*w,2*h);
  757. X                       SEEK(L_Head+L_Base16+L_Base4+1);
  758. X                       error(readplain(w,h,&Luma,&Chroma1,&Chroma2));
  759. X                       interpolate(&Chroma1);
  760. X                       interpolate(&Chroma2);
  761. X                       interpolate(&Chroma1);
  762. X                       interpolate(&Chroma2);
  763. X
  764. X                       cd_offset=Skip4Base();
  765. X                       SEEK(cd_offset+10);          EREADBUF;    cd_offhelp=(((long)sbuffer[2])<<8)|sbuffer[3];
  766. X                       SEEK(cd_offset+12);          readhqt(w,h,3);
  767. X                       SEEK(cd_offset+cd_offhelp);  decode(4*w,4*h,nullplane,&Chroma1,&Chroma2,1);
  768. X
  769. X                       halve(&Chroma1);
  770. X                       halve(&Chroma2);
  771. X                     }
  772. X                   ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  773. X                   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  774. X
  775. X                   if(!ppmname) fout=stdout;
  776. X                   else
  777. X                    {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  778. X            }
  779. X                   writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  780. X
  781. X                   break;
  782. X
  783. X    case S_4Base:  w=BaseW*2;
  784. X                   h=BaseH*2;
  785. X                   planealloc(&Luma,w,h);
  786. X                   planealloc(&Chroma1,w,h);
  787. X                   planealloc(&Chroma2,w,h);
  788. X
  789. X                  if(!do_overskip)
  790. X                     {SEEK(L_Head+L_Base16+L_Base4+1);
  791. X                      error(readplain(w/2,h/2,&Luma,&Chroma1,&Chroma2));
  792. X                      interpolate(&Luma);
  793. X                      interpolate(&Chroma1);
  794. X                      interpolate(&Chroma1);
  795. X                      interpolate(&Chroma2);
  796. X                      interpolate(&Chroma2);
  797. X
  798. X                      if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
  799. X
  800. X                      cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  801. X                      SEEK(cd_offset + 4);     readhqt(w,h,1);
  802. X                      SEEK(cd_offset + 5);     decode(w,h,&Luma,nullplane,nullplane,0);
  803. X                     }
  804. X                   else
  805. X                     {SEEK(L_Head+L_Base16+L_Base4+1);
  806. X                      error(readplain(w/2,h/2,&Luma,&Chroma1,&Chroma2));
  807. X                      interpolate(&Luma);
  808. X                      interpolate(&Chroma1);
  809. X                      interpolate(&Chroma1);
  810. X                      interpolate(&Chroma2);
  811. X                      interpolate(&Chroma2);
  812. X
  813. X                      cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  814. X                      SEEK(cd_offset + 4);     readhqt(w,h,1);
  815. X                      SEEK(cd_offset + 5);     decode(w,h,&Luma,nullplane,nullplane,0);
  816. X
  817. X                      cd_offset=ftell(fin);if(cd_offset % SECSIZE) error(E_POS);cd_offset/=SECSIZE;
  818. X                      SEEK(cd_offset+10);          EREADBUF;    cd_offhelp=(((long)sbuffer[2])<<8)|sbuffer[3];
  819. X                      SEEK(cd_offset+12);          readhqt(w,h,3);
  820. X                      SEEK(cd_offset+cd_offhelp);  decode(2*w,2*h,nullplane,&Chroma1,&Chroma2,1);
  821. X                     
  822. X                     }
  823. X                   ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  824. X                   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  825. X
  826. X                   if(!ppmname) fout=stdout;
  827. X                   else
  828. X                    {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  829. X            }
  830. X                   writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  831. X
  832. X                   break;
  833. X
  834. X    case S_16Base: w=BaseW*4;
  835. X                   h=BaseH*4;
  836. X                   planealloc(&Luma,w,h);
  837. X                   planealloc(&Chroma1,w,h);
  838. X                   planealloc(&Chroma2,w,h);
  839. X
  840. X                   SEEK(L_Head+L_Base16+L_Base4+1);
  841. X                   error(readplain(w/4,h/4,&Luma,&Chroma1,&Chroma2));
  842. X                   interpolate(&Luma);
  843. X                   interpolate(&Chroma1);
  844. X                   interpolate(&Chroma1);
  845. X                   interpolate(&Chroma2);
  846. X                   interpolate(&Chroma2);
  847. X
  848. X                   cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  849. X                   SEEK(cd_offset + 4);       readhqt(w/2,h/2,1);
  850. X                   SEEK(cd_offset + 5);       decode(w/2,h/2,&Luma,nullplane,nullplane,0);
  851. X                   interpolate(&Luma);
  852. X
  853. X                   if(do_diff) {clear(&Luma,128);clear(&Chroma1,156);clear(&Chroma2,137);}
  854. X
  855. X                   cd_offset=ftell(fin);if(cd_offset % SECSIZE) error(E_POS);cd_offset/=SECSIZE;
  856. X
  857. X                   SEEK(cd_offset+12);        readhqt(w,h,3);
  858. X                   SEEK(cd_offset+14);        decode(w,h,&Luma,&Chroma1,&Chroma2,0);
  859. X
  860. X                   interpolate(&Chroma1);
  861. X                   interpolate(&Chroma2);
  862. X
  863. X                   ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  864. X                   /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  865. X
  866. X                   if(!ppmname) fout=stdout;
  867. X                   else
  868. X                    {if (!(fout=fopen(ppmname,"w"))) error(E_WRITE);
  869. X            }
  870. X                   writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  871. X
  872. X                   break;
  873. X
  874. X    case S_Over:   w=BaseW/4;
  875. X                   h=BaseH/4;
  876. X             
  877. X                   planealloc(&Luma   ,w,h);
  878. X                   planealloc(&Chroma1,w,h);
  879. X                   planealloc(&Chroma2,w,h);
  880. X
  881. X                   for(bildnr=0;!feof(fin);bildnr++)
  882. X            {
  883. X               SEEK(5+SeBase16*bildnr);
  884. X    
  885. X               eret=readplain(w,h,&Luma,&Chroma1,&Chroma2);
  886. X                       if(eret==E_READ) break;
  887. X                       error(eret);
  888. X
  889. X               interpolate(&Chroma1);
  890. X               interpolate(&Chroma2);
  891. X    
  892. X               ycctorgb(w,h,&Luma,&Chroma1,&Chroma2);
  893. X               /* Now Luma holds red, Chroma1 hold green, Chroma2 holds blue */
  894. X    
  895. X                       sprintf(nbuf,"%s%04d",ppmname,bildnr+1);
  896. X               if (!(fout=fopen(nbuf,"w"))) error(E_WRITE);
  897. X               writepicture(w,h,&Luma,&Chroma1,&Chroma2,turn);
  898. X             }
  899. X                   break;
  900. X
  901. X     default: error(E_INTERN); 
  902. X   }
  903. X
  904. X
  905. X
  906. X
  907. Xexit(0);
  908. X
  909. X
  910. X
  911. X}
  912. X#undef ASKIP
  913. X
  914. X
  915. X
  916. X
  917. X
  918. X
  919. Xstatic enum ERRORS readplain(w,h,l,c1,c2)
  920. X  dim w,h;
  921. X  implane *l,*c1,*c2;
  922. X {dim i;
  923. X  uBYTE *pl=0,*pc1=0,*pc2=0;
  924. X  melde("readplain\n");
  925. X
  926. X  if(l)
  927. X   { if ((l->mwidth<w) || (l->mheight<h) || (!l->im)) error(E_INTERN);
  928. X     l->iwidth=w;
  929. X     l->iheight=h;
  930. X     pl=l->im;
  931. X   }
  932. X
  933. X  if(c1)
  934. X   { if ((c1->mwidth<w/2) || (c1->mheight<h/2) || (!c1->im)) error(E_INTERN);
  935. X     c1->iwidth=w/2;
  936. X     c1->iheight=h/2;
  937. X     pc1=c1->im;
  938. X   }
  939. X
  940. X  if(c2)
  941. X   { if ((c2->mwidth<w/2) || (c2->mheight<h/2) || (!c2->im)) error(E_INTERN);
  942. X     c2->iwidth=w/2;
  943. X     c2->iheight=h/2;
  944. X     pc2=c2->im;
  945. X   }
  946. X
  947. X  for(i=0;i<h/2;i++)
  948. X   {
  949. X    if(pl)
  950. X     { 
  951. X       if(fread(pl,w,1,fin)<1) return(E_READ);
  952. X       pl+= l->mwidth;
  953. X
  954. X       if(fread(pl,w,1,fin)<1) return(E_READ);
  955. X       pl+= l->mwidth;
  956. X     }
  957. X    else SKIPr(2*w);
  958. X     
  959. X    if(pc1)
  960. X     { if(fread(pc1,w/2,1,fin)<1) return(E_READ);
  961. X       pc1+= c1->mwidth;
  962. X     }
  963. X    else SKIPr(w/2);
  964. X     
  965. X    if(pc2)
  966. X     { if(fread(pc2,w/2,1,fin)<1) return(E_READ);
  967. X       pc2+= c2->mwidth;
  968. X     }
  969. X    else SKIPr(w/2);
  970. X
  971. X
  972. X   }
  973. X  RPRINT;
  974. X  return E_NONE;
  975. X }
  976. X
  977. X
  978. X
  979. X
  980. X
  981. X
  982. X
  983. X
  984. X
  985. X
  986. X
  987. Xstatic void interpolate(p)
  988. X  implane *p;
  989. X {dim w,h,x,y,yi;
  990. X  uBYTE *optr,*nptr,*uptr;
  991. X
  992. X  melde("interpolate\n");
  993. X  if ((!p) || (!p->im)) error(E_INTERN);
  994. X
  995. X  w=p->iwidth;
  996. X  h=p->iheight;
  997. X
  998. X  if(p->mwidth  < 2*w ) error(E_INTERN);
  999. X  if(p->mheight < 2*h ) error(E_INTERN);
  1000. X
  1001. X
  1002. X  p->iwidth=2*w;
  1003. X  p->iheight=2*h;
  1004. X
  1005. X
  1006. X  for(y=0;y<h;y++)
  1007. X   {yi=h-1-y;
  1008. X    optr=p->im+  yi*p->mwidth + (w-1);
  1009. X    nptr=p->im+2*yi*p->mwidth + (2*w - 2);
  1010. X
  1011. X    nptr[0]=nptr[1]=optr[0];
  1012. X
  1013. X    for(x=1;x<w;x++)
  1014. X     { optr--; nptr-=2;
  1015. X       nptr[0]=optr[0];
  1016. X       nptr[1]=(((int)optr[0])+((int)optr[1])+1)>>1;
  1017. X     }
  1018. X    }
  1019. X
  1020. X  for(y=0;y<h-1;y++)
  1021. X   {optr=p->im + 2*y*p->mwidth;
  1022. X    nptr=optr+p->mwidth;
  1023. X    uptr=nptr+p->mwidth;
  1024. X
  1025. X    for(x=0;x<w-1;x++)
  1026. X     {
  1027. X      nptr[0]=(((int)optr[0])+((int)uptr[0])+1)>>1;
  1028. X      nptr[1]=(((int)optr[0])+((int)optr[2])+((int)uptr[0])+((int)uptr[2])+2)>>2;
  1029. X      nptr+=2; optr+=2; uptr+=2;
  1030. X     }
  1031. X    *(nptr++)=(((int)*(optr++))+((int)*(uptr++))+1)>>1;
  1032. X    *(nptr++)=(((int)*(optr++))+((int)*(uptr++))+1)>>1;
  1033. X   }
  1034. X
  1035. X
  1036. X  optr=p->im + (2*h-2)*p->mwidth;
  1037. X  nptr=p->im + (2*h-1)*p->mwidth;
  1038. X  for(x=0;x<w;x++)
  1039. X   { *(nptr++) = *(optr++);  *(nptr++) = *(optr++); }
  1040. X
  1041. X }
  1042. X
  1043. X
  1044. X
  1045. X
  1046. X
  1047. X
  1048. X
  1049. X
  1050. X
  1051. X
  1052. Xstatic void halve(p)
  1053. X  implane *p;
  1054. X {dim w,h,x,y;
  1055. X  uBYTE *optr,*nptr;
  1056. X
  1057. X  melde("halve\n");
  1058. X  if ((!p) || (!p->im)) error(E_INTERN);
  1059. X
  1060. X  w=p->iwidth/=2;      
  1061. X  h=p->iheight/=2;     
  1062. X
  1063. X
  1064. X  for(y=0;y<h;y++)
  1065. X   {
  1066. X    nptr=(p->im) +   y*(p->mwidth);
  1067. X    optr=(p->im) + 2*y*(p->mwidth);
  1068. X
  1069. X    for(x=0;x<w;x++,nptr++,optr+=2)
  1070. X     { *nptr = *optr;
  1071. X     }
  1072. X
  1073. X   }
  1074. X
  1075. X }
  1076. X
  1077. X
  1078. X
  1079. X
  1080. X
  1081. X
  1082. X
  1083. X
  1084. X
  1085. X
  1086. X
  1087. X#define BitShift 12
  1088. X
  1089. Xstatic void ycctorgb(w,h,l,c1,c2)
  1090. X  dim w,h;
  1091. X  implane *l,*c1,*c2;
  1092. X {dim x,y;
  1093. X  uBYTE *pl,*pc1,*pc2;
  1094. X  long red,green,blue,i;
  1095. X  long L;
  1096. X  static int init=0;
  1097. X  static long XL[256],XC1[256],XC2[256],XC1g[256],XC2g[256];
  1098. X
  1099. X  melde("ycctorgb\n");
  1100. X  if((!l ) || ( l->iwidth != w ) || ( l->iheight != h) || (! l->im)) error(E_INTERN);
  1101. X  if((!c1) || (c1->iwidth != w ) || (c1->iheight != h) || (!c1->im)) error(E_INTERN);
  1102. X  if((!c2) || (c2->iwidth != w ) || (c2->iheight != h) || (!c2->im)) error(E_INTERN);
  1103. X
  1104. X  if(do_sharp) sharpit(l);
  1105. X  if(keep_ycc) return;
  1106. X
  1107. X  if(!init)
  1108. X   {init=1;
  1109. X    for(i=0;i<256;i++)
  1110. X     {  XL[i]= 5564 * i + 2048;
  1111. X       XC1[i]= 9085 * i - 1417185;
  1112. X       XC2[i]= 7461 * i - 1022138;
  1113. X      XC1g[i]= 274934 - 1762 * i;
  1114. X      XC2g[i]= 520268 - 3798 * i; 
  1115. X     }
  1116. X   }
  1117. X
  1118. X  for(y=0;y<h;y++)
  1119. X   {
  1120. X    pl =  l->im + y *  l->mwidth;
  1121. X    pc1= c1->im + y * c1->mwidth;
  1122. X    pc2= c2->im + y * c2->mwidth;
  1123. X
  1124. X    for(x=0;x<w;x++)
  1125. X     {
  1126. X      L = XL[*pl]; 
  1127. X      red  =(L + XC2[*pc2]               )>>BitShift;
  1128. X      green=(L + XC1g[*pc1] + XC2g[*pc2] )>>BitShift; 
  1129. X      blue =(L + XC1[*pc1]               )>>BitShift;
  1130. X
  1131. X      NORM(red);
  1132. X      NORM(green);
  1133. X      NORM(blue);
  1134. X
  1135. X      *(pl++ )=red; 
  1136. X      *(pc1++)=green; 
  1137. X      *(pc2++)=blue;
  1138. X     }
  1139. X   }
  1140. X }
  1141. X#undef BitShift
  1142. X
  1143. X
  1144. X
  1145. X
  1146. X
  1147. X
  1148. Xstatic void writepicture(w,h,r,g,b,t)
  1149. X  dim w,h;
  1150. X  implane *r,*g,*b;
  1151. X  enum TURNS t;
  1152. X {dim x,y;
  1153. X  register uBYTE *pr,*pg,*pb;
  1154. X#ifndef OWN_WRITE
  1155. X  pixel *pixrow;
  1156. X  register pixel* pP;
  1157. X#else
  1158. X  static uBYTE BUF[own_BUsize],*BUptr;
  1159. X  int   BUcount;
  1160. X
  1161. X#define BUinit {BUcount=0;BUptr=BUF;}
  1162. X#define BUflush {fwrite(BUF,BUcount*3,1,fout);BUinit; }
  1163. X#define BUwrite(r,g,b) {if(BUcount>=own_BUsize/3) BUflush; *BUptr++ = r ; *BUptr++ = g ; *BUptr++ = b ; BUcount++;}
  1164. X
  1165. X#endif
  1166. X
  1167. X  melde("writepicture\n");
  1168. X  if((!r) || (r->iwidth != w ) || (r->iheight != h) || (!r->im)) error(E_INTERN);
  1169. X  if((!g) || (g->iwidth != w ) || (g->iheight != h) || (!g->im)) error(E_INTERN);
  1170. X  if((!b) || (b->iwidth != w ) || (b->iheight != h) || (!b->im)) error(E_INTERN);
  1171. X
  1172. X  switch (t)
  1173. X   { case T_NONE:
  1174. X#ifndef OWN_WRITE
  1175. X              ppm_writeppminit(fout,w,h,(pixval) 255, 0);
  1176. X              pixrow = ppm_allocrow( w );
  1177. X          for(y=0;y<h;y++)
  1178. X           {
  1179. X        pr= r->im + y * r->mwidth;
  1180. X        pg= g->im + y * g->mwidth;
  1181. X        pb= b->im + y * b->mwidth;
  1182. X        
  1183. X             for(pP= pixrow,x=0;x<w;x++)
  1184. X         {
  1185. X          PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
  1186. X          pP++;  pr++;  pg++;  pb++;
  1187. X         }
  1188. X        ppm_writeppmrow( fout, pixrow, w, (pixval) 255, 0 );
  1189. X        
  1190. X           }
  1191. X          pm_close(fout);
  1192. X#else
  1193. X              fprintf(fout,PPM_Header,w,h);
  1194. X              BUinit;
  1195. X          for(y=0;y<h;y++)
  1196. X           {
  1197. X        pr= r->im + y * r->mwidth;
  1198. X        pg= g->im + y * g->mwidth;
  1199. X        pb= b->im + y * b->mwidth;
  1200. X        
  1201. X             for(x=0;x<w;x++) BUwrite(*pr++,*pg++,*pb++);        
  1202. X           }
  1203. X              BUflush;
  1204. X              if(ppmname) fclose(fout);
  1205. X#endif
  1206. X              break;
  1207. X     case T_RIGHT:
  1208. X#ifndef OWN_WRITE
  1209. X              ppm_writeppminit(fout,h,w,(pixval) 255, 0);
  1210. X              pixrow = ppm_allocrow( h );
  1211. X
  1212. X          for(y=0;y<w;y++)
  1213. X           {
  1214. X        pr= r->im + r->mwidth * ( r->iheight - 1) + y;
  1215. X        pg= g->im + g->mwidth * ( g->iheight - 1) + y;
  1216. X        pb= b->im + b->mwidth * ( b->iheight - 1) + y;
  1217. X        
  1218. X        for(pP= pixrow,x=0;x<h;x++)
  1219. X         {
  1220. X          PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
  1221. X          pP++;      pr-= r->mwidth;  pg-= g->mwidth;  pb-= b->mwidth;
  1222. X         }
  1223. X        ppm_writeppmrow( fout, pixrow, h, (pixval) 255, 0 );
  1224. X        
  1225. X           }
  1226. X          pm_close(fout);
  1227. X#else
  1228. X              fprintf(fout,PPM_Header,h,w);
  1229. X              BUinit;
  1230. X          for(y=0;y<w;y++)
  1231. X           {
  1232. X        pr= r->im + r->mwidth * ( r->iheight - 1) + y;
  1233. X        pg= g->im + g->mwidth * ( g->iheight - 1) + y;
  1234. X        pb= b->im + b->mwidth * ( b->iheight - 1) + y;
  1235. X        
  1236. X             for(x=0;x<h;x++) 
  1237. X                {BUwrite(*pr,*pg,*pb);    
  1238. X         pr-= r->mwidth;  pg-= g->mwidth;  pb-= b->mwidth;
  1239. X                }    
  1240. X           }
  1241. X              BUflush;
  1242. X              if(ppmname) fclose(fout);
  1243. X#endif
  1244. X              break;
  1245. X
  1246. X      case T_LEFT:
  1247. X#ifndef OWN_WRITE
  1248. X              ppm_writeppminit(fout,h,w,(pixval) 255, 0);
  1249. X              pixrow = ppm_allocrow( h );
  1250. X
  1251. X          for(y=0;y<w;y++)
  1252. X           {
  1253. X        pr= r->im + r->iwidth - 1 - y;
  1254. X        pg= g->im + g->iwidth - 1 - y;
  1255. X        pb= b->im + b->iwidth - 1 - y;
  1256. X        
  1257. X        
  1258. X        
  1259. X        for(pP= pixrow,x=0;x<h;x++)
  1260. X         {
  1261. X          PPM_ASSIGN(*pP,((int)*pr),((int)*pg),((int)*pb));
  1262. X          pP++;      pr+= r->mwidth;  pg+= g->mwidth;  pb+= b->mwidth;
  1263. X         }
  1264. X        ppm_writeppmrow( fout, pixrow, h, (pixval) 255, 0 );
  1265. X        
  1266. X           }
  1267. X          pm_close(fout);
  1268. X#else
  1269. X              fprintf(fout,PPM_Header,h,w);
  1270. X              BUinit;
  1271. X          for(y=0;y<w;y++)
  1272. X           {
  1273. X        pr= r->im + r->iwidth - 1 - y;
  1274. X        pg= g->im + g->iwidth - 1 - y;
  1275. X        pb= b->im + b->iwidth - 1 - y;
  1276. X        
  1277. X             for(x=0;x<h;x++) 
  1278. X                {BUwrite(*pr,*pg,*pb);    
  1279. X         pr+= r->mwidth;  pg+= g->mwidth;  pb+= b->mwidth;
  1280. X                }    
  1281. X           }
  1282. X              BUflush;
  1283. X              if(ppmname) fclose(fout);
  1284. X
  1285. X#endif
  1286. X              break;
  1287. X      default: error(E_INTERN);
  1288. X    }
  1289. X }
  1290. X
  1291. X
  1292. X
  1293. X
  1294. X
  1295. X
  1296. X
  1297. X
  1298. X
  1299. X
  1300. X
  1301. X
  1302. X
  1303. X
  1304. X
  1305. X
  1306. X
  1307. X
  1308. X
  1309. X
  1310. Xstruct ph1 
  1311. X {char  id1[8];
  1312. X  uBYTE ww1[14];
  1313. X  char  id2[20];
  1314. X  char  id3[4*16+4];
  1315. X  short ww2;
  1316. X  char  id4[20];
  1317. X  uBYTE ww3[2*16+1];
  1318. X  char  id5[4*16];
  1319. X  uBYTE idx[11*16];
  1320. X } ;
  1321. X
  1322. X
  1323. Xstatic void druckeid()
  1324. X{int i;
  1325. X struct ph1 *d;
  1326. X char ss[100];
  1327. X
  1328. X d=(struct ph1 *)sbuffer;
  1329. X
  1330. X#define dr(feld,kennung)   \
  1331. X     strncpy(ss,feld,sizeof(feld));\
  1332. X     ss[sizeof(feld)]=0;\
  1333. X     fprintf(stderr,"%s: %s \n",kennung,ss);
  1334. X
  1335. X#define db(feld) fprintf(stderr,"--%d\n",sizeof(feld)); for(i=0;i<sizeof(feld);i+=2) \
  1336. X  fprintf(stderr,"%4d %6d\n",i,(signed int)((((unsigned int)feld[i])<<8)|feld[i+1]));\
  1337. X  fprintf(stderr,"\n");
  1338. X
  1339. Xdr(d->id1,"Id1")
  1340. Xdr(d->id2,"Id2")
  1341. Xdr(d->id3,"Id3")
  1342. Xdr(d->id4,"Id4")
  1343. Xdr(d->id5,"Id5")
  1344. X
  1345. X/*
  1346. Xdb(d->ww1)
  1347. Xdb(d->ww3)
  1348. Xdb(d->idx)
  1349. X*/
  1350. X
  1351. X#undef dr 
  1352. X#undef db
  1353. X
  1354. X}
  1355. X
  1356. X
  1357. X
  1358. Xstruct pcdword
  1359. X { uBYTE high,low;
  1360. X };
  1361. X
  1362. Xstatic int lpt[1024];
  1363. X
  1364. Xstatic void readlpt(w,h)
  1365. X  dim w,h;
  1366. X {int i;
  1367. X  struct pcdword *ptr;
  1368. X
  1369. X  EREADBUF;
  1370. X
  1371. X  ptr = (struct pcdword *)sbuffer;
  1372. X
  1373. X  for(i=0;i<h/4;i++,ptr++)
  1374. X   {lpt[i] = ((int)ptr->high)<<8 | ptr->low ;
  1375. X   }
  1376. X
  1377. X
  1378. X  
  1379. X }
  1380. X
  1381. X
  1382. X
  1383. Xstruct pcdquad { uBYTE len,highseq,lowseq,key;};
  1384. Xstruct pcdhqt  { uBYTE entries; struct pcdquad entry[256];};
  1385. Xstruct myhqt { unsigned long seq,mask,len; uBYTE key; };
  1386. X
  1387. X
  1388. X#define E ((unsigned long) 1)
  1389. X
  1390. X
  1391. Xstatic void readhqtsub(source,ziel,anzahl)
  1392. X  struct pcdhqt *source;
  1393. X  struct myhqt *ziel;
  1394. X  int *anzahl;
  1395. X {int i;
  1396. X  struct pcdquad *sub;
  1397. X  struct myhqt *help;
  1398. X  *anzahl=(source->entries)+1;
  1399. X
  1400. X  for(i=0;i<*anzahl;i++)
  1401. X   {sub = (struct pcdquad *)(((uBYTE *)source)+1+i*sizeof(*sub));
  1402. X    help=ziel+i;
  1403. X
  1404. X    help->seq = (((unsigned long) sub->highseq) << 24) |(((unsigned long) sub->lowseq) << 16);
  1405. X    help->len = ((unsigned long) sub->len) +1;
  1406. X    help->key = sub->key;
  1407. X
  1408. X#ifdef DEBUGhuff
  1409. X   fprintf(stderr," Anz: %d A1: %08x  A2: %08x X:%02x %02x %02x %02x Seq:  %08x   Laenge:  %d %d\n",
  1410. X          *anzahl,sbuffer,sub,((uBYTE *)sub)[0],((uBYTE *)sub)[1],((uBYTE *)sub)[2],((uBYTE *)sub)[3],
  1411. X          help->seq,help->len,sizeof(uBYTE));
  1412. X#endif
  1413. X
  1414. X    if(help->len > 16) error(E_HUFF);
  1415. X
  1416. X    help->mask = ~ ( (E << (32-help->len)) -1); 
  1417. X
  1418. X  }
  1419. X#ifdef DEBUG
  1420. X  for(i=0;i<*anzahl;i++)
  1421. X   {help=ziel+i;
  1422. X    fprintf(stderr,"H: %3d  %08lx & %08lx (%2d) = %02x = %5d  %8x\n",
  1423. X        i, help->seq,help->mask,help->len,help->key,(signed char)help->key,
  1424. X        help->seq & (~help->mask));
  1425. X   }
  1426. X#endif
  1427. X
  1428. X}
  1429. X
  1430. X#undef E
  1431. X
  1432. Xstatic struct myhqt myhuff0[256],myhuff1[256],myhuff2[256];
  1433. Xstatic int          myhufflen0=0,myhufflen1=0,myhufflen2=0;
  1434. X
  1435. Xstatic void readhqt(w,h,n)
  1436. X  dim w,h;
  1437. X  int n;
  1438. X {
  1439. X  uBYTE *ptr;
  1440. X
  1441. X  melde("readhqt\n");
  1442. X  EREADBUF;
  1443. X  ptr = sbuffer;
  1444. X
  1445. X  readhqtsub((struct pcdhqt *)ptr,myhuff0,&myhufflen0);
  1446. X
  1447. X  if(n<2) return;
  1448. X  ptr+= 1 + 4* myhufflen0;
  1449. X  readhqtsub((struct pcdhqt *)ptr,myhuff1,&myhufflen1);
  1450. X
  1451. X  if(n<3) return;
  1452. X  ptr+= 1 + 4* myhufflen1;
  1453. X  readhqtsub((struct pcdhqt *)ptr,myhuff2,&myhufflen2);
  1454. X
  1455. X}
  1456. X
  1457. X
  1458. X
  1459. X
  1460. X
  1461. Xstatic void decode(w,h,f,f1,f2,autosync)
  1462. X  dim w,h;
  1463. X  implane *f,*f1,*f2;
  1464. X  int autosync;
  1465. X {int i,htlen,sum;
  1466. X  unsigned long sreg,maxwidth;
  1467. X  unsigned int inh,n,zeile,segment,ident;
  1468. X  struct myhqt *htptr,*hp;
  1469. X
  1470. X  uBYTE *nptr;
  1471. X  uBYTE *lptr;
  1472. X
  1473. X  melde("decode\n");
  1474. X#define nextbuf  {  nptr=sbuffer;  EREADBUF; }
  1475. X#define checkbuf { if (nptr >= sbuffer + sizeof(sbuffer)) nextbuf; }
  1476. X#define shiftout(n){ sreg<<=n; inh-=n; \
  1477. X                     while (inh<=24) \
  1478. X                      {checkbuf; \
  1479. X                       sreg |= ((unsigned long)(*(nptr++)))<<(24-inh);\
  1480. X                       inh+=8;\
  1481. X                      }\
  1482. X                    }  
  1483. X#define issync ((sreg & 0xffffff00) == 0xfffffe00) 
  1484. X#define seeksync { while (!issync) shiftout(1);}
  1485. X
  1486. X
  1487. X  if( f  && ((! f->im) || ( f->iheight < h  ) ||  (f->iwidth<w  ))) error(E_INTERN);
  1488. X  if( f1 && ((!f1->im) || (f1->iheight < h/2) || (f1->iwidth<w/2))) error(E_INTERN);
  1489. X  if( f2 && ((!f2->im) || (f2->iheight < h/2) || (f2->iwidth<w/2))) error(E_INTERN);
  1490. X
  1491. X  htlen=sreg=maxwidth=0;
  1492. X  htptr=0;
  1493. X  nextbuf;
  1494. X  inh=32;
  1495. X  lptr=0;
  1496. X  shiftout(16);
  1497. X  shiftout(16);
  1498. X
  1499. X  if(autosync) seeksync;
  1500. X
  1501. X  n=0;
  1502. X  for(;;)
  1503. X   {
  1504. X    if (issync)
  1505. X     {shiftout(24);
  1506. X      ident=sreg>>16;
  1507. X      shiftout(16);
  1508. X
  1509. X      zeile=(ident>>1) & 0x1fff;
  1510. X      segment=ident>>14;
  1511. X
  1512. X#ifdef DEBUG
  1513. X      fprintf(stderr,"Ident %4x Zeile:  %6d  Segment %3d Pixels bisher: %5d   Position: %8lx\n",
  1514. X          ident,zeile,segment,n,bufpos);
  1515. X#endif
  1516. X
  1517. X
  1518. X      if(lptr && (n!=maxwidth)) error(E_SEQ1);
  1519. X      n=0;
  1520. X
  1521. X      if(zeile==h) {RPRINT; return; }
  1522. X      if(zeile >h) error(E_SEQ2);
  1523. X
  1524. X      switch(segment)
  1525. X       {
  1526. X        case 0: if((!f) && autosync) {seeksync; break;}
  1527. X                if(!f) error(E_SEQ7);
  1528. X                lptr=f->im + zeile*f->mwidth;
  1529. X                maxwidth=f->iwidth;
  1530. X                htlen=myhufflen0;
  1531. X                htptr=myhuff0;
  1532. X                break;
  1533. X
  1534. X        case 2: if((!f1) && autosync) {seeksync; break;}
  1535. X                if(!f1) error(E_SEQ7);
  1536. X                lptr=f1->im + (zeile>>1)*f1->mwidth;
  1537. X                maxwidth=f1->iwidth;
  1538. X                htlen=myhufflen1;
  1539. X                htptr=myhuff1;
  1540. X                break;
  1541. X        case 3: if((!f2) && autosync) {seeksync; break;}
  1542. X                if(!f2) error(E_SEQ7);
  1543. X                lptr=f2->im + (zeile>>1)*f2->mwidth;
  1544. X                maxwidth=f2->iwidth;
  1545. X                htlen=myhufflen2;
  1546. X                htptr=myhuff2;
  1547. X                break;
  1548. X
  1549. X        default:error(E_SEQ3);
  1550. X    }
  1551. X     }
  1552. X    else
  1553. X     {
  1554. X/*      if((!lptr) || (n>maxwidth)) error(E_SEQ4);*/
  1555. X      if(!lptr)      error(E_SEQ6);
  1556. X      if(n>maxwidth) error(E_SEQ4);
  1557. X      for(i=0,hp=htptr;(i<htlen) && ((sreg & hp->mask)!= hp->seq); i++,hp++);
  1558. X      if(i>=htlen) error(E_SEQ5);
  1559. X
  1560. X      sum=((int)(*lptr)) + ((sBYTE)hp->key);
  1561. X      NORM(sum);
  1562. X      *(lptr++) = sum;
  1563. X
  1564. X      n++; 
  1565. X      shiftout(hp->len);
  1566. X
  1567. X     }
  1568. X
  1569. X   }
  1570. X
  1571. X
  1572. X#undef nextbuf  
  1573. X#undef checkbuf 
  1574. X#undef shiftout
  1575. X#undef issync
  1576. X#undef seeksync
  1577. X
  1578. X }
  1579. X
  1580. X
  1581. X
  1582. X
  1583. Xstatic void clear(l,n)
  1584. X  implane *l;
  1585. X  int n;
  1586. X{ dim x,y;
  1587. X  uBYTE *ptr;
  1588. X
  1589. X  ptr=l->im;
  1590. X  for (x=0;x<l->mwidth;x++)
  1591. X    for (y=0; y<l->mheight;y++)
  1592. X      *(ptr++)=n;
  1593. X}
  1594. X
  1595. X
  1596. X
  1597. X#define slen 3072
  1598. X
  1599. Xstatic void sharpit(l)
  1600. X  implane *l;
  1601. X {int x,y,h,w,mw,akk;
  1602. X  uBYTE f1[slen],f2[slen],*old,*akt,*ptr,*work,*help,*optr;
  1603. X
  1604. X  if((!l) || (!l->im)) error(E_INTERN);
  1605. X  if(l->iwidth > slen) error(E_INTERN);
  1606. X
  1607. X  old=f1; akt=f2;
  1608. X  h=l->iheight;
  1609. X  w=l->iwidth;
  1610. X  mw=l->mwidth;
  1611. X
  1612. X  for(y=1;y<h-1;y++)
  1613. X   {
  1614. X    ptr=l->im+ y*mw;
  1615. X    optr=ptr-mw;
  1616. X    work=akt;
  1617. X
  1618. X    *(work++)= *(ptr++);
  1619. X    for(x=1;x<w-1;x++)
  1620. X     {  akk = 5*((int)ptr[0])- ((int)ptr[1])  - ((int)ptr[-1]) 
  1621. X                              - ((int)ptr[mw]) - ((int)ptr[-mw]);
  1622. X        NORM(akk);
  1623. X        *(work++)=akk;
  1624. X        ptr++;
  1625. X     }
  1626. X
  1627. X    *(work++)= *(ptr++);
  1628. X
  1629. X    if(y>1) bcopy(old,optr,w);
  1630. X    help=old;old=akt;akt=help;
  1631. X     
  1632. X   }
  1633. X
  1634. X
  1635. X
  1636. X  akt=optr+mw;
  1637. X  for(x=0;x<w;x++)
  1638. X    *(akt++) = *(old++);
  1639. X }
  1640. X
  1641. X
  1642. X#undef slen
  1643. X
  1644. X
  1645. X
  1646. X
  1647. X
  1648. X
  1649. Xstatic int testbegin()
  1650. X {int i,j;
  1651. X  for(i=j=0;i<32;i++)
  1652. X    if(sbuffer[i]==0xff) j++;
  1653. X
  1654. X  return (j>30);
  1655. X  
  1656. X }
  1657. X
  1658. Xstatic long Skip4Base()
  1659. X  {long cd_offset,cd_offhelp;
  1660. X   
  1661. X   cd_offset = L_Head + L_Base16 + L_Base4 + L_Base ;
  1662. X   SEEK(cd_offset+3);          
  1663. X   EREADBUF;    
  1664. X   cd_offhelp=(((long)sbuffer[510])<<8)|sbuffer[511] + 1;
  1665. X
  1666. X   cd_offset+=cd_offhelp;
  1667. X
  1668. X   SEEK(cd_offset);
  1669. X   EREADBUF;
  1670. X   while(!testbegin())
  1671. X    {cd_offset++;
  1672. X     EREADBUF;
  1673. X    }
  1674. X   return cd_offset;
  1675. X  }
  1676. END_OF_FILE
  1677.   if test 34342 -ne `wc -c <'hpcdtoppm.c'`; then
  1678.     echo shar: \"'hpcdtoppm.c'\" unpacked with wrong size!
  1679.   fi
  1680.   # end of 'hpcdtoppm.c'
  1681. fi
  1682. if test -f 'hpcdtoppm.man' -a "${1}" != "-c" ; then 
  1683.   echo shar: Will not clobber existing file \"'hpcdtoppm.man'\"
  1684. else
  1685.   echo shar: Extracting \"'hpcdtoppm.man'\" \(3764 characters\)
  1686.   sed "s/^X//" >'hpcdtoppm.man' <<'END_OF_FILE'
  1687. X.TH hpcdtoppm 1 " 28 November 1992"
  1688. X.IX hpcdtoppm
  1689. X.SH NAME
  1690. Xhpcdtoppm v0.3 - convert a Photo-CD file into a portable pixmap
  1691. X.SH SYNOPSIS
  1692. X.B hpcdtoppm
  1693. X[options] pcd-file [ppm-file]
  1694. X.SH DESCRIPTION
  1695. XReads a Photo-CD Image file or Overview file, and outputs portable pixmap.
  1696. XImage files you can find on the Photo-CD in photo_cd/images, they are named
  1697. Xas "imgnnnn.pcd", where nnnn is a 4-digit-number. The Overview file is at
  1698. Xphoto_cd/overview.pcd . If there is no ppm-file-name given, output will be
  1699. Xprinted to stdout. hpcdtoppm stands for "Hadmut's pcdtoppm" to make it
  1700. Xdistinguishable in case someone else is building the same thing and
  1701. Xcalling it pcdtoppm.
  1702. X.IX GIF
  1703. X.SH OPTIONS
  1704. X.TP
  1705. X.B -i
  1706. XGive some information from the fileheader to stderr. It works only for 
  1707. XImage files. (It is not working correctly, just printing some strings.)
  1708. X.TP
  1709. X.B -s
  1710. XApply simple sharpness-operator on the Luma-channel.
  1711. X.TP
  1712. X.B -d
  1713. XDo not show the complete image, but only the decompressed difference.
  1714. XIt works only on the 4Base and the 16Base resolution. It does not
  1715. Xhave any deeper sense, but it was simple to implement and it shows what
  1716. Xcauses different sizes of image files.
  1717. X.TP
  1718. X.B -r
  1719. XRotate the picture clockwise for portraits.
  1720. X.TP
  1721. X.B -l
  1722. XRotate the picture counter-clockwise for portraits.
  1723. X.TP
  1724. X.B -a
  1725. XTry to find out the image orientation byself. This doesn't work
  1726. Xfor overview files yet. It is very experimental and depends on
  1727. Xone byte. Please tell me if it doesn't work.
  1728. X.TP
  1729. X.B -x
  1730. XOverskip Mode. Works on Base/16, Base/4, Base and 4Base. In Photo-CD
  1731. Ximages the luma channel is stored in full resolution, the two chroma
  1732. Xchannels are stored in half resolution only and have to be interpolated.
  1733. XIn the Overskip Mode the chroma channels of the next higher resolution are
  1734. Xtaken instead of interpolating. To see the difference, generate one ppm with
  1735. Xand one ppm without this flag. Use pnmarith to generate the difference image
  1736. Xof these two images. Call ppmhist for this difference or show it with xv
  1737. X(push the HistEq button in the color editor).
  1738. X.TP
  1739. X.B -1 | -Base/16 | -128x192
  1740. XExtract the Base/16 size picture (size 128x192 pixels). Note that you
  1741. Xcan only give one size option.
  1742. X.TP
  1743. X.B -2 | -Base/4 | -256x384
  1744. XExtract the Base/4 size picture.
  1745. X.TP
  1746. X.B -3 | -Base | -512x768
  1747. XExtract the Base size picture.
  1748. X.TP
  1749. X.B -4 | -4Base | -1024x1536
  1750. XExtract the 4Base size picture.
  1751. X.TP
  1752. X.B -5 | -16Base | -2048x3072
  1753. XExtract the 16Base size picture.
  1754. X.TP
  1755. X.B -0 | -Overview | -O
  1756. XExtract all pictures from an Overview file. A ppmfilename must be given. If the
  1757. Xgiven name is "foo", the files are named "foonnnn", where nnnn is a 4-digit number.
  1758. XSince they are stored in Base/16 format, they are extracted in this format.
  1759. X.TP
  1760. X.B -ycc
  1761. XSuppress the ycc to rgb conversion. This is experimental only.
  1762. XYou can use this and apply ppmtorgb3 on the file. Then you will
  1763. Xget three pgm-files, one Luma and two Chroma files. 
  1764. X
  1765. X.PP
  1766. X
  1767. X.SH BUGS
  1768. XI still don't have enough information about the Photo-CD to
  1769. Xtake care of all data structures. The informations i have are
  1770. Xquite vague and this program was developed by starring at the
  1771. Xhex-dumps and the famous trial-and-error-method. :-) If anything
  1772. Xdoesn't work, please send me a report and perhaps you could try to
  1773. Xfind out, why it doesn't work.
  1774. X.SH "SEE ALSO"
  1775. Xppm(5), ppmquant(1), ppmtopgm(1), ppmhist(1), pnmarith(1), ppmtorgb3(1), xv(1)
  1776. X.SH AUTHOR
  1777. XCopyright (c) 1992 by Hadmut Danisch (danisch@ira.uka.de).
  1778. XPermission to use and distribute this software and its
  1779. Xdocumentation for noncommercial use and without fee is hereby granted,
  1780. Xprovided that the above copyright notice appear in all copies and that
  1781. Xboth that copyright notice and this permission notice appear in
  1782. Xsupporting documentation. It is not allowed to sell this software in 
  1783. Xany way. This software is not public domain.
  1784. END_OF_FILE
  1785.   if test 3764 -ne `wc -c <'hpcdtoppm.man'`; then
  1786.     echo shar: \"'hpcdtoppm.man'\" unpacked with wrong size!
  1787.   fi
  1788.   # end of 'hpcdtoppm.man'
  1789. fi
  1790. if test -f 'simple_viewer' -a "${1}" != "-c" ; then 
  1791.   echo shar: Will not clobber existing file \"'simple_viewer'\"
  1792. else
  1793.   echo shar: Extracting \"'simple_viewer'\" \(181 characters\)
  1794.   sed "s/^X//" >'simple_viewer' <<'END_OF_FILE'
  1795. X#!/bin/csh -f
  1796. X# This is a simple Photo-CD viewer. You need xv.
  1797. X# Go into the image directory of the Photo-CD
  1798. X#
  1799. X#
  1800. Xforeach i (img*)
  1801. X  echo $i
  1802. X  hpcdtoppm -2 -a $i | xv -quick24 -
  1803. Xend
  1804. END_OF_FILE
  1805.   if test 181 -ne `wc -c <'simple_viewer'`; then
  1806.     echo shar: \"'simple_viewer'\" unpacked with wrong size!
  1807.   fi
  1808.   chmod +x 'simple_viewer'
  1809.   # end of 'simple_viewer'
  1810. fi
  1811. echo shar: End of archive 1 \(of 1\).
  1812. cp /dev/null ark1isdone
  1813. MISSING=""
  1814. for I in 1 ; do
  1815.     if test ! -f ark${I}isdone ; then
  1816.     MISSING="${MISSING} ${I}"
  1817.     fi
  1818. done
  1819. if test "${MISSING}" = "" ; then
  1820.     echo You have the archive.
  1821.     rm -f ark[1-9]isdone
  1822. else
  1823.     echo You still must unpack the following archives:
  1824.     echo "        " ${MISSING}
  1825. fi
  1826. exit 0
  1827. exit 0 # Just in case...
  1828.