home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / saoimage / sao1_07.tar / mainbffr.c < prev    next >
C/C++ Source or Header  |  1990-04-20  |  8KB  |  247 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    mainbffr.c (Main Buffers)
  6.  * Purpose:    Allocate or reallocate large buffers
  7.  * Subroutine:    init_imaging buffers()        returns: void
  8.  * Subroutine:    init_display_buffers()        returns: void
  9.  * Subroutine:    init_colorbarbuf()        returns: void
  10.  * Subroutine:    init_panbuf()            returns: void
  11.  * Subroutine:    init_dispbuf()            returns: void
  12.  * Subroutine:    init_imagebuf()            returns: int
  13.  * Xlib calls:    none
  14.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  15.  *        You may do anything you like with this file except remove
  16.  *        this copyright.  The Smithsonian Astrophysical Observatory
  17.  *        makes no representations about the suitability of this
  18.  *        software for any purpose.  It is provided "as is" without
  19.  *        express or implied warranty.
  20.  * Modified:    {0} Michael VanHilst    initial version          25 May 1989
  21.  *              {1} MVH fix in init_imagebuf to note square buf  4 April 1990
  22.  *        {n} <who> -- <does what> -- <when>
  23.  */
  24.  
  25. #include <stdio.h>        /* get stderr, NULL, etc */
  26. #include <X11/Xlib.h>        /* X window stuff */
  27. #include <X11/Xutil.h>        /* X window manager stuff */
  28. #include "hfiles/define.h"    /* define MIN, MAX, etc. */
  29. #include "hfiles/struct.h"    /* declare structure types */
  30. #include "hfiles/extern.h"    /* extern main parameter structures */
  31. #include "hfiles/scale.h"    /* define scaling constants */
  32.  
  33. /*
  34.  * Subroutine:    init_imaging_buffers
  35.  * Purpose:    Allocate major buffers used for imaging
  36.  */
  37. void init_imaging_buffers ()
  38. {
  39.   char *calloc_errchk();
  40.   int init_imagebuf();
  41.  
  42.   buffer.scalemap = (unsigned char *)
  43.     calloc_errchk(SCALEBUFSZ, sizeof(char), "scaling map");
  44.   buffer.histogram = (int *)
  45.     calloc_errchk(SCALEBUFSZ, sizeof(int), "histogram table");
  46.   (void)init_imagebuf ();
  47.  
  48. /*
  49.  * Subroutine:    init_display_buffers
  50.  * Purpose:    Allocate buffers used for each window's display
  51.  */
  52. void init_display_buffers ()
  53. {
  54.   void init_panbuf(), init_dispbuf();
  55.  
  56.   init_panbuf();
  57.   init_dispbuf();
  58.  
  59. /*
  60.  * Subroutine:    init_panbuf
  61.  * Purpose:    Allocate or reallocate panbox display buffers
  62.  */
  63. void init_panbuf ()
  64. {
  65.   int buf_sz;
  66.   char *calloc_errchk();
  67.   
  68.   buf_sz = panbox.xwidth * panbox.yheight;
  69.   /* test if the current buffers are adequate, else allocate or reallocate */
  70.   if( buf_sz > buffer.panbuf_sz ) {
  71.     if( buffer.panbuf != NULL )
  72.       free( (char *)buffer.panbuf );
  73.     if( panbox.image.data != NULL ) {
  74.       free( panbox.image.data );
  75.       panbox.image.data = NULL;
  76.       panbox.data_size = 0;
  77.     }
  78.     /* reserve exact window sized buffer for the panbox short integer image */
  79.     buffer.panbuf = (short *)
  80.       calloc_errchk(buf_sz, sizeof(short), "Panbox map");
  81.     buffer.panbuf_sz = buf_sz;
  82.     /* reserve buffer for the panbox display image */
  83.     if( color.screen_depth <= 1 ) {
  84.       /* if only bitmap will be used */
  85.       panbox.image.bytes_per_line = (panbox.xwidth + 7) / 8;
  86.       buf_sz = panbox.image.bytes_per_line * panbox.yheight;
  87.     }
  88.     panbox.image.data = calloc_errchk(buf_sz, sizeof(char), "Panbox display");
  89.     panbox.data_size = buf_sz;
  90.   }
  91.   panbox.image.width = panbox.xwidth;
  92.   panbox.image.height = panbox.yheight;
  93. }
  94.  
  95. /*
  96.  * Subroutine:    init_dispbuf
  97.  * Purpose:    Allocate or reallocate dispbox display buffer
  98.  */
  99. void init_dispbuf ()
  100. {
  101.   int buf_sz;
  102.   char *calloc_errchk();
  103.   void set_coordsys(), set_tdisp();
  104.  
  105.   dispbox.image.width = dispbox.xwidth;
  106.   dispbox.image.height = dispbox.yheight;
  107.   if( color.screen_depth <= 1 ) {
  108.     /* if only bitmap will be used */
  109.     dispbox.image.bytes_per_line = (dispbox.xwidth + 7) / 8;
  110.     buf_sz = dispbox.image.bytes_per_line * dispbox.yheight;
  111.   } else
  112.     buf_sz = dispbox.xwidth * dispbox.yheight;
  113.   /* test if the current buffer is adequate, else allocate or reallocate */
  114.   if( buf_sz > dispbox.data_size ) {
  115.     if( dispbox.image.data != NULL )
  116.       free( dispbox.image.data );
  117.     dispbox.image.data = calloc_errchk(buf_sz, sizeof(char), "Display image");
  118.     dispbox.data_size = buf_sz;
  119.   }
  120.   /* set the display coord system and propose new display parameters */
  121.   set_coordsys(&coord.disp, 0.5, (int)dispbox.width, (int)dispbox.height,
  122.            dispbox.xzero, dispbox.yzero,
  123.            dispbox.xzero + dispbox.xwidth - 1,
  124.            dispbox.yzero + dispbox.yheight - 1);
  125.   /* complete tdi parameters, must already have center and zoom */
  126.   set_tdisp(&coord);
  127. }
  128.  
  129. /*
  130.  * Subroutine:    init_imagebuf
  131.  * Purpose:    Allocate or reallocate main image buffer to fit img or as
  132.  *        much as allowed.  Also allocate file data buffer if data
  133.  *        cannot be read directly into i*2 buf.
  134.  * Returns:    1 on success, else 0.
  135.  * Post-state:    buffer.load_filebuf set to 0 if alloc's failed.
  136.  * Method:    Try to allocate enough for entire given image subsection.
  137.  *        If the display is to be rotated, make the short buf square
  138.  *        or double (whichever is less).
  139.  * Parameters:
  140.  *    buffer:        i/o: record structure for imaging buffers
  141.  *    coord.img:    i: coordinate system of image or image subsection
  142.  *    coord.buf:    o: coordinate system of short integer image buffer
  143.  */
  144. static char imgbuf_error[] =
  145.   "Unable to allocate sufficient memory for requested image.\n";
  146. int init_imagebuf ()
  147. {
  148.   int width, height;
  149.   int img_sz, buf_sz;
  150.   int shortbuf_double = 0;
  151.   int shortbuf_square = 0;
  152.   int did_alloc = 0;
  153.   char *calloc_errchk();
  154.   void set_coordsys();
  155.  
  156.   /* calculate buffer size, use img if within limit, else use limit */
  157.   width = coord.img.width;
  158.   height = coord.img.height;
  159.   img_sz = width * height;
  160.   /* if image is to be rotated 90% (aspect ratio changed) */
  161.   if( img.rotate_code & 1 ) {
  162.     /* make short buffer square or double for rotation algorithm */
  163.     buf_sz = SQR(MAX(width, height));
  164.     if( buf_sz > (2 * img_sz) ) {
  165.       buf_sz = 2 * img_sz;
  166.       shortbuf_double = 1;
  167.     } else
  168.       shortbuf_square = 1;
  169.   } else
  170.     buf_sz = img_sz;
  171.   /* buf_sz is in shorts, img_sz will now be in bytes (as is filebuf_sz) */
  172.   img_sz *= img.bytepix;
  173.   /* free filebuf if unique and inadequate, or unneeded */
  174.   if( buffer.filebuf == (char *)buffer.shortbuf ) {
  175.     buffer.filebuf = NULL;
  176.     buffer.filebuf_sz = 0;
  177.   } else if( (buffer.filebuf != NULL) &&
  178.          ((img.bytepix <= 2) || (img_sz > buffer.filebuf_sz)) ) {
  179.     free( buffer.filebuf );
  180.     buffer.filebuf = NULL;
  181.     buffer.filebuf_sz = 0;
  182.   }
  183.   /* check the adequacy of current short integer image buf */
  184.   if( buf_sz > buffer.shortbuf_sz ) {
  185.     if( buffer.shortbuf != NULL )
  186.       free( (char *)buffer.shortbuf );
  187.     buffer.shortbuf = (short *)calloc_errchk(buf_sz, sizeof(short), NULL);
  188.     if( buffer.shortbuf == 0 ) {
  189.       /* if failed, clear the slate, report error, and continue */
  190.       buffer.shortbuf_sz = 0;
  191.       if( buffer.filebuf != NULL ) {
  192.     free( buffer.filebuf );
  193.     buffer.filebuf = NULL;
  194.     buffer.filebuf_sz = 0;
  195.       }
  196.       (void)fprintf(stderr, imgbuf_error);
  197.       buffer.load_filebuf = 0;
  198.       return( 0 );
  199.     }
  200.     buffer.shortbuf_sz = buf_sz;
  201.     did_alloc = 1;
  202.   }
  203.   /* check on file data buf (if it still exists, it must be adequate) */
  204.   if( buffer.filebuf == NULL ) {
  205.     if( img.bytepix > 2 ) {
  206.       /* force worst case allignment */
  207.       buffer.filebuf = calloc_errchk((img_sz + 7) / 8, 8, NULL);
  208.       if( buffer.filebuf == NULL ) {
  209.     /* if failed, clear the slate, report error, and continue */
  210.     buffer.filebuf_sz = 0;
  211.     free( (char *)buffer.shortbuf );
  212.     buffer.shortbuf = NULL;
  213.     buffer.shortbuf_sz = 0;
  214.     fputs (imgbuf_error, stderr);
  215.     buffer.load_filebuf = 0;
  216.     return( 0 );
  217.       }
  218.       buffer.filebuf_sz = img_sz;
  219.       did_alloc++;
  220.     } else {
  221.       /* no special input buffer needed */
  222.       buffer.filebuf = (char *)buffer.shortbuf;
  223.       /* shortbuf_sz is shorts, filebuf_sz is bytes */
  224.       buffer.filebuf_sz = buffer.shortbuf_sz * sizeof(short);
  225.     }
  226.   }
  227.   /* note rotation space status */
  228.   buffer.shortbuf_double = shortbuf_double;
  229.   buffer.shortbuf_square = shortbuf_square;
  230.   /* set basic buffer coord system parameters (fill buffer) */
  231.   set_coordsys(&coord.buf, 0.5, width, height, 0, 0, width - 1, height - 1);
  232.   /* flag that buffer must be loaded */
  233.   coord.buferror = 1;
  234.   buffer.load_filebuf = 1;
  235.   /* report buffer size */
  236.   if( control.verbose && did_alloc ) {
  237.     (void)printf("Reserved %d x %d image data buffer", width, height);
  238.     if( did_alloc > 1 )
  239.       (void)printf("s.\n");
  240.     else
  241.       (void)printf(".\n");
  242.   }
  243.   return( 1 );
  244. }
  245.