home *** CD-ROM | disk | FTP | other *** search
/ Fish 'n' More 2 / fishmore-publicdomainlibraryvol.ii1991xetec.iso / fish / graphics / applications / dkbtrace / src / dumptoiff.c < prev    next >
C/C++ Source or Header  |  1990-08-26  |  14KB  |  510 lines

  1. /*****************************************************************************
  2. *
  3. *                                   dumptoiff.c
  4. *
  5. *   from DKBTrace (c) 1990  David Buck
  6. *
  7. *  This file converts the raw output from the ray tracer into HAM files.
  8. *
  9. * This software is freely distributable. The source and/or object code may be
  10. * copied or uploaded to communications services so long as this notice remains
  11. * at the top of each file.  If any changes are made to the program, you must
  12. * clearly indicate in the documentation and in the programs startup message
  13. * who it was who made the changes. The documentation should also describe what
  14. * those changes were. This software may not be included in whole or in
  15. * part into any commercial package without the express written consent of the
  16. * author.  It may, however, be included in other public domain or freely
  17. * distributed software so long as the proper credit for the software is given.
  18. *
  19. * This software is provided as is without any guarantees or warranty. Although
  20. * the author has attempted to find and correct any bugs in the software, he
  21. * is not responsible for any damage caused by the use of the software.  The
  22. * author is under no obligation to provide service, corrections, or upgrades
  23. * to this package.
  24. *
  25. * Despite all the legal stuff above, if you do find bugs, I would like to hear
  26. * about them.  Also, if you have any comments or questions, you may contact me
  27. * at the following address:
  28. *
  29. *     David Buck
  30. *     22C Sonnet Cres.
  31. *     Nepean Ontario
  32. *     Canada, K2H 8W7
  33. *
  34. *  I can also be reached on the following bulleton boards:
  35. *
  36. *     ATX              (613) 526-4141
  37. *     OMX              (613) 731-3419
  38. *     Mystic           (613) 731-0088 or (613) 731-6698
  39. *
  40. *  Fidonet:   1:163/109.9
  41. *  Internet:  David_Buck@Carleton.CA
  42. *
  43. *
  44. *****************************************************************************/
  45.  
  46.  
  47. #include <stdio.h>
  48. #include <exec/types.h>
  49. #include <intuition/intuition.h>
  50. #include <graphics/display.h>
  51. #include <libraries/dos.h>
  52. #include <proto/all.h>
  53. #include "config.h"
  54. #include "iff.h"
  55. #include "dumptoiff.h"
  56. #include "dumproto.h"
  57.  
  58. struct IntuitionBase *IntuitionBase;
  59. struct GfxBase *GfxBase;
  60. struct Screen *s;
  61.  
  62. #define extract_red(x) ((x & 0xF00) >> 8)
  63. #define extract_green(x) ((x & 0x0F0) >> 4)
  64. #define extract_blue(x) (x & 0x00F)
  65.  
  66. struct NewScreen MyScreen =
  67.    {
  68.    0, 0,
  69.    SCREEN_WIDTH, SCREEN_HEIGHT,
  70.    6,
  71.    0, 1,
  72.    INTERLACE | HAM,
  73.    0,
  74.    NULL,
  75.    (UBYTE *) "DumpToIFF",
  76.    NULL,
  77.    NULL
  78.    };
  79.  
  80. UWORD ColourTbl[16] = { 0x000, 0x111, 0x222, 0x333, 0x444, 0x555, 0x666,
  81.                         0x777, 0x888, 0x999, 0xaaa, 0xbbb, 0xccc, 0xddd,
  82.                         0xeee, 0xfff };
  83.  
  84. LONG last_y = -1;
  85. IMAGE Raw_Image;
  86.  
  87. FILE *fp, *palette_file, *output_palette_file;
  88. char input_filename[100], palette_filename[100], output_filename[100];
  89. char output_palette_filename[100];
  90.  
  91.  
  92. int output_file, read_palette, write_palette, dithering;
  93. void get_parameters(int argc, char **argv);
  94.  
  95. void main (argc, argv) 
  96.    int argc;
  97.    char **argv;
  98.    {
  99.    unsigned int red, green, blue, i;
  100.    unsigned int x, y, index;
  101.  
  102.    if (argc < 2)
  103.      {
  104.      printf ("\nUsage:  DumpToIFF [options] <dump_filename> <iff_file_name> [<palette_filename>]\n");
  105.      printf ("            Options:\n");
  106.      printf ("               -d           - No dithering\n");
  107.      printf ("               -pfilename   - Write a palette file\n");
  108.      exit(0);
  109.      }
  110.  
  111.    Close_Threshold = 5;
  112.  
  113.    fp = NULL;
  114.    read_palette = FALSE;
  115.    write_palette = FALSE;
  116.    output_file = FALSE;
  117.    dithering = TRUE;
  118.  
  119.    IntuitionBase = (struct IntuitionBase *)
  120.                     OpenLibrary ("intuition.library",INT_REV);
  121.    if (IntuitionBase == NULL)
  122.       exit(FALSE);
  123.  
  124.    GfxBase = (struct GfxBase *)
  125.                       OpenLibrary ("graphics.library", GR_REV);
  126.    if (GfxBase == NULL)
  127.       exit(FALSE);
  128.  
  129.    get_parameters(argc, argv);
  130.  
  131.    printf ("Reading raw file\n");
  132.    read_raw_image (&Raw_Image, input_filename);
  133.  
  134.  
  135.    if (dithering) {
  136.       printf ("Dithering...\n");
  137.       dither(&Raw_Image);
  138.       }
  139.  
  140.    printf ("Processing...\n");
  141.    if (read_palette) {
  142.       if ((palette_file = fopen (palette_filename, "r")) == NULL) {
  143.          display_close();
  144.          exit(FALSE);
  145.          }
  146.  
  147.       for (i = 0 ; i < 16 ; i++) {
  148.          if (fscanf (palette_file, "%d %d %d", &red, &green, &blue) != 3) {
  149.             printf ("Error reading palette file\n");
  150.             exit (1);
  151.             }
  152.  
  153.          ColourTbl[i] = ((red & 0x0f) << 8) |
  154.                         ((green & 0x0f) << 4) | (blue & 0x0f);
  155.          }
  156.       }
  157.    else {
  158.       start_recording_colours();
  159.  
  160.       for (y = 0 ; y < Raw_Image.height ; y++) {
  161.          for (x = 0 ; x < Raw_Image.width ; x++) {
  162.             index = y*Raw_Image.width + x;
  163.             process (x, y, Raw_Image.red[index],
  164.                            Raw_Image.green[index],
  165.                            Raw_Image.blue[index]);
  166.          
  167.             }
  168.          }
  169.       choose_palette();
  170.       }
  171.  
  172.    /* Write out the palette file */
  173.    if (write_palette) {
  174.       if ((output_palette_file = fopen (output_palette_filename, "w")) == NULL)
  175.          {
  176.          printf ("Cannot create palette file\n");
  177.          exit (1);
  178.          }
  179.  
  180.       
  181.       for (i = 0 ; i < 16 ; i++)
  182.          fprintf (output_palette_file, "%d %d %d\n",
  183.                   extract_red(ColourTbl[i]),
  184.                   extract_green(ColourTbl[i]),
  185.                   extract_blue(ColourTbl[i]));
  186.  
  187.  
  188.       fclose(output_palette_file);
  189.       }
  190.  
  191.    printf ("Displaying...\n");
  192.  
  193.    MyScreen.Width = Raw_Image.width+1;
  194.    MyScreen.Height = Raw_Image.height;
  195.    if ((s = (struct Screen *) OpenScreen (&MyScreen))
  196.           == NULL)
  197.       exit (FALSE);
  198.  
  199.    ShowTitle (s, FALSE);
  200.  
  201.  
  202.    SetAPen (&(s->RastPort), 7L);
  203.    RectFill (&(s -> RastPort), 0L, 0L, Raw_Image.width, Raw_Image.height-1);
  204.  
  205.    LoadRGB4 (&(s->ViewPort), ColourTbl, 16L);
  206.  
  207.    for (y = 0 ; y < Raw_Image.height ; y++) {
  208.       for (x = 0 ; x < Raw_Image.width ; x++) {
  209.             index = y*Raw_Image.width + x;
  210.             display_plot (x, y, Raw_Image.red[index],
  211.                                 Raw_Image.green[index],
  212.                                 Raw_Image.blue[index]);
  213.          }
  214.       }
  215.  
  216.    if (output_file)
  217.       ConvertToIFF(output_filename);
  218.  
  219.    printf ("Finished\n");
  220.    display_close();
  221.    }
  222.  
  223. void get_parameters (argc, argv)
  224.    int argc;
  225.    char **argv;
  226.    {
  227.    int i, filename_number;
  228.  
  229.    filename_number = 0;
  230.    for (i = 1 ; i < argc ; i++) {
  231.       if (argv[i][0] == '-')
  232.          switch (argv[i][1]) {
  233.             case 'd':  dithering = FALSE;
  234.                        break;
  235.  
  236.             case 'p':  strcpy (output_palette_filename, &argv[i][2]);
  237.                        write_palette = TRUE;
  238.                        break;
  239.  
  240.             default:   printf ("Unknown option\n");
  241.                        break;
  242.             }
  243.       else
  244.          switch (filename_number) {
  245.             case 0: strcpy (input_filename, argv[i]);
  246.                     filename_number++;
  247.                     break;
  248.  
  249.             case 1: strcpy (output_filename, argv[i]);
  250.                     output_file = TRUE;
  251.                     filename_number++;
  252.                     break;
  253.  
  254.             case 2: strcpy (palette_filename, argv[i]);
  255.                     filename_number++;
  256.                     read_palette = TRUE;
  257.                     break;
  258.  
  259.             default: printf ("Too many filenames in commandline\n");
  260.                      exit(1);
  261.             }
  262.       }
  263.    if (filename_number == 0) {
  264.       printf ("No input file specified\n");
  265.       exit(1);
  266.       }
  267.    }
  268.  
  269.  
  270. void display_close ()
  271.    {
  272.    if (fp != NULL)
  273.       fclose (fp);
  274.    CloseScreen (s);
  275.    CloseLibrary (GfxBase) ;
  276.    CloseLibrary (IntuitionBase) ;
  277.    }
  278.  
  279. void display_plot (x, y, new_red, new_green, new_blue)
  280.    LONG x, y, new_red, new_green, new_blue;
  281.    {
  282.    LONG colour, newline;
  283.  
  284.    new_red &= 0xFF;
  285.    new_green &= 0xFF;
  286.    new_blue &= 0xFF;
  287.  
  288.    new_red /= 16;
  289.    new_green /= 16;
  290.    new_blue /= 16;
  291.  
  292.    newline = 0;
  293.    if (last_y != y) {
  294.       newline = 1;
  295.       last_y = y;
  296.       reset_colours();
  297.       SetAPen (&(s -> RastPort), 0);
  298.       WritePixel (&(s -> RastPort), 0, y);
  299.       }
  300.  
  301.    colour = best_colour (new_red, new_blue, new_green);
  302.    SetAPen (&(s -> RastPort), colour);
  303.    WritePixel (&(s -> RastPort), x+1, y);
  304.    }
  305.  
  306.  
  307. void dither (Image)
  308.    IMAGE *Image;
  309.    {
  310.    long index;
  311.    short i, j, new_red, new_green, new_blue,
  312.        red_error, green_error, blue_error;
  313.  
  314.    red_error = 0;
  315.    green_error = 0;
  316.    blue_error = 0;
  317.  
  318.    for (j = 0 ; j < Image->height ; j++)
  319.       for (i = 0 ; i < Image->width ; i++) {
  320.          index = j * Image->width + i;
  321.          red_error = Image->red[index] % 16;
  322.          green_error = Image->green[index] % 16;
  323.          blue_error = Image->blue[index] % 16;
  324.  
  325.          if (i < Image->width-1) {
  326.             new_red = Image->red[index+1] + red_error * 7 / 16;
  327.             new_green = Image->green[index+1] + green_error * 7 / 16;
  328.             new_blue = Image->blue[index+1] + blue_error * 7 / 16;
  329.             Image->red[index+1] = (new_red>255) ? 255 : new_red;
  330.             Image->green[index+1] = (new_green>255) ? 255 : new_green;
  331.             Image->blue[index+1] = (new_blue>255) ? 255 : new_blue;
  332.             }
  333.  
  334.          if (j < Image->height-1) {
  335.             index += Image->width;
  336.             if (i != 0) {
  337.                new_red = Image->red[index-1] + red_error * 3 / 16;
  338.                new_green = Image->green[index-1] + green_error * 3 / 16;
  339.                new_blue = Image->blue[index-1] + blue_error * 3 / 16;
  340.                Image->red[index-1] = (new_red>255) ? 255 : new_red;
  341.                Image->green[index-1] = (new_green>255) ? 255 : new_green;
  342.                Image->blue[index-1] = (new_blue>255) ? 255 : new_blue;
  343.                }
  344.  
  345.  
  346.             new_red = Image->red[index] + red_error * 5 / 16;
  347.             new_green = Image->green[index] + green_error * 5 / 16;
  348.             new_blue = Image->blue[index] + blue_error * 5 / 16;
  349.             Image->red[index] = (new_red>255) ? 255 : new_red;
  350.             Image->green[index] = (new_green>255) ? 255 : new_green;
  351.             Image->blue[index] = (new_blue>255) ? 255 : new_blue;
  352.  
  353.             if (i < Image->width-1) {
  354.                new_red = Image->red[index+1] + red_error / 16;
  355.                new_green = Image->green[index+1] + green_error / 16;
  356.                new_blue = Image->blue[index+1] + blue_error / 16;
  357.                Image->red[index+1] = (new_red>255) ? 255 : new_red;
  358.                Image->green[index+1] = (new_green>255) ? 255 : new_green;
  359.                Image->blue[index+1] = (new_blue>255) ? 255 : new_blue;
  360.                }
  361.             }
  362.          }
  363.    }
  364.  
  365.  
  366. void process (x, y, new_red, new_green, new_blue)
  367.    LONG x, y, new_red, new_green, new_blue;
  368.    {
  369.    LONG newline;
  370.  
  371.    new_red &= 0xFF;
  372.    new_green &= 0xFF;
  373.    new_blue &= 0xFF;
  374.  
  375.    new_red /= 16;
  376.    new_green /= 16;
  377.    new_blue /= 16;
  378.  
  379.    newline = 0;
  380.    if (last_y != y) {
  381.      newline = 1;
  382.      last_y = y;
  383.      reset_colours();
  384.      }
  385.  
  386.    record_colours (new_red, new_green, new_blue);
  387.    }
  388.  
  389.  
  390. void ConvertToIFF(file_name)
  391.    char *file_name;
  392.    {
  393.    char *buffer;
  394.    BPTR file;
  395.    BOOL PutPict();
  396.  
  397.    if ((file = Open (file_name, MODE_NEWFILE)) == 0) {
  398.       printf ("\nCannot open IFF file\n");
  399.       exit (0);
  400.       }
  401.  
  402.    buffer = malloc(BUFFER_SIZE);
  403.    if (PutPict (file, &(s->ViewPort), buffer, BUFFER_SIZE))
  404.       printf ("\nIFF write error\n");
  405.    Close (file);
  406.    }
  407.  
  408. int read_raw_byte(f)
  409.    FILE *f;
  410.    {
  411.    int c;
  412.    if ((c = getc(f)) == EOF)
  413.       return (-1);
  414.    return (c);
  415.    }
  416.  
  417. int read_raw_word(f)
  418.    FILE *f;
  419.    {
  420.    int byte1, byte2;
  421.  
  422.    byte1 = read_raw_byte(f);
  423.    if (byte1 == -1)
  424.       return(-1);
  425.  
  426.    byte2 = read_raw_byte(f);
  427.    if (byte2 == -1)
  428.       return(-1);
  429.  
  430.    return (byte1 + byte2*256);
  431.    }
  432.  
  433. void read_raw_image(Image, filename)
  434.    IMAGE *Image;
  435.    char *filename;
  436.    {
  437.    FILE *f;
  438.    int byte, i, index, row, pixels;
  439.  
  440.    if ((f = fopen(filename, "rb")) == NULL) {
  441.       printf ("Cannot open raw file %s\n", filename);
  442.       exit(1);
  443.       }
  444.  
  445.    Image->width = read_raw_word(f);
  446.    if (Image->width == -1) {
  447.       printf ("Cannot read size in dump file\n");
  448.       exit(1);
  449.       }
  450.  
  451.    Image->height = read_raw_word(f);
  452.    if (Image->height == -1) {
  453.       printf ("Cannot read size in dump file: %s\n", filename);
  454.       exit(1);
  455.       }
  456.  
  457.    pixels = Image->width * Image->height;
  458.  
  459.    if (((Image->red = (unsigned char *) malloc(pixels))==NULL) ||
  460.        ((Image->green = (unsigned char *) malloc(pixels))==NULL) ||
  461.        ((Image->blue = (unsigned char *) malloc(pixels))==NULL)) {
  462.       printf ("Cannot allocate memory for picture: %s\n", filename);
  463.       exit(1);
  464.       }
  465.  
  466.    for (i = 0 ; i < pixels ; i++) {
  467.       Image->red[i] = 0;
  468.       Image->green[i] = 0;
  469.       Image->blue[i] = 0;
  470.       }
  471.  
  472.    row = read_raw_word(f);
  473.    while (row != -1) {
  474.       for (i = 0 ; i < Image->width ; i++) {
  475.          index = row*Image->width + i;
  476.  
  477.          byte = read_raw_byte(f);
  478.          if (byte == -1) {
  479.             printf ("Unexpected end of file in raw image: %s\n", filename);
  480.             exit(1);
  481.             }
  482.          Image->red[index] = byte;
  483.          }
  484.  
  485.       for (i = 0 ; i < Image->width ; i++) {
  486.          index = row*Image->width + i;
  487.  
  488.          byte = read_raw_byte(f);
  489.          if (byte == -1) {
  490.             printf ("Unexpected end of file in raw image: %s\n", filename);
  491.             exit(1);
  492.             }
  493.          Image->green[index] = byte;
  494.          }
  495.  
  496.       for (i = 0 ; i < Image->width ; i++) {
  497.          index = row*Image->width + i;
  498.  
  499.          byte = read_raw_byte(f);
  500.          if (byte == -1) {
  501.             printf ("Unexpected end of file in raw image: %s\n", filename);
  502.             exit(1);
  503.             }
  504.          Image->blue[index] = byte;
  505.          }
  506.       row = read_raw_word(f);
  507.       }
  508.    fclose (f);
  509.    }
  510.