home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / utilities / utilsm / randjpeg / source / c / process < prev    next >
Encoding:
Text File  |  1996-01-21  |  7.1 KB  |  265 lines

  1. /* process.c
  2.  * MACHINE:     RISC OS 3.60
  3.  * LANGUAGE:    Acorn C v5.06
  4.  * AUTHOR:      Cy Booker <cy@cheepnis.demon.co.uk>
  5.  * LICENCE:     Freeware, Copyright (c) 1996 Cy Booker
  6.  */
  7.  
  8. #include "process.h"
  9.  
  10.  
  11. #include <assert.h>
  12. #include <ctype.h>
  13. #include <limits.h>
  14. #include <locale.h>
  15. #include <math.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <string.h>
  19.  
  20.  
  21. #include "OS:colourtrans.h"
  22. #include "OS:hourglass.h"
  23. #include "OS:jpeg.h"
  24. #include "OS:macros.h"
  25. #include "OS:osfile.h"
  26. #include "OS:osspriteop.h"
  27.  
  28.  
  29. #include "internal.h"
  30.  
  31.  
  32. #include "OS:osfile.h"
  33.  
  34. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  35.  */
  36.  
  37. #define XDPI                    (90)
  38. #define YDPI                    (90)
  39.  
  40.  
  41. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  42.  */
  43.  
  44. #define MODE(LOG2BPP, XRES, YRES) ((os_mode)(\
  45.                      (((LOG2BPP) + 1) << osspriteop_TYPE_SHIFT)\
  46.                      | ((XRES) << osspriteop_YRES_SHIFT)\
  47.                      | ((YRES) << osspriteop_XRES_SHIFT)\
  48.                      | 1))
  49.  
  50. #define LSR(X, S)       (((unsigned int)(X)) >> (S))            /* portable */
  51.  
  52. #define WORD_WIDTH(P)  LSR((P) + 31, 5)                         /* P is BIT width */
  53.  
  54.  
  55. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  56.  */
  57.  
  58.  
  59. rgbtuple        default_wimp_palette_as_tuples[256];
  60.  
  61. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  62.  */
  63.  
  64.  
  65. static void inline_reduce_sprite_to_8bpp(
  66.                 osspriteop_area *area,
  67.                 const char      *sprite_name);
  68.  
  69. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  70.  */
  71.  
  72.   /*
  73.    * actually, the current JPEG renderer ignores the source DPI
  74.    * when rendering, so keep scale factors as constant
  75.    */
  76.  
  77. extern void process(
  78.                 const char      *source_file_name,
  79.                 const char      *dest_file_name) {
  80.   os_error              *error;
  81.   int                   c0, c1, c2, c3;
  82.   osspriteop_area       *area;
  83.   os_mode               mode;
  84.   jpeg_info_flags       flags;
  85.   int                   width, height, xdpi, ydpi, workspace_size;
  86.   int                   lb_bpp;
  87.   int                   line_length;
  88.   size_t                area_size;
  89.   char                  sprite_name[osspriteop_NAME_LIMIT+1];
  90.  
  91.   assert(source_file_name);
  92.   assert(dest_file_name);
  93.  
  94.   {
  95.     const char  *name;
  96.     int         len;
  97.     int         i;
  98.     
  99.     name = strrchr(source_file_name, '.');
  100.     if (!name) {
  101.       name = strrchr(source_file_name, ':');
  102.     }
  103.     if (!name) {
  104.       name = source_file_name;
  105.     } else {
  106.       name++;
  107.     }
  108.     len = strlen(name);
  109.     if (len > osspriteop_NAME_LIMIT) {
  110.       name += len - osspriteop_NAME_LIMIT;
  111.     }
  112.     for (i= 0; (name[i]); i++) {
  113.       sprite_name[i] = tolower(name[i]);
  114.     }
  115.     sprite_name[i] = '\0';
  116.   }
  117.  
  118.   flags = jpegfileinfo_dimensions(
  119.                 source_file_name,
  120.                 &width, &height,
  121.                 &xdpi, &ydpi,
  122.                 &workspace_size);
  123.  
  124.   lb_bpp = 5;
  125.  
  126.   line_length = 4 * WORD_WIDTH(width * (1 << lb_bpp));
  127.  
  128.   mode = MODE(lb_bpp, XDPI, YDPI);
  129.   
  130.   area_size = sizeof(osspriteop_area)
  131.                 + sizeof (osspriteop_header)
  132.                 + 0 /*palette_size*/
  133.                 + (line_length * height)
  134.                 + 0 /*mask size*/;
  135.  
  136.   area = xmalloc(area_size);
  137.  
  138.   area->size  = area_size;
  139.   area->first = sizeof(osspriteop_area);
  140.   osspriteop_clear_sprites(osspriteop_USER_AREA, area);
  141.   osspriteop_create_sprite(
  142.                 osspriteop_NAME,
  143.                 area,
  144.                 sprite_name,
  145.                 FALSE,                  /* no palette */
  146.                 width,
  147.                 height,
  148.                 mode);
  149.   xhourglass_on();
  150.   osspriteop_switch_output_to_sprite(
  151.                 osspriteop_NAME,
  152.                 area,
  153.                 (osspriteop_id)sprite_name,
  154.                 NULL,                           /* use system save area */
  155.                 &c0, &c1, &c2, &c3);
  156.   {
  157.     error = xcolourtrans_invalidate_cache();
  158.     if (error) goto recover;
  159.  
  160.     error = xjpeg_plot_file_scaled(source_file_name, 0, 0, NULL, 0);
  161.     if (error) goto recover;
  162.   }
  163.   osspriteop_unswitch_output(c0, c1, c2, c3);
  164.   colourtrans_invalidate_cache();
  165.  
  166.   inline_reduce_sprite_to_8bpp(area, sprite_name);
  167.  
  168.   osspriteop_save_sprite_file(osspriteop_USER_AREA, area, dest_file_name);
  169.   xhourglass_off();
  170.   free (area);
  171.   return;
  172. recover:
  173.   xosspriteop_unswitch_output(c0, c1, c2, c3);
  174.   xhourglass_off();
  175.   os_generate_error(error);
  176. }
  177.  
  178.  
  179. /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  180.  */
  181.  
  182.  
  183. static void inline_reduce_sprite_to_8bpp(
  184.                 osspriteop_area *area,
  185.                 const char      *sprite_name) {
  186.   osspriteop_header     *sprite;
  187.   int                   width;
  188.   int                   height;
  189.   int                   line_length;
  190.   process_image         p;
  191.   int                   size;
  192.   int                   delta;
  193.   char                  *base = (char *)area;
  194.   int                   sprite_offset;
  195.   int                   eof_sprite;
  196.   int                   nbytes_above;
  197.   int                   bpp;
  198.   int                   ppw;
  199.  
  200.   assert(area);
  201.   assert(sprite_name);
  202.  
  203.   sprite = osspriteop_select_sprite(
  204.                 osspriteop_NAME,
  205.                 area,
  206.                 (osspriteop_id)sprite_name);
  207.   assert(sprite);
  208.  
  209.   width       = sprite->width + 1;
  210.   height      = sprite->height + 1;
  211.   line_length = ALIGN(width);
  212.   p.pixel_width        = width;
  213.   p.pixel_height       = height;
  214.   p.source_line_length = width * 4;
  215.   p.dest_line_length   = line_length;
  216.   p.buffer             = (byte *)(((char *)sprite) + sprite->image);
  217.   p.fn                 = map_scaled_rgb_to_8bpp_colour_number_changefsi;
  218.  
  219.   {
  220.     int       red, grn, blu, tnt, idx;
  221.  
  222.     for (idx= 0; (idx < 256); idx++) {
  223.       /* idx == %BGgRbrTt */
  224.       red = ((idx & 0x10) >> 1) | ((idx & 0x04) >> 0);
  225.       grn = ((idx & 0x40) >> 3) | ((idx & 0x20) >> 3);
  226.       blu = ((idx & 0x80) >> 4) | ((idx & 0x08) >> 1);
  227.       tnt = idx & 0x03;
  228.       red |= tnt; red |= red << 4; red |= red << 8;   /* expand 4 bit -> 16 bit */
  229.       grn |= tnt; grn |= grn << 4; grn |= grn << 8;
  230.       blu |= tnt; blu |= blu << 4; blu |= blu << 8;
  231.       default_wimp_palette_as_tuples[idx].red = red;
  232.       default_wimp_palette_as_tuples[idx].grn = grn;
  233.       default_wimp_palette_as_tuples[idx].blu = blu;
  234.     }
  235.   }
  236.   xhourglass_on();
  237.  
  238.   /*process_image_8bpp_floyd_steinberg(&p);*/
  239.   process_image_8bpp_sierra2_4a(&p);
  240.   /*process_image_8bpp_sierra3(&p);*/
  241.   /*process_image_8bpp_nearest(&p);*/
  242.   xhourglass_off();
  243.  
  244.   size = (height * line_length) + sizeof(*sprite);
  245.   delta = size - sprite->size;
  246.  
  247.   sprite_offset = ((char *)sprite) - base;
  248.   eof_sprite = sprite_offset + sprite->size;
  249.   nbytes_above = area->used - eof_sprite;
  250.   if (nbytes_above > 0) {
  251.     memmove(base + eof_sprite, base + sprite_offset + size, nbytes_above);
  252.   }
  253.   
  254.   bpp = 8;
  255.   ppw = 32 / bpp;
  256.   sprite->right_bit = 31 - (bpp * (width % ppw));        /* and must do this! */
  257.   sprite->width = (line_length / 4) - 1;
  258.   sprite->mode = os_MODE8BPP90X90;
  259.   sprite->size += delta;
  260.   area->used += delta;
  261.  
  262.   osspriteop_verify_area(osspriteop_USER_AREA, area);
  263. }
  264.  
  265.