PageRenderTime 71ms CodeModel.GetById 24ms RepoModel.GetById 2ms app.codeStats 0ms

/Pristine-Pro/PICDRIVE/SEQ/SEQ.C

http://github.com/AnimatorPro/Animator-Pro
C | 495 lines | 366 code | 50 blank | 79 comment | 69 complexity | 369a4a25fbff96771ec363e2c021633c MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /* seq.c - source code to the Atari ST Cyber Paint .SEQ format
  2. * driver */
  3. #define REXLIB_INTERNALS
  4. #include "errcodes.h"
  5. #include "stdtypes.h"
  6. #include "stdio.h"
  7. #include "picdrive.h"
  8. #include "syslib.h"
  9. #include "seq.h"
  10. Boolean suffix_in(char *string, char *suff);
  11. void blit_box(int w, int h, int sx, int sy, unsigned char *s, int sbpr,
  12. int dx, int dy, unsigned char *d, int dbpr);
  13. void xor_blit_box(int w, int h, int sx, int sy, unsigned char *s, int sbpr,
  14. int dx, int dy, unsigned char *d, int dbpr);
  15. Errcode conv_bitmaps(UBYTE *planes[], int pcount,
  16. int bpr, int width, int height, Rcel *screen);
  17. #define ISUFFI ".SEQ"
  18. typedef struct ifile {
  19. /** This structure starts with and Image_file, and has further data
  20. ** local to the PDR.
  21. **/
  22. Image_file hdr;
  23. FILE *file;
  24. Seq_header seq;
  25. UBYTE stscreen[32000]; /* emulate an ST screen here */
  26. } Ifile;
  27. #define copy_bytes(source,dest,count) memcpy(dest,source,count)
  28. #define clear_mem(dest,count) memset(dest,0,count)
  29. #define clear_struct(s) clear_mem(s, sizeof(s))
  30. /* fixed width/height of a SEQ animation */
  31. #define STW 320
  32. #define STH 200
  33. static void intel_swaps(void *p, int length)
  34. /*****************************************************************************
  35. * Convert an array of 16 bit quantitys between 68000 and intel format.
  36. ****************************************************************************/
  37. {
  38. register char *x = p;
  39. char swap;
  40. while (--length >= 0)
  41. {
  42. swap = x[0];
  43. x[0] = x[1];
  44. x[1] = swap;
  45. x += 2;
  46. }
  47. }
  48. intel_swap(void *pt)
  49. /*****************************************************************************
  50. * Convert a 16 bit quantity between 68000 and intel format.
  51. ****************************************************************************/
  52. {
  53. #define x ((char *)pt)
  54. char swap;
  55. swap = x[0];
  56. x[0] = x[1];
  57. x[1] = swap;
  58. #undef x
  59. }
  60. long_intel_swap(void *pt)
  61. /*****************************************************************************
  62. * Convert a 32 bit quantity between 68000 and intel format.
  63. ****************************************************************************/
  64. {
  65. #define x ((SHORT *)pt)
  66. SHORT swap;
  67. swap = x[0];
  68. x[0] = x[1];
  69. x[1] = swap;
  70. intel_swap((char *)x);
  71. intel_swap((char *)(x+1));
  72. #undef x
  73. }
  74. static Boolean spec_best_fit(Anim_info *ainfo)
  75. /*****************************************************************************
  76. * Tell host that we can only write 8 bit-a-pixel images,
  77. * fixed width/height.
  78. ****************************************************************************/
  79. {
  80. Boolean nofit;
  81. nofit = (ainfo->depth == 8
  82. && ainfo->width == STW
  83. && ainfo->height == STH);
  84. ainfo->depth = 8;
  85. ainfo->width = STW;
  86. ainfo->height = STH;
  87. return(nofit); /* return whether fit was exact */
  88. }
  89. static Errcode open_file(Pdr *pd, char *path, Image_file **pif,
  90. Anim_info *ainfo )
  91. /*****************************************************************************
  92. * Open up the file, and if possible verify header.
  93. ****************************************************************************/
  94. {
  95. Ifile *gf;
  96. FILE *f;
  97. Errcode err = Success;
  98. *pif = NULL; /* for better error recovery */
  99. if (!suffix_in(path, ISUFFI))
  100. return(Err_suffix);
  101. if((gf = zalloc(sizeof(*gf))) == NULL)
  102. return(Err_no_memory);
  103. if((f = gf->file = fopen(path, "rb")) == NULL)
  104. {
  105. err = pj_errno_errcode();
  106. goto ERROR;
  107. }
  108. if (fread(&gf->seq, sizeof(gf->seq), 1, f) != 1)
  109. {
  110. err = Err_truncated;
  111. goto ERROR;
  112. }
  113. intel_swap(&gf->seq.magic);
  114. intel_swap(&gf->seq.version);
  115. long_intel_swap(&gf->seq.cel_count);
  116. intel_swap(&gf->seq.speed);
  117. if (gf->seq.magic != CYBER_MAGIC && gf->seq.magic != FLICKER_MAGIC)
  118. {
  119. err = Err_bad_magic;
  120. goto ERROR;
  121. }
  122. if (gf->seq.version != 0 || gf->seq.resolution != 0)
  123. {
  124. err = Err_version;
  125. goto ERROR;
  126. }
  127. if (ainfo != NULL) /* fill in ainfo structure if any */
  128. {
  129. clear_struct(ainfo);
  130. ainfo->depth = 8;
  131. ainfo->width = STW;
  132. ainfo->height = STH;
  133. ainfo->num_frames = gf->seq.cel_count;
  134. ainfo->millisec_per_frame = 10*gf->seq.speed/60;
  135. }
  136. *pif = (Image_file *)gf;
  137. return(Success);
  138. ERROR:
  139. close_file(&gf);
  140. return(err);
  141. }
  142. static close_file(Ifile **pgf)
  143. /*****************************************************************************
  144. * Clean up resources used by picture driver in loading (saving) a file.
  145. ****************************************************************************/
  146. {
  147. Ifile *gf;
  148. if(pgf == NULL || (gf = *pgf) == NULL)
  149. return;
  150. if(gf->file)
  151. fclose(gf->file);
  152. free(gf);
  153. *pgf = NULL;
  154. }
  155. conv_st_cmap(USHORT *st_cmap, UBYTE *pj_ctab)
  156. {
  157. int i;
  158. USHORT cm;
  159. for (i=0; i<16; i++)
  160. {
  161. cm = *st_cmap++;
  162. *pj_ctab++ = ((cm&0x700)>>3);
  163. *pj_ctab++ = ((cm&0x070)<<1);
  164. *pj_ctab++ = ((cm&0x007)<<5);
  165. }
  166. }
  167. word_uncompress(SHORT *s, SHORT *d, int length)
  168. /*****************************************************************************
  169. * Do word run-length decompression. Note length is count in words, not
  170. * bytes.
  171. ****************************************************************************/
  172. {
  173. SHORT run_length;
  174. SHORT run_data;
  175. for (;;)
  176. {
  177. if (length <= 0) /* check to see if out of data yet */
  178. break;
  179. run_length = *s++;
  180. length -= 1; /* used up 1 SHORT of source */
  181. if (run_length & 0x8000) /* see if it's a compressed run or a literal */
  182. {
  183. run_length &= 0x7fff; /* knock of the hi bit */
  184. length -= run_length; /* used up lots more of source */
  185. while (--run_length >= 0) /* go through loop run_length times */
  186. *d++ = *s++;
  187. }
  188. else /* yeah, it's compressed a little */
  189. {
  190. run_data = *s++;
  191. length -= 1; /* used another SHORT of source */
  192. while (--run_length >= 0)
  193. *d++ = run_data;
  194. }
  195. }
  196. }
  197. columns_to_bitplanes(SHORT *s,SHORT *d,int wpl,int height)
  198. /*****************************************************************************
  199. * Convert from column oriented bitplane to row oriented bitplane.
  200. * (In a compressed seq file, after word-decompression the result
  201. * is such that the next word contains the 16 pixels underneath
  202. * the first word, not the 16 to the right.)
  203. ****************************************************************************/
  204. {
  205. int i, j, k;
  206. SHORT *sp, *dp;
  207. SHORT *sl, *dl;
  208. unsigned plane_size;
  209. plane_size = wpl*height;
  210. /* step through planes */
  211. for (i = 0; i< 4; i++)
  212. {
  213. sp = s;
  214. dp = d;
  215. /* step through lines */
  216. for (j=0; j<height; j++)
  217. {
  218. sl = sp;
  219. dl = dp;
  220. /* step through words */
  221. for (k=0; k<wpl; k++)
  222. {
  223. *dl = *sl;
  224. dl += 1;
  225. sl += height;
  226. }
  227. sp += 1;
  228. dp += wpl;
  229. }
  230. d += plane_size;
  231. s += plane_size;
  232. }
  233. }
  234. de_interleave(SHORT *s,SHORT *d,int wpl,int height)
  235. /*****************************************************************************
  236. * Convert from word-interleaved bitplanes (like ST screen) to normal
  237. * bitplanes.
  238. ****************************************************************************/
  239. {
  240. int i, j, k;
  241. SHORT *sp, *dp;
  242. SHORT *sl, *dl;
  243. unsigned plane_size;
  244. plane_size = wpl*height;
  245. /* step through planes */
  246. for (i = 0; i< 4; i++)
  247. {
  248. sp = s;
  249. dp = d;
  250. /* step through lines */
  251. for (j=0; j<height; j++)
  252. {
  253. sl = sp;
  254. dl = dp;
  255. /* step through words */
  256. for (k=0; k<wpl; k++)
  257. {
  258. *dl = *sl;
  259. sl += 4;
  260. dl += 1;
  261. }
  262. sp += 4*wpl;
  263. dp += wpl;
  264. }
  265. s += 1;
  266. d += plane_size;
  267. }
  268. }
  269. static Errcode read_next(Image_file *ifile,Rcel *screen)
  270. /*****************************************************************************
  271. * Read in subsequent frames of image.
  272. ****************************************************************************/
  273. {
  274. Ifile *gf = (Ifile *)ifile; /* There's a bit of data past ifile header */
  275. FILE *f = gf->file;
  276. Errcode err = Success;
  277. Neo_head neo;
  278. int sbpr;
  279. unsigned plane_size;
  280. unsigned buf_size;
  281. SHORT *buf1 = NULL, *buf2 = NULL;
  282. unsigned bsize;
  283. UBYTE *planes;
  284. UBYTE *stscreen = gf->stscreen;
  285. int i;
  286. UBYTE *stplanes[4];
  287. /** read in frame header, swap around the fields that
  288. ** need it from Intel to Motorola format, and then
  289. ** verify that the header is as it should be.
  290. **/
  291. if (fread(&neo, sizeof(neo), 1, f) != 1)
  292. {
  293. err = Err_truncated;
  294. goto ERROR;
  295. }
  296. intel_swap(&neo.type);
  297. intel_swap(&neo.resolution);
  298. intel_swaps(neo.colormap, 16);
  299. intel_swap(&neo.xoff);
  300. intel_swap(&neo.yoff);
  301. intel_swap(&neo.width);
  302. intel_swap(&neo.height);
  303. long_intel_swap(&neo.data_size);
  304. sbpr = seq_Mask_line(neo.width);
  305. plane_size = sbpr*neo.height;
  306. buf_size = plane_size*4; /* 4 bitplanes in ST display */
  307. if (neo.type != -1)
  308. {
  309. err = Err_bad_record;
  310. goto ERROR;
  311. }
  312. if (neo.compress == NEO_UNCOMPRESSED)
  313. {
  314. neo.data_size = buf_size;
  315. }
  316. /** Set the color map
  317. **/
  318. conv_st_cmap(neo.colormap, (UBYTE *)(screen->cmap->ctab));
  319. pj_cmap_load(screen,screen->cmap);
  320. /** Check for zero length data.
  321. ** Special (easy) case
  322. **/
  323. if (neo.data_size == 0)
  324. {
  325. /* if it's an xor don't have to do anything at all, cool breeze! */
  326. /* (otherwise it means clear the screen */
  327. if (neo.op != NEO_XOR)
  328. clear_mem(stscreen, 32000);
  329. goto CONV_SCREEN;
  330. }
  331. if (neo.data_size > 32000) /* sanity check on data size */
  332. {
  333. err = Err_format;
  334. goto ERROR;
  335. }
  336. /** Allocate the buffers...
  337. **/
  338. if ((buf1 = malloc(buf_size)) == NULL)
  339. {
  340. err = Err_no_memory;
  341. goto ERROR;
  342. }
  343. if ((buf2 = malloc(buf_size)) == NULL)
  344. {
  345. err = Err_no_memory;
  346. goto ERROR;
  347. }
  348. /** Read in the possibly compressed and
  349. ** generally in ST format data
  350. **/
  351. if (fread(buf1, neo.data_size, 1, f) != 1)
  352. {
  353. err = Err_truncated;
  354. goto ERROR;
  355. }
  356. /** Here we decompress data and convert it to
  357. ** a bit-plane oriented cel. planes points
  358. ** to the beginning of the pixel data for this
  359. ** cel.
  360. **/
  361. if (neo.compress == NEO_CCOLUMNS)
  362. {
  363. bsize = neo.data_size>>1;
  364. intel_swaps(buf1,bsize); /* swap so counts are right */
  365. word_uncompress(buf1, buf2, bsize);
  366. intel_swaps(buf2,plane_size*2); /* swap back so image right */
  367. columns_to_bitplanes(buf2,buf1,sbpr>>1,neo.height);
  368. planes = (UBYTE *)buf1;
  369. }
  370. else
  371. {
  372. de_interleave(buf1,buf2,sbpr>>1,neo.height);
  373. planes = (UBYTE *)buf2;
  374. }
  375. /** Now we blit the cel onto the ST screen, doing
  376. ** either a move-blit or an xor-blit.
  377. **/
  378. if (neo.op == NEO_XOR)
  379. {
  380. for (i=0; i<4; ++i)
  381. {
  382. xor_blit_box(neo.width, neo.height, 0, 0, planes, sbpr,
  383. neo.xoff, neo.yoff, stscreen+8000*i, 40);
  384. planes += plane_size;
  385. }
  386. }
  387. else
  388. {
  389. clear_mem(stscreen, 32000);
  390. for (i=0; i<4; ++i)
  391. {
  392. blit_box(neo.width, neo.height, 0, 0, planes, sbpr,
  393. neo.xoff, neo.yoff, stscreen+8000*i, 40);
  394. planes += plane_size;
  395. }
  396. }
  397. /** Now convert stscreen to byte-a-pixel
  398. **/
  399. CONV_SCREEN:
  400. for (i=0; i<4; ++i)
  401. {
  402. stplanes[i] = stscreen;
  403. stscreen += 8000;
  404. }
  405. err = conv_bitmaps(stplanes, 4, 40, 320, 200, screen);
  406. ERROR:
  407. if (buf1 != NULL)
  408. free(buf1);
  409. if (buf2 != NULL)
  410. free(buf2);
  411. return(err);
  412. }
  413. static Errcode read_first(Image_file *ifile, Rcel *screen)
  414. /*****************************************************************************
  415. * Seek to the beginning of an open file, and then read in the
  416. * first frame of image into screen.
  417. ****************************************************************************/
  418. {
  419. Ifile *gf = (Ifile *)ifile; /* There's a bit of data past ifile header */
  420. Errcode err;
  421. /* skip past header & offset list */
  422. if ((err = fseek(gf->file,
  423. gf->seq.cel_count * sizeof(long) + sizeof(Seq_header),
  424. SEEK_SET)) < Success)
  425. return(err);
  426. return(read_next(ifile, screen));
  427. }
  428. Hostlib _a_a_stdiolib = { NULL, AA_STDIOLIB, AA_STDIOLIB_VERSION };
  429. Hostlib _a_a_gfxlib = { &_a_a_stdiolib, AA_GFXLIB, AA_GFXLIB_VERSION };
  430. Hostlib _a_a_syslib = { &_a_a_gfxlib, AA_SYSLIB, AA_SYSLIB_VERSION };
  431. static char title_info[] = "Atari ST Cyber SEQ format.";
  432. Pdr rexlib_header = {
  433. { REX_PICDRIVER, PDR_VERSION, NOFUNC, NOFUNC, &_a_a_syslib },
  434. title_info, /* title_info */
  435. "", /* long_info */
  436. ISUFFI, /* default_suffi */
  437. 0,4000, /* max_write_frames, max_read_frames */
  438. spec_best_fit, /* (*spec_best_fit)() */
  439. NOFUNC, /* (*create_image_file)() */
  440. open_file, /* (*open_image_file)() */
  441. close_file, /* (*close_image_file)() */
  442. read_first, /* (*read_first_frame)() */
  443. read_next, /* (*read_delta_next)() */
  444. NOFUNC, /* (*save_frames)() */
  445. };