home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / formats / gif / amiga / amigif.arc / showgif.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-06-16  |  7.1 KB  |  388 lines

  1. /***********************************************************
  2.  * Copyright (c) 1987                                      *
  3.  * by CompuServe Inc, Columbus, Ohio.  All Rights Reserved *
  4.  ***********************************************************/
  5.  
  6. /*
  7.  * ABSTRACT:
  8.  *
  9.  * ENVIRONMENT: AmigaDOS
  10.  *
  11.  * AUTHOR: Steve Wilhite, CREATION DATE: 12-Mar-87
  12.  *
  13.  * REVISION HISTORY:
  14.  *
  15.  */
  16.  
  17. #include <exec/types.h>
  18. #include <intuition/intuition.h>
  19. #include <stdio.h>
  20.  
  21. /*
  22.  * IMPORTS:
  23.  */
  24.  
  25. extern APTR OpenLibrary();
  26. extern APTR OpenScreen();
  27. extern APTR OpenWindow();
  28. extern APTR GetMsg();
  29. extern void LoadRGB4();
  30.  
  31. /*
  32.  * EXPORTS:
  33.  */
  34.  
  35. struct IntuitionBase *IntuitionBase;
  36. struct GfxBase *GfxBase;
  37.  
  38. /*
  39.  * PRIVATE:
  40.  */
  41.  
  42. static void Terminate();
  43.  
  44. static UWORD colorTable[32];
  45. static struct ViewPort *vp;
  46. static struct RastPort *rp;
  47. static struct Screen *Screen;
  48. static struct Window *Window;
  49. static struct IntuiMessage *Msg;
  50. static UWORD Class, Code;
  51.  
  52. static struct NewScreen NewScreen =
  53.     {
  54.     0, 0, 0, 0, 0, 0, 1, 0, CUSTOMSCREEN, NULL, NULL, NULL, NULL
  55.     };
  56.  
  57. static struct NewWindow NewWindow =
  58.     {
  59.     0, 0, 0, 0, 0, 1,
  60.     CLOSEWINDOW,
  61.     ACTIVATE | BORDERLESS | WINDOWCLOSE,
  62.     NULL, NULL, NULL, NULL, NULL,
  63.     320, 200, 640, 400,
  64.     CUSTOMSCREEN
  65.     };
  66.  
  67. #define buffer_size    4096
  68. #define INTUITION_REV    0
  69. #define GRAPHICS_REV    0
  70.  
  71.  
  72. static int
  73.     input_file = 0,
  74.     bytes_unread,
  75.     palette[16],
  76.     backdrop_width, backdrop_height,
  77.     fill_color,
  78.     left_edge, top_edge, right_edge, bottom_edge,
  79.     image_width, image_height,
  80.     bit_planes,
  81.     have_color_map, interlaced_mode,
  82.     row, col,
  83.     old_color = -1,
  84.     plane[4],
  85.     screen_width = 320, screen_height = 200,
  86.     base_row[4] = {0, 4, 2, 1 },
  87.     row_disp[4] = {8, 8, 4, 2 },
  88.     interlace_pass,
  89.     num_colors;
  90.  
  91. static char
  92.     signature[] = "GIF87a";
  93.  
  94. static unsigned char
  95.     input_buffer[buffer_size],
  96.     *input_ptr;
  97.  
  98.  
  99. static int read_byte()
  100. /*
  101.  * Function:
  102.  *    Read the next byte from the input file.
  103.  *
  104.  * Returns:
  105.  *    0 .. 255    the byte
  106.  *    -1        end of file
  107.  *    -4        read error
  108.  */
  109.     {
  110.     if (bytes_unread == 0)
  111.     {
  112.     bytes_unread = Read(input_file, input_buffer, buffer_size);
  113.  
  114.     if (bytes_unread < 1)
  115.         if (bytes_unread == 0)
  116.         return -1;
  117.         else
  118.         return -4;        /* disk read error */
  119.  
  120.     input_ptr = input_buffer;
  121.     }
  122.  
  123.     bytes_unread--;
  124.     return (int) *input_ptr++;
  125.     }
  126.  
  127. static int write_pixel(pixel)
  128. /*
  129.  * Function:
  130.  *    Draw the specified pixel. Clip the image if necessary.
  131.  *
  132.  * Returns:
  133.  *    0 (always)
  134.  */
  135.     int pixel;
  136.     {
  137.     if (pixel != fill_color && col < NewWindow.Width && row < NewWindow.Height)
  138.     {
  139.     SetAPen(rp, pixel);
  140.     WritePixel(rp, col, row);
  141.     }
  142.  
  143.     col++;
  144.  
  145.     if (col > right_edge)
  146.     {
  147.     col = left_edge;
  148.  
  149.     if (interlaced_mode)
  150.         {
  151.         row += row_disp[interlace_pass];
  152.  
  153.         if (row > bottom_edge)
  154.         {
  155.         interlace_pass++;
  156.         row = top_edge + base_row[interlace_pass];
  157.         }
  158.         }
  159.     else
  160.         row++;
  161.     }
  162.  
  163.     return 0;
  164.     }
  165.  
  166. main(argc, argv)
  167.     int argc;
  168.     char *argv[];
  169.     {
  170.     int
  171.     status,
  172.     done,
  173.     i, j,
  174.     row, col,
  175.     color_resolution,
  176.         count, pixel,
  177.         red, green, blue,
  178.     color;
  179.  
  180.     char ch;
  181.  
  182.     /* Setup the libraries we will need. */
  183.     
  184.     IntuitionBase = (struct IntuitionBase *)
  185.         OpenLibrary("intuition.library", INTUITION_REV);
  186.         
  187.     if (IntuitionBase == NULL)
  188.     {
  189.     puts("?cannot open intuition library\n");
  190.     exit(FALSE);
  191.     }
  192.  
  193.     GfxBase = (struct GfxBase *)
  194.     OpenLibrary("graphics.library", GRAPHICS_REV);
  195.  
  196.     if (GfxBase == NULL)
  197.     {
  198.     puts("?cannot open graphics library\n");
  199.         exit(FALSE);
  200.     }
  201.  
  202.     if (argc < 2)
  203.     {
  204.     puts("usage: ShowGIF input-file\n");
  205.     exit(1);
  206.     }
  207.  
  208.     input_file = Open(argv[1], 1005);
  209.  
  210.     if (input_file == 0)
  211.     {
  212.     printf("? file %s not found\n", argv[1]);
  213.     exit(1);
  214.     }
  215.  
  216.     bytes_unread = 0;
  217.  
  218.     /* Read the signature sequence (should check it someday) */
  219.  
  220.     for (count = 0; count < 6; count++)
  221.     read_byte();
  222.  
  223.     /* Read the virtual screen description */
  224.  
  225.     backdrop_width = read_byte();
  226.     backdrop_width += 256*read_byte();
  227.     backdrop_height = read_byte();
  228.     backdrop_height += 256*read_byte();
  229.     count = read_byte();
  230.     bit_planes = (count & 7) + 1;
  231.     num_colors = 1 << bit_planes;
  232.     have_color_map = (count & 0x80) != 0;
  233.     fill_color = read_byte();
  234.     read_byte();            /* reserved */
  235.  
  236.     if (have_color_map)
  237.     /*
  238.      * Setup the default color map.
  239.      */
  240.     for (i = 0; i < num_colors; i++)
  241.         {
  242.         color = 0;
  243.  
  244.         red = read_byte();
  245.         colorTable[i] = (red & 0xF0) << 4;
  246.         green = read_byte();
  247.         colorTable[i] |= (green & 0xF0);
  248.         blue = read_byte();
  249.         colorTable[i] |= (blue & 0xF0) >> 4;
  250.         }
  251.  
  252.     /* Setup graphics mode depending on the size of the backdrop */
  253.  
  254.     if (backdrop_width <= 320)
  255.     {
  256.     NewScreen.Width = 320;
  257.     NewScreen.Height = 200;
  258.     NewScreen.Depth = bit_planes;
  259.     }
  260.     else if (backdrop_height <= 200)
  261.     {
  262.     NewScreen.Width = 640;
  263.     NewScreen.Height = 200;
  264.     NewScreen.Depth = 4;
  265.     NewScreen.ViewModes = HIRES;
  266.     }
  267.     else
  268.     {
  269.     NewScreen.Width = 640;
  270.     NewScreen.Height = 400;
  271.     NewScreen.Depth = 4;
  272.     NewScreen.ViewModes = HIRES | LACE;
  273.     }
  274.  
  275.     NewWindow.Width = NewScreen.Width;
  276.     NewWindow.Height = NewScreen.Height;
  277.  
  278.     if ((Screen = (struct Screen *) OpenScreen(&NewScreen)) == NULL)
  279.     {
  280.         puts("?cannot open new screen\n");
  281.         exit(FALSE);
  282.     }
  283.     
  284.     NewWindow.Screen = Screen;
  285.     
  286.     if ((Window = (struct Window *) OpenWindow(&NewWindow)) == NULL)
  287.     {
  288.         puts("?cannot open window\n");
  289.     Terminate();
  290.     }
  291.     
  292.     vp = &Screen->ViewPort;
  293.     rp = Window->RPort;
  294.  
  295.     LoadRGB4(vp, colorTable, num_colors);
  296.     SetDrMd(rp, JAM1);
  297.     SetAPen(rp, 0);
  298.     RectFill(rp, 0, 0, NewWindow.Width - 1, NewWindow.Height - 1);
  299.     done = 0;
  300.  
  301.     while (!done)
  302.     {
  303.     ch = read_byte();
  304.  
  305.     switch (ch)
  306.         {
  307.         case ',':
  308.         /*
  309.          * Read the image description.
  310.          */
  311.         left_edge = read_byte();
  312.         left_edge += 256*read_byte();
  313.         top_edge = read_byte();
  314.         top_edge += 256*read_byte();
  315.         image_width = read_byte();
  316.         image_width += 256*read_byte();
  317.         image_height = read_byte();
  318.         image_height += 256*read_byte();
  319.         count = read_byte();
  320.         bit_planes = (count & 0x07) + 1;
  321.         interlaced_mode = (count & 0x40) != 0;
  322.         have_color_map = (count & 0x80) != 0;
  323.         num_colors = 1 << bit_planes;
  324.         right_edge = left_edge + image_width - 1;
  325.         bottom_edge = top_edge + image_height - 1;
  326.  
  327.         if (have_color_map)
  328.             /*
  329.              * Read the local color map but ignore it for now.
  330.              */
  331.             for (i = 0; i < num_colors; i++)
  332.             {
  333.             red = read_byte();
  334.             green = read_byte();
  335.             blue = read_byte();
  336.             }
  337.  
  338.         row = top_edge;
  339.         col = left_edge;
  340.         interlace_pass = 0;
  341.         status = Expand_Data(read_byte, write_pixel);
  342.  
  343.         /*
  344.          * Wait until we get a close window message
  345.          */
  346.  
  347.         for (;;)
  348.             {
  349.             WaitPort(Window->UserPort);
  350.  
  351.             while ((Msg = (struct IntuiMessage *) GetMsg(Window->UserPort)) != NULL)
  352.             {
  353.             Class = Msg->Class;
  354.             Code = Msg->Code;
  355.             ReplyMsg(Msg);
  356.  
  357.             if (Class == CLOSEWINDOW)
  358.                 Terminate();
  359.             }
  360.             }
  361.  
  362.         break;
  363.  
  364.         case ';':    /* End of image-set */
  365.  
  366.         Terminate();
  367.         break;
  368.  
  369.         default:
  370.         printf("? unexpected byte %2x in GIF file\n", ch);
  371.         Terminate();
  372.         }
  373.     }
  374.     }
  375.  
  376.  
  377. static void Terminate()
  378.     {
  379.     if (input_file != 0)
  380.     Close(input_file);
  381.     if (Window != NULL)
  382.     CloseWindow(Window);
  383.     CloseScreen(Screen);
  384.     OpenWorkBench();
  385.     exit(TRUE);
  386.     }
  387.  
  388.