/Pristine-Pro/PICDRIVE/PICT2/PICTBMAP.C

http://github.com/AnimatorPro/Animator-Pro · C · 912 lines · 668 code · 123 blank · 121 comment · 104 complexity · eb90c38516738c49e86f5820619826d8 MD5 · raw file

  1. /***************************************************************
  2. Pict file pdr modules:
  3. Created by Peter Kennard. Sept 29, 1991
  4. Functions to read, parse and decompress pict file pixel map
  5. data chunks and transfer the pixels to a pj screen, or to
  6. single line pixel buffers in true color mode.
  7. ****************************************************************/
  8. #include "errcodes.h"
  9. #include "pict.h"
  10. #include "picdrive.h"
  11. #include "syslib.h"
  12. void intel_swap_pixMap(pixMap *pm)
  13. /* Intel swap integer fields in an apple pixel map header. */
  14. {
  15. static USHORT pmswaps[] = {
  16. SET_OFFSET(pixMap,rowBytes),
  17. SWAP_WORDS(7),
  18. SWAP_LONGS(1),
  19. SET_OFFSET(pixMap,pixelType),
  20. SWAP_WORDS(4),
  21. SWAP_LONGS(2),
  22. SWAP_WORDS(2),
  23. END_SWAPTAB
  24. };
  25. intel_swap_struct(pm,pmswaps);
  26. }
  27. static Errcode read_pixMap(Pfile *pf, pixMap *pm)
  28. /* Read a pixMap header from the file, and make allowance for version 1 or 2
  29. * types. Convert version 1 to version 2 format. */
  30. {
  31. /* Note the baseAddr field is NOT in the file */
  32. if(pf_read(pf,&pm->PMAP_FSTART, PMAP_FSIZE) < Success)
  33. goto error;
  34. intel_swap_pixMap(pm);
  35. if(!(pm->rowBytes & 0x8000)) /* This is a BITmap */
  36. {
  37. /* Go back to end of bitMap in file and load pixMap values that
  38. * would be valid for a bitmap. */
  39. pf_seek_bytes(pf, sizeof(bitMap)-sizeof(pixMap));
  40. pm->packType = PACK_BRUN;
  41. pm->packSize = 0;
  42. pm->pixelType = 0;
  43. pm->cmpSize = 1;
  44. pm->pixelSize = 1;
  45. pm->cmpCount = 1;
  46. pm->planeBytes = 0;
  47. pm->myflags = PM_NOCTABLE;
  48. }
  49. else /* This is a pixel map. Clear sign bit */
  50. {
  51. pm->rowBytes &= ~(0x8000);
  52. pm->myflags = 0;
  53. if(pm->pixelType == 16)
  54. pm->myflags |= PM_NOCTABLE;
  55. }
  56. #ifdef PRINTSTUFF
  57. #define PRTIT(f) printf(sizeof(MEMBER(pixMap,f)) > 2?"%s %ld\n":"%s %d\n",\
  58. #f, pm->f )
  59. PRTIT( rowBytes);
  60. PRTIT(Bounds.top);
  61. PRTIT(Bounds.left);
  62. PRTIT(Bounds.right);
  63. PRTIT(Bounds.bot);
  64. PRTIT( version);
  65. PRTIT( packType);
  66. PRTIT( packSize);
  67. PRTIT( pixelType);
  68. PRTIT( pixelSize);
  69. PRTIT( cmpCount);
  70. PRTIT( cmpSize);
  71. PRTIT( planeBytes);
  72. #undef PRTIT
  73. #endif /* PRINTSTUFF */
  74. return(Success);
  75. error:
  76. return(pf->lasterr);
  77. }
  78. static Errcode read_cTable_head(Pfile *pf, colorTable *ct)
  79. /* Read header for pixel map color table from file and intel swap it. */
  80. {
  81. static USHORT ctswaps[] = {
  82. SWAP_LONGS(1),
  83. SWAP_WORDS(2),
  84. END_SWAPTAB
  85. };
  86. pf_read(pf,ct,sizeof(*ct));
  87. intel_swap_struct(ct,ctswaps);
  88. return(pf->lasterr);
  89. }
  90. static Errcode read_colorTable(Pfile *pf)
  91. /* Read a color table header from file, alloc a buffer for pf->cTable and
  92. * read in the color values from the file. */
  93. {
  94. ULONG bytesize;
  95. ctEntry *entry;
  96. colorTable ct;
  97. USHORT use_indices;
  98. int i;
  99. if(read_cTable_head(pf,&ct) < Success)
  100. goto error;
  101. bytesize = (ct.ctSize+1) * sizeof(ctEntry);
  102. freez(&pf->cTable);
  103. if((pf->cTable = malloc(bytesize + sizeof(colorTable))) == NULL)
  104. return(pf->lasterr = Err_no_memory);
  105. if(pf_read(pf,CT_ENTRIES(pf->cTable),bytesize) < Success)
  106. goto error;
  107. intel_swap_words(CT_ENTRIES(pf->cTable),bytesize>>1);
  108. *pf->cTable = ct;
  109. #ifdef PRINTSTUFF
  110. #define PRTIT(f) printf(sizeof(ct.f) > 2?"%s %ld\n":"%s %d\n",\
  111. #f, pf->cTable->f )
  112. PRTIT(id);
  113. PRTIT(ctFlags);
  114. PRTIT(ctSize);
  115. #undef PRTIT
  116. #endif /* PRINTSTUFF */
  117. /* Check table entry order and set inorder flag if it is. I would assume
  118. * these tables may not be in order or the pixel_ix field wouldn't
  119. * exist, if they are not we need to make pen ids equal indices. Some
  120. * pics I have gotten have all zeros in the index field and they display
  121. * ok if the table is assumed to be in index order so I set it here */
  122. use_indices = 0;
  123. entry = CT_ENTRIES(pf->cTable);
  124. for(i = ct.ctSize;i >= 0;--i)
  125. {
  126. use_indices |= entry->pixel_ix;
  127. ++entry;
  128. }
  129. /* Entry is at max now so we count down in loop below. */
  130. pf->flags |= PH_CTAB_INORDER; /* be optimistic */
  131. for(i = ct.ctSize;i >= 0;--i)
  132. {
  133. --entry;
  134. if(!use_indices)
  135. entry->pixel_ix = i;
  136. else
  137. {
  138. if((entry)->pixel_ix != i)
  139. pf->flags &= ~PH_CTAB_INORDER;
  140. }
  141. }
  142. return(Success);
  143. error:
  144. return(pf->lasterr);
  145. }
  146. static Errcode skip_colorTable(Pfile *pf)
  147. /* Read color table header from file and skip by the data. Used for ignored
  148. * chunks. */
  149. {
  150. colorTable ct;
  151. if(read_cTable_head(pf,&ct) >= Success)
  152. pf_seek_bytes(pf,(ct.ctSize+1) * sizeof(ctEntry));
  153. return(pf->lasterr);
  154. }
  155. static Errcode load_colorTable(Pfile *pf)
  156. /* Load previously read in Apple style color table into a pj color map. */
  157. {
  158. Cmap *cmap;
  159. Rgb3 *rgb;
  160. ctEntry *cte;
  161. int count;
  162. USHORT max_ix;
  163. cmap = pf->screen->cmap;
  164. cte = CT_ENTRIES(pf->cTable);
  165. max_ix = cmap->num_colors;
  166. /* note ctSize is one less than actual size of table */
  167. for(count = pf->cTable->ctSize;count >= 0;--count)
  168. {
  169. /* must be within range of destination */
  170. if(cte->pixel_ix < max_ix)
  171. {
  172. rgb = &cmap->ctab[cte->pixel_ix];
  173. rgb->r = (cte->r >> 8);
  174. rgb->g = (cte->g >> 8);
  175. rgb->b = (cte->b >> 8);
  176. }
  177. ++cte;
  178. }
  179. pj_cmap_load(pf->screen,cmap);
  180. return(Success);
  181. }
  182. static Errcode read_rowbytes_line(Pfile *pf,void *buf,unsigned maxsize)
  183. /* Read line of implicit rowBytes size for an unpacked line. */
  184. {
  185. return(pf_read(pf,buf,pf->pm.rowBytes));
  186. }
  187. static Errcode donothing_unpack(BYTE *packline, UBYTE *buf, int len)
  188. /* Filler function: Does nothing. */
  189. {
  190. return(Success);
  191. }
  192. /*********** bit to byte a pixel expander functions ********* /
  193. /* All are: void expand_Xbit(UBYTE *bitbuf,UBYTE *pix, UBYTE *maxpix)
  194. *
  195. * bitbuf is a buffer of X bit wide pixels, input
  196. * pix is the output buffer of byte wide pixels
  197. * maxpix it the loop controller or one beyond the last output pixel available
  198. */
  199. typedef union bitbytes {
  200. struct {
  201. UBYTE low;
  202. UBYTE hi;
  203. } b;
  204. USHORT w;
  205. } Bitbytes;
  206. static void dont_make_pixels(UBYTE *bitbuf,UBYTE *pix, UBYTE *maxpix, int bpr)
  207. /* donothing place holder function for pixel cruncher */
  208. {
  209. return;
  210. }
  211. static void expand_1bit(UBYTE *bitbuf,UBYTE *pix, UBYTE *maxpix, int bpr)
  212. /* Expand buffer of 1 bit pixels to byte a pixel buffer. */
  213. {
  214. Bitbytes bits;
  215. int count;
  216. bits.w = 0;
  217. count = 0;
  218. while(pix < maxpix)
  219. {
  220. if(--count <= 0)
  221. {
  222. count = 8;
  223. bits.b.low = *bitbuf++;
  224. }
  225. bits.w <<= 1;
  226. *pix++ = bits.b.hi & 1;
  227. }
  228. }
  229. static void expand_2bit(UBYTE *bitbuf,UBYTE *pix, UBYTE *maxpix, int bpr)
  230. /* Expand buffer of 2 bit pixels to byte a pixel buffer. */
  231. {
  232. Bitbytes bits;
  233. int count;
  234. bits.w = 0;
  235. count = 0;
  236. while(pix < maxpix)
  237. {
  238. if(--count <= 0)
  239. {
  240. count = 4;
  241. bits.b.low = *bitbuf++;
  242. }
  243. bits.w <<= 2;
  244. *pix++ = bits.b.hi & 0x3;
  245. }
  246. }
  247. static void expand_4bit(UBYTE *bitbuf,UBYTE *pix, UBYTE *maxpix, int bpr)
  248. /* Expand buffer of 4 bit pixels to byte a pixel buffer. */
  249. {
  250. UBYTE b;
  251. for(;;)
  252. {
  253. if(pix >= maxpix)
  254. break;
  255. b = *bitbuf++;
  256. *pix++ = b >> 4;
  257. if(pix >= maxpix)
  258. break;
  259. *pix++ = b & 0xF;
  260. }
  261. }
  262. static void bits16_to_Rgb3(UBYTE *bitbuf, UBYTE *pix, UBYTE *maxpix, int bpr)
  263. /* Expand 16 bit apple pixels to 24 bit r,g,b pixels */
  264. {
  265. USHORT *pix16 = (USHORT *)bitbuf;
  266. Bitbytes bits;
  267. #define RGB ((Rgb3 *)pix)
  268. /* layout of apple 16 bit pixel is 0rrrrrgggggbbbbb */
  269. while(pix < maxpix)
  270. {
  271. bits.w = *pix16++ << 1;
  272. RGB->r = (bits.b.hi & 0xF8) | ((bits.b.hi>>5) & 0x07);
  273. RGB->g = (bits.b.hi & 0x07);
  274. bits.w <<= 5;
  275. RGB->g |= (bits.b.hi & 0xF8);
  276. RGB->b = (bits.b.hi & 0x07);
  277. bits.w <<= 5;
  278. RGB->b |= (bits.b.hi & 0xF8);
  279. pix += sizeof(*RGB);
  280. }
  281. #undef RGB
  282. }
  283. static void interleave_rgbs(UBYTE *bitbuf, UBYTE *pix, UBYTE *maxpix, int bpr)
  284. /* Take 3 end to end [rrr][ggg][bbb] buffers and produce one buffer of
  285. * ordered rgb triples rgbrgbrgb. Bpr is 4x the length of the input buffer
  286. * used by each color component. The fourth color component is used as an
  287. * Alpha channel if present and is not used by the PDR. */
  288. {
  289. UBYTE *reds;
  290. UBYTE *greens;
  291. UBYTE *blues;
  292. #define RGB ((Rgb3 *)pix)
  293. /* Layout of apple 32 bit pixels as decompressed by byte run compression
  294. * is bpr/4 reds bpr/4 greens bpr/4 blues bpr/4 alphas */
  295. bpr >>= 2;
  296. reds = bitbuf;
  297. greens = reds + bpr;
  298. blues = greens + bpr;
  299. while(pix < maxpix)
  300. {
  301. RGB->r = *reds++;
  302. RGB->g = *greens++;
  303. RGB->b = *blues++;
  304. pix = OPTR(pix,sizeof(*RGB));
  305. }
  306. #undef RGB
  307. }
  308. static void copy_pixel_bytes(UBYTE *bitbuf, UBYTE *pix, UBYTE *maxpix, int bpr)
  309. /* this copies unpacked pixels just as they are */
  310. {
  311. copy_bytes(bitbuf,pix,SIZE(pix,maxpix));
  312. }
  313. /*******************************************************************/
  314. /*** transfer mode "blit" logic functions D must equal s + width !!
  315. *** and is used for the loop test. Each function will logicly merge
  316. *** string s into d putting the result in d. */
  317. static void or_pixels(UBYTE *s,UBYTE *d)
  318. {
  319. UBYTE *maxs;
  320. maxs = d;
  321. while(s < maxs)
  322. *d++ |= *s++;
  323. }
  324. static void xor_pixels(UBYTE *s,UBYTE *d)
  325. {
  326. UBYTE *maxs;
  327. maxs = d;
  328. while(s < maxs)
  329. *d++ ^= *s++;
  330. }
  331. static void andnot_pixels(UBYTE *s,UBYTE *d)
  332. {
  333. UBYTE *maxs;
  334. maxs = d;
  335. while(s < maxs)
  336. *d++ &= ~(*s++);
  337. }
  338. static void not_pixels(UBYTE *s,UBYTE *d)
  339. {
  340. UBYTE *maxs;
  341. maxs = d;
  342. while(s < maxs)
  343. *d++ = ~(*s++);
  344. }
  345. static void ornot_pixels(UBYTE *s,UBYTE *d)
  346. {
  347. UBYTE *maxs;
  348. maxs = d;
  349. while(s < maxs)
  350. *d++ |= ~(*s++);
  351. }
  352. static void xornot_pixels(UBYTE *s,UBYTE *d)
  353. {
  354. UBYTE *maxs;
  355. maxs = d;
  356. while(s < maxs)
  357. *d++ ^= ~(*s++);
  358. }
  359. static void and_pixels(UBYTE *s,UBYTE *d)
  360. {
  361. UBYTE *maxs;
  362. maxs = d;
  363. while(s < maxs)
  364. *d++ &= *s++;
  365. }
  366. static Errcode init_pixmap_transfer(Pfile *pf)
  367. /* Sets up state variables in pictfile to start pixel transfer from file
  368. * to output raster of rgb lines from a pixel map record in the file.
  369. * It sets the state to correspond to the description of the pixel data in
  370. * the previously read pixel map header. */
  371. {
  372. LONG bsize;
  373. /* get width and height of output raster from this pixel map */
  374. pf->pixwidth = pf->pm.Bounds.right - pf->pm.Bounds.left;
  375. if(pf->mode == PF_RGBLINES)
  376. pf->pixwidth *= sizeof(Rgb3);
  377. pf->pmheight = pf->pm.Bounds.bot - pf->pm.Bounds.top;
  378. /* We potentially use 3 buffers one for pixels, one for packed
  379. * bits, and one for unpacked bits. Maybe a little bigger than needed
  380. * but surely enough. Make sure it is at least 2*width for transfer
  381. * mode functionality which needs an extra buffer for compositing.
  382. * When the composite function is called, all buffer space other than
  383. * pixbuf can be overwritten and used. */
  384. bsize = (pf->pm.rowBytes*3)+128;
  385. if(bsize < pf->pixwidth)
  386. bsize += pf->pixwidth;
  387. bsize += pf->pixwidth;
  388. /* re-allocate pixel buffer if too small */
  389. if(pf->pixbuf == NULL || pf->pbsize < bsize)
  390. {
  391. freez(&pf->pixbuf);
  392. if((pf->pixbuf = malloc(bsize)) == NULL)
  393. return(pf->lasterr = Err_no_memory);
  394. pf->pbsize = bsize;
  395. }
  396. /* We use one pixwidth line of pixels for the output buffer. */
  397. pf->maxpix = OPTR(pf->pixbuf,pf->pixwidth);
  398. /* Select pixel expansion or crunching function based on pixel depth. */
  399. switch(pf->pm.pixelSize)
  400. {
  401. case 1:
  402. pf->make_pixels = expand_1bit;
  403. goto setup_bitbuf;
  404. case 2:
  405. pf->make_pixels = expand_2bit;
  406. goto setup_bitbuf;
  407. case 4:
  408. pf->make_pixels = expand_4bit;
  409. goto setup_bitbuf;
  410. case 16:
  411. pf->make_pixels = bits16_to_Rgb3;
  412. goto setup_bitbuf;
  413. case 32:
  414. {
  415. /* Note: In the unpacked case we copy the pixels. This is because
  416. * we are loading the pixels into an ouput line buffer and the
  417. * make_pixels function is used to load the pixels into the output
  418. * line. Maybe an extra copy but code is simpler in rgb_readline() */
  419. switch(pf->pm.packType)
  420. {
  421. case PACK_BRUN_CMP:
  422. pf->make_pixels = interleave_rgbs;
  423. goto setup_bitbuf;
  424. case NOPACK_ODDSIZE: /* not packed, out RGBs are the same in
  425. * this case */
  426. pf->make_pixels = copy_pixel_bytes;
  427. goto setup_bitbuf;
  428. }
  429. goto set_dont_make;
  430. }
  431. default: /* If we don't support it, just do nothing. */
  432. case 8:
  433. set_dont_make:
  434. {
  435. pf->make_pixels = dont_make_pixels;
  436. pf->bitbuf = pf->pixbuf; /* this needs no expansion so unpack
  437. * readbuf direct to pixbuf */
  438. break;
  439. }
  440. setup_bitbuf:
  441. {
  442. /* Set up a bitbuf as a separate area where decompressed bits
  443. * are put before being converted to pixels. note this is
  444. * long aligned */
  445. pf->bitbuf = OPTR(pf->maxpix,4-(pf->pixwidth & 3));
  446. break;
  447. }
  448. }
  449. /* Select read function based on ranges of bytes per row as defined
  450. * by apple docs. */
  451. if(pf->pm.rowBytes < 8) /* Data is unpacked and lines are bpr size. */
  452. {
  453. pf->read_line = read_rowbytes_line;
  454. pf->pm.packType = NOPACK; /* set to select no packing packtype */
  455. }
  456. else if(pf->pm.rowBytes <= 250)
  457. {
  458. /* imbedded size is a leading byte */
  459. pf->read_line = read_chunk8;
  460. }
  461. else
  462. {
  463. /* imbedded size is a leading short int */
  464. pf->read_line = read_chunk16;
  465. }
  466. /* Select unpacker function based on packType field. */
  467. switch(pf->pm.packType)
  468. {
  469. case PACK_BRUN: /* byte run byte a pixel compression */
  470. pf->unpack_line = brun_unpack_line;
  471. goto packed_line;
  472. case NOPACK: /* unpacked format */
  473. case NOPACK_ODDSIZE:
  474. goto unpacked_line;
  475. case PACK_CHUNKRUN: /* word run compression only for 16 bit pixels */
  476. {
  477. if(pf->pm.pixelSize != 16)
  478. goto unpacked_line;
  479. pf->unpack_line = wrun_unpack_line;
  480. goto packed_line;
  481. }
  482. case PACK_BRUN_CMP: /* Each byte size component byte run compressed */
  483. {
  484. if(pf->pm.pixelSize != 32)
  485. goto unpacked_line;
  486. if(pf->pm.cmpCount == 3)
  487. pf->unpack_line = brun_unpack_3compbytes;
  488. else
  489. pf->unpack_line = brun_unpack_line;
  490. goto packed_line;
  491. }
  492. default: /* Just make ugly screen of data. not supported */
  493. unpacked_line:
  494. pf->unpack_line = donothing_unpack; /* no compression */
  495. pf->readbuf = pf->bitbuf; /* no unpacking read to bitbuf */
  496. break;
  497. packed_line:
  498. /* Use a separate read area since we are unpacking */
  499. pf->readbuf = OPTR(pf->bitbuf,pf->pm.rowBytes);
  500. break;
  501. }
  502. /* Set maxsize safety margin for reader so it won't overrun buffer. */
  503. pf->max_read_size = pf->pbsize - SIZE(pf->pixbuf,pf->readbuf) - 2;
  504. /* Select blit logic function for transfer mode field. */
  505. switch(pf->tmode)
  506. {
  507. default:
  508. pf->tmode = 0;
  509. case 0: /* d = s NO compositing logic */
  510. break;
  511. case 1: /* d |= s */
  512. pf->composite_pixels = or_pixels;
  513. break;
  514. case 2: /* d ^= s */
  515. pf->composite_pixels = xor_pixels;
  516. break;
  517. case 3: /* d &= ~s */
  518. pf->composite_pixels = andnot_pixels;
  519. break;
  520. case 4: /* d = ~s */
  521. pf->composite_pixels = not_pixels;
  522. break;
  523. case 5: /* d |= ~s */
  524. pf->composite_pixels = ornot_pixels;
  525. break;
  526. case 6: /* d ^= ~s */
  527. pf->composite_pixels = xornot_pixels;
  528. break;
  529. case 7: /* d &= s */
  530. pf->composite_pixels = and_pixels;
  531. break;
  532. }
  533. return(Success);
  534. }
  535. static Errcode pixmap_to_screen(Pfile *pf)
  536. /* Using functions set by init_pixmap_transfer() read pixels and move
  537. * them to the screen via the transfer methods selected. */
  538. {
  539. int ret;
  540. UBYTE *dstbuf;
  541. SHORT height;
  542. Coor x,y;
  543. height = pf->pmheight;
  544. dstbuf = pf->tmode == 0 ? pf->pixbuf:pf->maxpix;
  545. y = pf->dstRect.top;
  546. x = pf->dstRect.left;
  547. /** THE getit unpackit convertit blitit loop !!! ***/
  548. while(height-- > 0)
  549. {
  550. if(pf->read_line(pf,pf->readbuf,pf->max_read_size) < 0)
  551. goto error;
  552. if((ret = pf->unpack_line(pf->readbuf,pf->bitbuf,
  553. pf->pm.rowBytes)) < Success)
  554. {
  555. goto reterr;
  556. }
  557. pf->make_pixels(pf->bitbuf,pf->pixbuf,pf->maxpix,pf->pm.rowBytes);
  558. if(pf->tmode)
  559. {
  560. /* note dstbuf and maxpix are and must be the same! */
  561. /* get source */
  562. pj_get_hseg(pf->screen,pf->maxpix,x,y,pf->pixwidth);
  563. pf->composite_pixels(pf->pixbuf,pf->maxpix);
  564. }
  565. pj_put_hseg(pf->screen,dstbuf,x,y,pf->pixwidth);
  566. ++y;
  567. }
  568. return(Success);
  569. reterr:
  570. pf->lasterr = ret;
  571. error:
  572. return(pf->lasterr);
  573. }
  574. static Errcode skip_bitsrect(Pfile *pf,pixMap *pm)
  575. /* Seek by pixel data for an ignored pixMap. */
  576. {
  577. SHORT height;
  578. Errcode (*skipit)(Pfile *);
  579. /* Get width and height of pixel map. */
  580. height = pf->pm.Bounds.bot - pf->pm.Bounds.top;
  581. if(pf->pm.rowBytes < 8) /* data is unpacked and lines are bpr size */
  582. return(pf_seek_bytes(pf, height*pm->rowBytes));
  583. /* Data is in embedded size chunks */
  584. if(pf->pm.rowBytes <= 250)
  585. skipit = skip_chunk8;
  586. else
  587. skipit = skip_chunk16;
  588. while(height-- > 0)
  589. {
  590. if(skipit(pf) < Success)
  591. break;
  592. }
  593. return(pf->lasterr);
  594. }
  595. Errcode do_pixmap(Pfile *pf)
  596. /* Read in a pixel map record from the file and either get info,
  597. * transfer to screen, or prepare to read the first RGB line depending
  598. * on the pf->mode. */
  599. {
  600. pf->got_bitmap = TRUE;
  601. if(read_pixMap(pf,&pf->pm) < Success)
  602. goto error;
  603. if(pf->mode == PF_SCANINFO)
  604. {
  605. /* Set offset to first pixel map if we are in an RGB true color file. */
  606. if((pf->ainfo.depth = pf->pm.pixelSize) > 8)
  607. {
  608. if((pf->first_pmap_oset = ftell(pf->file)) < 0)
  609. return(pf->lasterr = pj_errno_errcode());
  610. pf->first_pmap_oset -= PMAP_FSIZE; /* we already read it */
  611. }
  612. return(pf->lasterr = RET_ENDSCAN);
  613. }
  614. else if(pf->mode == PF_FULLFRAME)
  615. {
  616. /* Ignore true color data for full frame mode. */
  617. if((pf->ainfo.depth = pf->pm.pixelSize) > 8)
  618. return(skip_pmap_data(pf,&pf->pm));
  619. }
  620. /* If there is one, read the color map and load it into the screen. */
  621. if(!(pf->pm.myflags & PM_NOCTABLE))
  622. {
  623. if(read_colorTable(pf) < Success)
  624. goto error;
  625. if(pf->mode == PF_FULLFRAME)
  626. load_colorTable(pf);
  627. }
  628. /* Read in relative positioning rectangles. */
  629. if(read_pRect(pf,&pf->srcRect) < Success)
  630. goto error;
  631. if(read_pRect(pf,&pf->dstRect) < Success)
  632. goto error;
  633. /* Set destination rect as relative to picture frame. */
  634. set_rect_relto(&pf->dstRect, &pf->frame);
  635. /* Read transfer mode field. */
  636. if(read_short(pf,&pf->tmode) < Success)
  637. goto error;
  638. #ifdef PRINTSTUFF
  639. printf("srect t %d l %d b %d r %d\n"
  640. "drect t %d l %d b %d r %d\n"
  641. "tmode %d\n",
  642. pf->srcRect.top,
  643. pf->srcRect.left,
  644. pf->srcRect.bot,
  645. pf->srcRect.right,
  646. pf->dstRect.top,
  647. pf->dstRect.left,
  648. pf->dstRect.bot,
  649. pf->dstRect.right,
  650. pf->tmode );
  651. #endif /* PRINTSTUFF */
  652. if(pf->op & 1) /* ops 0x90 and 0x98 and 0x9a have no clipping region
  653. * ops 0x91 and 0x99 and 0x9b do */
  654. {
  655. skip_region(pf); /* we don't use these now */
  656. }
  657. /* Set up state environment for pixel transfer. */
  658. if(init_pixmap_transfer(pf) < Success)
  659. goto error;
  660. /* If we are doing full screens transfer the whole pixMap to the screen */
  661. if(pf->mode == PF_FULLFRAME)
  662. {
  663. if(pf->pm.pixelSize > 8)
  664. return(pf->lasterr = Err_unimpl);
  665. return(pixmap_to_screen(pf));
  666. }
  667. /* else, We are doing RGB lines and just initalized the next pixMap. */
  668. return(pf->lasterr = RET_PMAPSTART);
  669. error:
  670. return(pf->lasterr);
  671. }
  672. static Errcode skip_pmap_data(Pfile *pf, pixMap *pm)
  673. /* Seek by all data for an ignored pixMap */
  674. {
  675. if(!(pm->myflags & PM_NOCTABLE))
  676. {
  677. if(skip_colorTable(pf) < Success)
  678. goto error;
  679. }
  680. skip_bitsrect(pf,pm);
  681. error:
  682. return(pf->lasterr);
  683. }
  684. Errcode skip_pattern(Pfile *pf)
  685. /* Seek over and ignore a fill patern description. */
  686. {
  687. SHORT patType;
  688. pixMap pm;
  689. if(read_short(pf,&patType) < Success)
  690. goto error;
  691. #ifdef PRINTSTUFF
  692. printf("pat%d ", patType );
  693. #endif /* PRINTSTUFF */
  694. pf_seek_bytes(pf,8); /* skip over pattern words */
  695. switch(patType)
  696. {
  697. case 1:
  698. {
  699. if(read_pixMap(pf,&pm) < Success)
  700. goto error;
  701. skip_pmap_data(pf,&pm);
  702. break;
  703. }
  704. case 2: /* dither pattern */
  705. pf_seek_bytes(pf,sizeof(RGBColor));
  706. break;
  707. default:
  708. pf->lasterr = Err_format;
  709. break;
  710. }
  711. error:
  712. return(pf->lasterr);
  713. }
  714. Errcode do_truecolor(Pfile *pf)
  715. /* Read the pixel map header info and prepare to read the next RGB line
  716. * from that pixMap or return info if scanning. */
  717. {
  718. /* Seek past a dummy size of 0 and an end of file opcode */
  719. if(pf_seek_bytes(pf,4) < Success)
  720. goto error;
  721. #ifdef PRINTSTUFF
  722. printf("True color!!\n");
  723. #endif
  724. do_pixmap(pf);
  725. error:
  726. return(pf->lasterr);
  727. }
  728. Errcode pict_rgb_readline(Pfile *pf, Rgb3 *linebuf)
  729. /* Read next available RGB line in the file. */
  730. {
  731. int ret;
  732. ++pf->last_rgbline; /* next please */
  733. #ifdef PRINTSTUFF
  734. printf("readline %d", pf->last_rgbline );
  735. #endif
  736. for(;;)
  737. {
  738. if(pf->lasterr < Success)
  739. return(pf->lasterr);
  740. if(pf->lasterr == RET_EOPIC) /* Alas, no more pixels. */
  741. goto stuff_white;
  742. if(pf->last_rgbline >= pf->ainfo.height) /* bigger than pic size ! */
  743. return(Err_eof);
  744. if(pf->last_rgbline < pf->dstRect.top) /* gap in pixel maps! */
  745. goto stuff_white;
  746. /* Scan through opcodes to next pixMap record or to EOPIC if
  747. * the line we want is beyond the last one in the current pixMap. */
  748. if(pf->last_rgbline >= pf->dstRect.bot)
  749. do_pictops(pf);
  750. else
  751. break;
  752. }
  753. /* Read compressed line of pixels. */
  754. if(pf->read_line(pf,pf->readbuf,pf->max_read_size) < 0)
  755. goto error;
  756. /* Clip if somehow outside of line. */
  757. if(((USHORT)pf->dstRect.left) >= pf->ainfo.width)
  758. goto stuff_white;
  759. /* Unpack line of pixels. */
  760. if((ret = pf->unpack_line(pf->readbuf,pf->bitbuf,
  761. pf->pm.rowBytes)) < Success)
  762. {
  763. pf->lasterr = ret;
  764. goto error;
  765. }
  766. if(pf->dstRect.left > 0 || pf->dstRect.right > pf->ainfo.width)
  767. {
  768. /* If we are somehow offset from output line put in what we got
  769. * and leave the rest white. This is really an error. */
  770. stuff_bytes(0xFF,linebuf,pf->pixwidth);
  771. pf->make_pixels(pf->bitbuf,pf->pixbuf,pf->maxpix,pf->pm.rowBytes);
  772. copy_bytes( pf->pixbuf, linebuf + pf->dstRect.left,
  773. (pf->ainfo.width - pf->dstRect.left)*sizeof(Rgb3) );
  774. }
  775. else
  776. pf->make_pixels(pf->bitbuf,(UBYTE *)linebuf,
  777. OPTR(linebuf,pf->pixwidth),pf->pm.rowBytes);
  778. /* We did this one ok, next line please. */
  779. ++pf->dstRect.top;
  780. return(Success);
  781. stuff_white:
  782. stuff_bytes(0xFF,linebuf,pf->pixwidth);
  783. return(Success);
  784. error:
  785. printf("error");
  786. return(pf->lasterr);
  787. }