home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / utilities / utilsf / jpegv6 / c / rdsprite < prev    next >
Encoding:
Text File  |  1995-10-10  |  8.8 KB  |  331 lines

  1. /*
  2.  * rdsprite.c
  3.  * © Dave Thomas, Tue 10th October 1995
  4.  *
  5.  * This file contains routines to read RISC OS Sprite images.
  6.  */
  7.  
  8. #include "cdjpeg.h"        /* Common decls for cjpeg/djpeg applications */
  9. #include "DeskLib:h.KernelSWIs"    /* swi i/f */
  10.  
  11. #ifdef SPRITE_SUPPORTED
  12.  
  13.  
  14. /* Macros to deal with unsigned chars as efficiently as compiler allows */
  15.  
  16. #ifdef HAVE_UNSIGNED_CHAR
  17. typedef unsigned char U_CHAR;
  18. #define UCH(x)    ((int) (x))
  19. #else /* !HAVE_UNSIGNED_CHAR */
  20. #ifdef CHAR_IS_UNSIGNED
  21. typedef char U_CHAR;
  22. #define UCH(x)    ((int) (x))
  23. #else
  24. typedef char U_CHAR;
  25. #define UCH(x)    ((int) (x) & 0xFF)
  26. #endif
  27. #endif /* HAVE_UNSIGNED_CHAR */
  28.  
  29.  
  30. #define    ReadOK(file,buffer,len)    (JFREAD(file,buffer,len) == ((size_t) (len)))
  31.  
  32.  
  33. /* Private version of data source object */
  34.  
  35. typedef struct _sprite_source_struct * sprite_source_ptr;
  36.  
  37. typedef struct _sprite_source_struct {
  38.   struct cjpeg_source_struct pub; /* public fields */
  39.  
  40.   j_compress_ptr cinfo;        /* back link saves passing separate parm */
  41.  
  42.   JSAMPARRAY colormap;        /* Sprite colourmap (converted to my format) */
  43.  
  44.   jvirt_sarray_ptr whole_image;    /* Needed to convert 32bpp images down */
  45.   JDIMENSION source_row;    /* Current source row number */
  46.   JDIMENSION row_width;        /* Physical width of scanlines in file */
  47.  
  48.   int bits_per_pixel;        /* remembers 8- or 24-bit format */
  49. } sprite_source_struct;
  50.  
  51.  
  52. LOCAL int
  53. read_byte (sprite_source_ptr sinfo)
  54. /* Read next byte from sprite file */
  55. {
  56.   register FILE *infile = sinfo->pub.input_file;
  57.   register int c;
  58.  
  59.   if ((c = getc(infile)) == EOF)
  60.     ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
  61.   return c;
  62. }
  63.  
  64.  
  65. LOCAL void
  66. read_colormap (sprite_source_ptr sinfo, int cmaplen, int mapentrysize)
  67. /* Read the colourmap from a sprite file */
  68. {
  69.   int i;
  70.  
  71.   if (mapentrysize != 4)
  72.     ERREXIT(sinfo->cinfo, JERR_SPRITE_BADCMP);
  73.  
  74.   /* &BbGgRrAa,&BbGgRrAa format (flash on, flash off) */
  75.   for (i = 0; i < cmaplen; i++) {
  76.     (void) read_byte(sinfo);
  77.     sinfo->colormap[0][i] = (JSAMPLE) read_byte(sinfo);
  78.     sinfo->colormap[1][i] = (JSAMPLE) read_byte(sinfo);
  79.     sinfo->colormap[2][i] = (JSAMPLE) read_byte(sinfo);
  80.     (void) read_byte(sinfo);
  81.     (void) read_byte(sinfo);
  82.     (void) read_byte(sinfo);
  83.     (void) read_byte(sinfo);
  84.   }
  85.   break;
  86. }
  87.  
  88.  
  89. /*
  90.  * Read one row of pixels.
  91.  * The image has been read into the whole_image array, but is otherwise
  92.  * unprocessed.  We must read it out in top-to-bottom row order, and if
  93.  * it is an 8-bit image, we must expand colormapped pixels to 24bit format.
  94.  */
  95.  
  96. METHODDEF JDIMENSION
  97. get_8bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
  98. /* This version is for reading 8-bit colormap indexes */
  99. {
  100.   sprite_source_ptr source = (sprite_source_ptr) sinfo;
  101.   register JSAMPARRAY colormap = source->colormap;
  102.   JSAMPARRAY image_ptr;
  103.   register int p;
  104.   register JSAMPROW inptr, outptr;
  105.   register JDIMENSION col;
  106.  
  107.   /* Expand the colormap indexes to real data */
  108.   inptr = image_ptr[0];
  109.   outptr = source->pub.buffer[0];
  110.   for (col = cinfo->image_width; col > 0; col--) {
  111.     p = GETJSAMPLE(*inptr++);
  112.     *outptr++ = colormap[0][p];
  113.     *outptr++ = colormap[1][p];
  114.     *outptr++ = colormap[2][p];
  115.   }
  116.  
  117.   return 1;
  118. }
  119.  
  120.  
  121. METHODDEF JDIMENSION
  122. get_16bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
  123. {
  124. }
  125.  
  126. METHODDEF JDIMENSION
  127. get_32bit_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
  128. {
  129.   sprite_source_ptr source = (sprite_source_ptr) sinfo;
  130.   JSAMPARRAY image_ptr;
  131.   register JSAMPROW inptr, outptr;
  132.   register JDIMENSION col;
  133.  
  134.   /* Fetch next row from virtual array */
  135.   source->source_row--;
  136.   image_ptr = (*cinfo->mem->access_virt_sarray)
  137.     ((j_common_ptr) cinfo, source->whole_image,
  138.      source->source_row, (JDIMENSION) 1, FALSE);
  139.  
  140.   inptr = image_ptr[0];
  141.   outptr = source->pub.buffer[0];
  142.   for (col = cinfo->image_width; col > 0; col--) {
  143.     (void) = *inptr++;
  144.     outptr[0] = *inptr++;
  145.     outptr[1] = *inptr++;
  146.     outptr[2] = *inptr++;
  147.     outptr += 3;
  148.   }
  149.  
  150.   return 1;
  151. }
  152.  
  153.  
  154. /*
  155.  * This method loads the image into whole_image during the first call on
  156.  * get_pixel_rows.  The get_pixel_rows pointer is then adjusted to call
  157.  * get_8bit_row or get_24bit_row on subsequent calls.
  158.  */
  159.  
  160. METHODDEF JDIMENSION
  161. preload_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
  162. {
  163.   sprite_source_ptr source = (sprite_source_ptr) sinfo;
  164.   register FILE *infile = source->pub.input_file;
  165.   register int c;
  166.   register JSAMPROW out_ptr;
  167.   JSAMPARRAY image_ptr;
  168.   JDIMENSION row, col;
  169.   cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
  170.  
  171.   /* Read the data into a virtual array in input-file row order. */
  172.   for (row = 0; row < cinfo->image_height; row++) {
  173.     if (progress != NULL) {
  174.       progress->pub.pass_counter = (long) row;
  175.       progress->pub.pass_limit = (long) cinfo->image_height;
  176.       (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
  177.     }
  178.     image_ptr = (*cinfo->mem->access_virt_sarray)
  179.       ((j_common_ptr) cinfo, source->whole_image,
  180.        row, (JDIMENSION) 1, TRUE);
  181.     out_ptr = image_ptr[0];
  182.     for (col = source->row_width; col > 0; col--) {
  183.       /* inline copy of read_byte() for speed */
  184.       if ((c = getc(infile)) == EOF)
  185.     ERREXIT(cinfo, JERR_INPUT_EOF);
  186.       *out_ptr++ = (JSAMPLE) c;
  187.     }
  188.   }
  189.   if (progress != NULL)
  190.     progress->completed_extra_passes++;
  191.  
  192.   /* Set up to read from the virtual array in top-to-bottom order */
  193.   switch (source->bits_per_pixel) {
  194.   case 8:
  195.     source->pub.get_pixel_rows = get_8bit_row;
  196.     break;
  197.   case 24:
  198.     source->pub.get_pixel_rows = get_24bit_row;
  199.     break;
  200.   default:
  201.     ERREXIT(cinfo, JERR_sprite_BADDEPTH);
  202.   }
  203.   source->source_row = cinfo->image_height;
  204.  
  205.   /* And read the first row */
  206.   return (*source->pub.get_pixel_rows) (cinfo, sinfo);
  207. }
  208.  
  209.  
  210. /*
  211.  * Read the file header; return image size and component count.
  212.  */
  213.  
  214. #define WORD(array,offset)  ((INT32) UCH(array[offset]) + \
  215.                 (((INT32) UCH(array[offset+1])) << 8) + \
  216.                 (((INT32) UCH(array[offset+2])) << 16) + \
  217.                 (((INT32) UCH(array[offset+3])) << 24))
  218.  
  219. METHODDEF void
  220. start_input_sprite (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
  221. {
  222.   sprite_source_ptr source = (sprite_source_ptr) sinfo;
  223.   U_CHAR spriteheader[56];
  224.   INT32 noofsprites;
  225.   INT32 offsettofirst;
  226.   INT32 offsettofree;
  227.   INT32 offsettonext;
  228.   U_CHAR spritename[12];
  229.   INT32 width;
  230.   INT32 height;
  231.   INT32 firstbit;
  232.   INT32 lastbit;
  233.   INT32 offsettosprite;
  234.   INT32 offsettomask;
  235.   INT32 mode;
  236.   INT32 bpp, colours, xdpi, ydpi;
  237.  
  238.   width = WORD(spriteinfoheader,24) + 1;
  239.   height = WORD(spriteinfoheader,28) + 1;
  240.   firstbit = WORD(spriteinfoheader,32);
  241.   lastbit = WORD(spriteinfoheader,36);
  242.   offsettosprite = WORD(spriteinfoheader,40);
  243.   mode = WORD(spriteinfoheader,48);
  244.  
  245.   OS_ReadModeVariable(mode, 9, &bpp);
  246.   bpp = 1<<bpp;
  247.   colours = 1<<bpp;
  248.   width = (width*32-(31-lastbit)-firstbit)/bpp
  249.  
  250.   source->bits_per_pixel = bpp;
  251.  
  252.   switch (bpp) {
  253.   case 8:
  254.     mapentrysize = 4;
  255.     TRACEMS2(cinfo, 1, JTRC_SPRITE_MAPPED, (int) width, (int) height);
  256.     break;
  257.   case 16, 32:
  258.     TRACEMS2(cinfo, 1, JTRC_SPRITE, (int) width, (int) height);
  259.     break;
  260.   default:
  261.     ERREXIT(cinfo, JERR_SPRITE_BADDEPTH);
  262.     break;
  263.   }
  264.  
  265.   /* Set JFIF density parameters from the sprite data */
  266.   OS_ReadModeVariable(mode, 4, &xdpi);
  267.   OS_ReadModeVariable(mode, 5, &ydpi);
  268.   cinfo->X_density = (UINT16) (180/xdpi);
  269.   cinfo->Y_density = (UINT16) (180/ydpi);
  270.   cinfo->density_unit = 1;    /* dots/inch **CHECK THIS!!** */
  271.  
  272.   /* Read the colormap, if any */
  273.   if (mapentrysize > 0) {
  274.     /* Allocate space to store the colormap */
  275.     source->colormap = (*cinfo->mem->alloc_sarray)
  276.       ((j_common_ptr) cinfo, JPOOL_IMAGE, (JDIMENSION) colours, (JDIMENSION) 3);
  277.     /* and read it from the file */
  278.     read_colormap(source, (int) colours, mapentrysize);
  279.   }
  280.  
  281.   /* Compute row width in file */
  282.   source->row_width = (JDIMENSION) (WORD(spriteinfoheader,24) + 1) * 4;
  283.  
  284.   /* Allocate one-row buffer for returned data */
  285.   source->pub.buffer = (*cinfo->mem->alloc_sarray)
  286.     ((j_common_ptr) cinfo, JPOOL_IMAGE,
  287.      (JDIMENSION) (width * 3), (JDIMENSION) 1);
  288.   source->pub.buffer_height = 1;
  289.  
  290.   cinfo->in_color_space = JCS_RGB;
  291.   cinfo->input_components = 3;
  292.   cinfo->data_precision = 8;
  293.   cinfo->image_width = (JDIMENSION) width;
  294.   cinfo->image_height = (JDIMENSION) height;
  295. }
  296.  
  297.  
  298. /*
  299.  * Finish up at the end of the file.
  300.  */
  301.  
  302. METHODDEF void
  303. finish_input_sprite (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
  304. {
  305.   /* no work */
  306. }
  307.  
  308.  
  309. /*
  310.  * The module selection routine for sprite format input.
  311.  */
  312.  
  313. GLOBAL cjpeg_source_ptr
  314. jinit_read_sprite (j_compress_ptr cinfo)
  315. {
  316.   sprite_source_ptr source;
  317.  
  318.   /* Create module interface object */
  319.   source = (sprite_source_ptr)
  320.       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  321.                   SIZEOF(sprite_source_struct));
  322.   source->cinfo = cinfo;    /* make back link for subroutines */
  323.   /* Fill in method ptrs, except get_pixel_rows which start_input sets */
  324.   source->pub.start_input = start_input_sprite;
  325.   source->pub.finish_input = finish_input_sprite;
  326.  
  327.   return (cjpeg_source_ptr) source;
  328. }
  329.  
  330. #endif /* sprite_SUPPORTED */
  331.