aboutsummaryrefslogtreecommitdiff
path: root/pkg/dataio/import/bltins
diff options
context:
space:
mode:
authorJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
committerJoseph Hunkeler <jhunkeler@gmail.com>2015-07-08 20:46:52 -0400
commitfa080de7afc95aa1c19a6e6fc0e0708ced2eadc4 (patch)
treebdda434976bc09c864f2e4fa6f16ba1952b1e555 /pkg/dataio/import/bltins
downloadiraf-linux-fa080de7afc95aa1c19a6e6fc0e0708ced2eadc4.tar.gz
Initial commit
Diffstat (limited to 'pkg/dataio/import/bltins')
-rw-r--r--pkg/dataio/import/bltins/README13
-rw-r--r--pkg/dataio/import/bltins/ipcmap.x76
-rw-r--r--pkg/dataio/import/bltins/ipgif.x883
-rw-r--r--pkg/dataio/import/bltins/ipras.x504
-rw-r--r--pkg/dataio/import/bltins/ipxwd.x188
-rw-r--r--pkg/dataio/import/bltins/mkpkg13
6 files changed, 1677 insertions, 0 deletions
diff --git a/pkg/dataio/import/bltins/README b/pkg/dataio/import/bltins/README
new file mode 100644
index 00000000..c15b9cfe
--- /dev/null
+++ b/pkg/dataio/import/bltins/README
@@ -0,0 +1,13 @@
+ This directory contains the source code for the 'builtin' formats
+converted with IMPORT. Here we implement three formats that require different
+levels of processing: the GIF format uses LZW compression and a colormap for
+pixel storage and requires the most work, Sun Rasterfiles have various formats
+that may require colormap application or RLE decoding, and lastly the X
+Window Dump format that fits the generic binary raster model with the exception
+of an 8-bit file with a colormap.
+ Because formats are defined in the data base the user is unaware of
+any special processing that occurs unless implementing a new format that
+requires partivular handling. In the case of colormap files the example of
+XWD can be followed and all that's needed is a routine to read the colormap
+from the image. 'Builtin' formats must, however, be declared in the source
+import$ipbuiltin.x to route execution to the format-specific code.
diff --git a/pkg/dataio/import/bltins/ipcmap.x b/pkg/dataio/import/bltins/ipcmap.x
new file mode 100644
index 00000000..ad44a7cf
--- /dev/null
+++ b/pkg/dataio/import/bltins/ipcmap.x
@@ -0,0 +1,76 @@
+include "../import.h"
+
+# IPCMAP.X -- Procedures for colormap application or lookup.
+
+
+# IP_GRAY_CMAP - Apply the colormap to an array of pixels and convert the
+# pixels to grayscale using the NTSC formula.
+
+procedure ip_gray_cmap (data, len, cmap)
+
+char data[ARB] #i pixel values
+int len #i how many of 'em
+pointer cmap #i colormap pointer
+
+int i
+short val, ip_gcmap_val()
+
+begin
+ do i = 1, len {
+ val = data[i] + 1
+ data[i] = ip_gcmap_val (val, cmap)
+ }
+end
+
+
+# IP_GCMAP_VAL - Apply the colormap to a single pixel and convert the
+# result to grayscale using the NTSC formula.
+
+short procedure ip_gcmap_val (pix, cmap)
+
+char pix #i pixel value
+pointer cmap #i colormap pointer
+
+short val
+
+begin
+ val = (R_COEFF * CMAP(cmap,IP_RED,pix) +
+ G_COEFF * CMAP(cmap,IP_GREEN,pix) +
+ B_COEFF * CMAP(cmap,IP_BLUE,pix))
+ return (val)
+end
+
+
+# IP_RGB_VAL - Given a grayscale value figure out what the requested color
+# component is from the colormap.
+
+short procedure ip_rgb_val (pix, cmap, color)
+
+char pix #i pixel value
+pointer cmap #i colormap pointer
+int color #i requested color
+
+short i, val
+
+begin
+ # Need to optimize this later... For now just compute the colormap
+ # grayscale values until we find a match and use the index.
+ i = 0
+ val = -1
+ while (val != pix && i <= 256) {
+ i = i + 1
+ val = (R_COEFF * CMAP(cmap,IP_RED,i) +
+ G_COEFF * CMAP(cmap,IP_GREEN,i) +
+ B_COEFF * CMAP(cmap,IP_BLUE,i))
+ }
+
+ switch (color) {
+ case IP_RED:
+ val = CMAP(cmap,IP_RED,i-1)
+ case IP_GREEN:
+ val = CMAP(cmap,IP_GREEN,i-1)
+ case IP_BLUE:
+ val = CMAP(cmap,IP_BLUE,i-1)
+ }
+ return (val)
+end
diff --git a/pkg/dataio/import/bltins/ipgif.x b/pkg/dataio/import/bltins/ipgif.x
new file mode 100644
index 00000000..a7394e18
--- /dev/null
+++ b/pkg/dataio/import/bltins/ipgif.x
@@ -0,0 +1,883 @@
+include "../import.h"
+
+
+# IPGIF.X - Source file for the GIF builtin format converter.
+
+
+# Define the GIF data structure
+define MAX_CODE_ENTRIES 4096 # because LZW has 12 bit max
+define SZ_GIFSTRUCT 35
+define SZ_GIFCODE 280
+define SZ_GIFEXTN 256
+define SZ_GIFSTACK (2*MAX_CODE_ENTRIES+2)
+define SZ_GIFCTAB (2*MAX_CODE_ENTRIES+2)
+
+define GIF_FD Memi[$1] # GIF file descriptor
+define GIF_WIDTH Memi[$1+1] # Screen width
+define GIF_HEIGHT Memi[$1+2] # Screen height
+define GIF_CP Memi[$1+3] # Colormap pointer
+define GIF_BITPIX Memi[$1+4] # Bits per pixel
+define GIF_COLRES Memi[$1+5] # Color resolution
+define GIF_BACKGROUND Memi[$1+6] # background color (unused?)
+define GIF_ASPECT Memi[$1+7] # Aspect ratio
+define GIF_IMNUM Memi[$1+8] # Image number
+define GIF_CMAP Memi[$1+9] # Global colormap (ptr)
+
+define GIF_EXTBP Memi[$1+10] # Extension buffer (ptr)
+define GIF_CODEP Memi[$1+11] # Code table buffer (ptr)
+define GIF_CTABP Memi[$1+12] # Code table (ptr)
+define GIF_STACKP Memi[$1+13] # Stack (ptr)
+define GIF_CURBIT Memi[$1+14] # Decoder var
+define GIF_LASTBIT Memi[$1+15] # Decoder var
+define GIF_DONE Memi[$1+16] # Decoder var
+define GIF_LASTBYTE Memi[$1+17] # Decoder var
+define GIF_ZERO_DATABLOCK Memi[$1+18] # Decoder var
+define GIF_SP Memi[$1+19] # stack pointer
+
+define GIF_CLEAR_CODE Memi[$1+20] # LZW clear code
+define GIF_END_CODE Memi[$1+21] # LZW end code
+define GIF_FIRST_CODE Memi[$1+22] # LZW decoder var
+define GIF_OLD_CODE Memi[$1+23] # LZW decoder var
+define GIF_MAX_CODE Memi[$1+24] # LZW free code
+define GIF_MAX_CODE_SIZE Memi[$1+25] # LZW upper limit
+define GIF_CODE_SIZE Memi[$1+26] # LZW current code size
+define GIF_SET_CODE_SIZE Memi[$1+27] # LZW input code size
+define GIF_FRESH Memi[$1+28] # LZW init var
+
+# The following are used for GIF89a only.
+define GIF_TRANSPARENT Memi[$1+30] # Transparent Color Index
+define GIF_DELAYTIME Memi[$1+31] # Delay time
+define GIF_INPUTFLAG Memi[$1+32] # User input flag
+define GIF_DISPOSAL Memi[$1+33] # Disposal Method
+
+# Array macros.
+define CODEBUF Memc[GIF_CODEP($1)+$2]
+define EXTBUF Memc[GIF_EXTBP($1)+$2]
+define CODETAB Memc[GIF_CTABP($1)+($2*MAX_CODE_ENTRIES)+$3]
+define STACK Memc[GIF_STACKP($1)+$2]
+
+#---------------------------------------------------------------------------
+
+define INTERLACE 040X # Image descriptor flags
+define LOCAL_COLORMAP 080X
+
+# Define the flags for the GIF89a extension blocks.
+define GE_PLAINTEXT 001X # Plain Text Extension
+define GE_APPLICATION 0FFX # Application Extension
+define GE_COMMENT 0FEX # Comment Extension
+define GE_GCONTROL 0F9X # Graphics Control Extension
+
+define DEBUG false
+define VDEBUG false
+
+
+# IP_GIF - Read and process a GIF format file into an IRAF image.
+
+procedure ip_gif (ip, fname, info_only, verbose)
+
+pointer ip #i import struct pointer
+char fname[ARB] #i file name
+int info_only #i print out image info only?
+int verbose #i verbosity flag
+
+pointer gif
+int fd
+int bitpix, use_global_cmap, interlace
+int width, height, version
+char ch
+short sig[7], screen[12]
+
+pointer gif_open()
+int btoi(), strncmp(), gif_rdbyte(), gif_getbytes()
+int shifti()
+
+long filepos
+common /gifcom/ filepos
+
+begin
+ # Allocate the gif struct pointer.
+ gif = gif_open()
+ GIF_FD(gif) = IP_FD(ip)
+ fd = GIF_FD(gif)
+
+ # The GIF signature is verified in the database file but check it
+ # here anyway.
+ filepos = 1
+ call ip_lseek (fd, BOF)
+ if (gif_getbytes(fd, sig, 6) != OK)
+ call error (0, "Error reading GIF magic number.")
+ if (strncmp(sig[4],"87a",3) == 0)
+ version = 87
+ else if (strncmp(sig[4],"89a",3) == 0)
+ version = 89
+ else
+ call error (0, "Bad version: File is not a GIF 87a or 89A")
+
+ # Now read the screen descriptor.
+ if (gif_getbytes(fd, screen, 7) != OK)
+ call error (0, "Error reading screen descriptor.")
+
+ GIF_WIDTH(gif) = screen[1] + (256 * screen[2])
+ GIF_HEIGHT(gif) = screen[3] + (256 * screen[4])
+ GIF_BITPIX(gif) = shifti (2, and(int(screen[5]),07X))
+ GIF_COLRES(gif) = shifti (and(int(screen[5]), 070X), -3) + 1
+ GIF_BACKGROUND(gif) = screen[6]
+ GIF_ASPECT(gif) = screen[7]
+ if (DEBUG) {
+ call eprintf ("w:%d h:%d bpix:%d ncol:%d bkg:%d asp:%d\n")
+ call pargi(GIF_WIDTH(gif)); call pargi(GIF_HEIGHT(gif))
+ call pargi(GIF_BITPIX(gif)); call pargi(GIF_COLRES(gif))
+ call pargi(GIF_BACKGROUND(gif)); call pargi(GIF_ASPECT(gif))
+ call flush (STDERR)
+ }
+
+ # We'll set the buffer size to the full image to speed processing.
+ IP_SZBUF(ip) = GIF_HEIGHT(gif)
+
+ # See if we have a global colormap.
+ if (and (int(screen[5]), LOCAL_COLORMAP) > 0)
+ call gif_rdcmap (gif, GIF_BITPIX(gif), GIF_CMAP(gif))
+ IP_CMAP(ip) = GIF_CMAP(gif)
+
+ # Now process the rest of the image blocks.
+ GIF_IMNUM(gif) = 0
+ repeat {
+ if (gif_rdbyte(fd, ch) != OK) {
+ call error (0, "Bad data read.")
+ }
+
+ if (ch == ';') { # GIF terminator
+ break
+ }
+
+ if (ch == '!') { # Extension block
+ # Read the extension function code.
+ if (gif_rdbyte(fd, ch) != OK)
+ call error (0, "Bad data read.")
+ call gif_extension (gif, ch, IP_VERBOSE(ip))
+ next
+ }
+
+ if (ch != ',') { # not a valid start character
+ if (ch != '\0') { # quietly allow a NULL block
+ call eprintf ("Ignoring bogus start char 0x%02x.")
+ call pargc (ch)
+ }
+ next
+ }
+
+ # Read the current image descriptor block. There may be more
+ # than one image in a file so we'll just copy each image into
+ # a separate band of the output image (should be rare).
+ GIF_IMNUM(gif) = GIF_IMNUM(gif) + 1
+ if (gif_getbytes (fd, screen, 9) != OK)
+ call error (0, "Bad scene descriptor")
+
+ # See if this image has a local colormap. There supposedly aren't
+ # a lot of files that use this (GIF89a only) but we'll read it
+ # anyway so we don't get stung on file positioning.
+ if (and (int(screen[9]), LOCAL_COLORMAP) == LOCAL_COLORMAP)
+ use_global_cmap = NO
+ else
+ use_global_cmap = YES
+
+ # Unpack the image descriptor into useful things.
+ bitpix = shifti (1, (and (int(screen[9]), 07X) + 1))
+ interlace = btoi (and (int(screen[9]), INTERLACE) == INTERLACE)
+ width = screen[5] + (screen[6] * 256)
+ height = screen[7] + (screen[8] * 256)
+ if (DEBUG) {
+ call eprintf ("global_cmap:%d bitpix:%d ")
+ call pargi(use_global_cmap); call pargi(bitpix)
+ call eprintf ("interlace:%d w:%d h:%d\n")
+ call pargi(interlace); call pargi(width); call pargi(height)
+ }
+
+ if (info_only == NO) {
+ if (use_global_cmap == NO) {
+ # Process the image with a local colormap.
+ call gif_rdcmap (gif, bitpix, GIF_CMAP(gif))
+ call gif_read_image (ip, gif, width, height,
+ GIF_CMAP(gif), interlace)
+ } else {
+ # Process the image with the global colormap.
+ call gif_read_image (ip, gif, width, height,
+ GIF_CMAP(gif), interlace)
+ }
+ } else {
+ call ip_gif_info (ip, fname, version, width, height,
+ GIF_BITPIX(gif), use_global_cmap, interlace, verbose)
+ break
+ }
+ }
+
+ # Clean up.
+ call gif_close (gif)
+ IP_CMAP(ip) = NULL
+end
+
+
+# IP_GIF_INFO - Print information about the GIF file.
+
+procedure ip_gif_info (ip, fname, version, width, height, colres, global,
+ interlace, verbose)
+
+pointer ip #i task struct pointer
+char fname[ARB] #i file name
+int version #i GIF version
+int width, height #i image dimensions
+int colres #i number of colormap entries
+int global #i image has global colormap
+int interlace #i image is interlaced
+int verbose #i verbosity flag
+
+begin
+ # If not verbose print a one-liner.
+ if (verbose == NO) {
+# call printf ("Input file:\n\t")
+ call printf ("%s: %20t%d x %d \t\tCompuServe GIF %da format file\n")
+ call pargstr (fname)
+ call pargi (width)
+ call pargi (height)
+ call pargi (version)
+
+ # Print out the format comment if any.
+# if (IP_COMPTR(ip) != NULL) {
+# if (COMMENT(ip) != '\0') {
+# call printf ("%s\n")
+# call pargstr (COMMENT(ip))
+# }
+# call strcpy ("\0", COMMENT(ip), SZ_LINE)
+# }
+ return
+ }
+
+ # Print a more verbose description.
+ call printf ("%s: %20tCompuServe GIF %da Format File\n")
+ call pargstr (fname)
+ call pargi (version)
+
+ # Print out the format comment if any.
+ if (IP_COMPTR(ip) != NULL) {
+ if (COMMENT(ip) != '\0') {
+ call printf ("%s\n")
+ call pargstr (COMMENT(ip))
+ }
+ call strcpy ("\0", COMMENT(ip), SZ_LINE)
+ }
+
+ call printf ("%20tResolution:%38t%d x %d\n")
+ call pargi (width)
+ call pargi (height)
+
+ call printf ("%20tPixel storage: %38t%s\n")
+ if (interlace == YES)
+ call pargstr ("Interlaced order")
+ else
+ call pargstr ("Sequential order")
+
+ call printf ("%20tByte Order: %38t%s\n")
+ call pargstr ("LSB first")
+
+ call printf ("%20tType: %38t%s\n")
+ call pargstr ("8-bit Color indexed")
+
+ call printf ("%20t%s Colormap: %38t%d entries\n")
+ if (global == YES)
+ call pargstr ("Global")
+ else
+ call pargstr ("Local")
+ call pargi (colres)
+
+ call printf ("%20tCompression: %38t%s\n")
+ call pargstr ("Lempel-Ziv and Welch (LZW)")
+end
+
+
+# GIF_OPEN - Open the GIF structure descriptor.
+
+pointer procedure gif_open ()
+
+pointer gif
+
+begin
+ iferr (call calloc (gif, SZ_GIFSTRUCT, TY_STRUCT))
+ call error (0, "Error allocating GIF structure.")
+
+ # Allocate the extension and code buffers.
+ iferr (call calloc (GIF_CODEP(gif), SZ_GIFCODE, TY_CHAR))
+ call error (0, "Error allocating GIF code buffer pointer.")
+ iferr (call calloc (GIF_EXTBP(gif), SZ_GIFEXTN, TY_CHAR))
+ call error (0, "Error allocating GIF extension pointer.")
+ iferr (call calloc (GIF_CTABP(gif), SZ_GIFCTAB, TY_CHAR))
+ call error (0, "Error allocating code table pointer.")
+ iferr (call calloc (GIF_STACKP(gif), SZ_GIFSTACK, TY_CHAR))
+ call error (0, "Error allocating GIF stack pointer.")
+
+ # Initialize some of the variables to non-zero values.
+ GIF_ZERO_DATABLOCK(gif) = NO
+ GIF_TRANSPARENT(gif) = -1
+ GIF_DELAYTIME(gif) = -1
+ GIF_INPUTFLAG(gif) = -1
+
+ return (gif)
+end
+
+
+# GIF_CLOSE - Close the GIF structure descriptor.
+
+procedure gif_close (gif)
+
+pointer gif #i GIF struct pointer
+
+begin
+ call mfree (GIF_STACKP(gif), TY_CHAR)
+ call mfree (GIF_CTABP(gif), TY_CHAR)
+ call mfree (GIF_EXTBP(gif), TY_CHAR)
+ call mfree (GIF_CODEP(gif), TY_CHAR)
+
+ if (GIF_CMAP(gif) != NULL)
+ call mfree (GIF_CMAP(gif), TY_CHAR)
+ call mfree (gif, TY_STRUCT)
+end
+
+
+# GIF_READ_IMAGE - Read the image raster from the file. Decompress the
+# LZW compressed data stream into 8-bit pixels.
+
+procedure gif_read_image (ip, gif, width, height, cmap, interlace)
+
+pointer ip #i task struct pointer
+pointer gif #i GIF struct pointer
+int width, height #i image dimensions
+pointer cmap #i colormap pointer
+int interlace #i interlace flag
+
+pointer im, op, out, data
+char csize, pix, val
+int i, v, xpos, ypos, pass
+int nlines, line, percent
+
+pointer ip_evaluate()
+int gif_rdbyte(), gif_lzw_rdbyte()
+short ip_gcmap_val()
+
+begin
+ # Get the initial code_size for the compression routines.
+ if (gif_rdbyte(GIF_FD(gif), csize) != OK)
+ call error (0, "EOF or read error on image data.")
+ call gif_lzw_init (gif, csize)
+
+ # Patch up the pixtype param if needed.
+ call ip_fix_pixtype (ip)
+
+ # See if we need to create any outbands operands if the user didn't.
+ if (IP_NBANDS(ip) == ERR)
+ call ip_fix_outbands (ip)
+
+ im = IP_IM(ip)
+ op = PTYPE(ip,GIF_IMNUM(gif))
+ call malloc (data, width, TY_CHAR)
+ IO_DATA(op) = data
+ IO_NPIX(op) = width
+
+ # Get the pixels.
+ xpos = 0
+ ypos = 0
+ pass = 0
+ nlines = 0
+ percent = 0
+ repeat {
+ v = gif_lzw_rdbyte (gif)
+ if (v < 0)
+ break # at the EOF
+ else {
+ if (cmap != NULL && IP_USE_CMAP(ip) == YES) {
+ # Apply the colormap since this is just an index.
+ val = v + 1
+ pix = ip_gcmap_val (val, cmap)
+ } else
+ pix = char (v)
+ Memc[data+xpos] = pix # assign the pixel
+ }
+
+ xpos = xpos + 1
+ if (xpos == width) {
+ xpos = 0
+ nlines = nlines + 1
+
+ # Evaluate outbands expression.
+ do i = 1, IP_NBANDS(ip) {
+ out = ip_evaluate (ip, O_EXPR(ip,i))
+
+ # Write bands to output image
+ if (IP_OUTPUT(ip) != IP_NONE) {
+ line = ypos + 1
+ call ip_wrline (ip, im, out, GIF_WIDTH(gif), line,
+ (GIF_IMNUM(gif)-1)*IP_NBANDS(ip)+i)
+ }
+ call evvfree (out)
+ }
+
+ # Print percent done if being verbose
+ if (IP_VERBOSE(ip) == YES) {
+ if (nlines * 100 / height >= percent + 10) {
+ percent = percent + 10
+ call printf (" Status: %2d%% complete\r")
+ call pargi (percent)
+ call flush (STDOUT)
+ }
+ }
+
+ # if the image is interlaced adjust the line number accordingly,
+ # otherwise just increment it.
+ if (interlace == YES) {
+ switch (pass) {
+ case 0, 1:
+ ypos = ypos + 8
+ case 2:
+ ypos = ypos + 4
+ case 3:
+ ypos = ypos + 2
+ }
+
+ if (ypos >= height) {
+ pass = pass + 1
+ switch (pass) {
+ case 1:
+ ypos = 4
+ case 2:
+ ypos = 2
+ case 3:
+ ypos = 1
+ }
+ }
+ } else {
+ # Non-interlaced GIF so just increment the line number.
+ ypos = ypos + 1
+ }
+ }
+ }
+
+ if (IP_VERBOSE(ip) == YES) {
+ call printf (" Status: Done \n")
+ call flush (STDOUT)
+ }
+
+ # Clean up the data pointer.
+ call mfree (data, TY_CHAR)
+end
+
+
+# GIF_RDCMAP - Read a colormap (local or global) from the GIF file.
+
+procedure gif_rdcmap (gif, ncolors, cmap)
+
+pointer gif #i GIF struct pointer
+int ncolors #i number of colors to read
+pointer cmap #u local or global colormap ptr
+
+int i
+char rgb[3]
+int gif_getbytes()
+
+begin
+ if (cmap == NULL)
+ iferr (call calloc (cmap, 3*CMAP_SIZE, TY_CHAR))
+ call error (0, "Error allocating color map.")
+
+ do i = 1, ncolors {
+ # Read RGB colors.
+ if (gif_getbytes (GIF_FD(gif), rgb, 3) != OK)
+ call error (0, "Bad GIF colormap - not enough colors.")
+
+ # Load the colormap.
+ CMAP(cmap,IP_RED,i) = rgb[1]
+ CMAP(cmap,IP_GREEN,i) = rgb[2]
+ CMAP(cmap,IP_BLUE,i) = rgb[3]
+ }
+end
+
+
+# GIF_EXTENSION - Process a GIF extension block. For now we'll just ignore
+# these when converting the image but read the data blocks anyway. We should
+# still be able to read the image but won't take advantage of the GIF89a
+# extensions.
+
+procedure gif_extension (gif, label, verbose)
+
+pointer gif #i Gif struct pointer
+char label #i GIF extension label
+int verbose #i print verbose info?
+
+pointer sp, buf
+int val
+int and(), gif_get_data_block()
+
+begin
+ call smark (sp)
+ call salloc (buf, SZ_GIFCODE, TY_CHAR)
+
+ switch (label) {
+ case GE_PLAINTEXT: # Plain Text Extension
+ if (verbose == YES) {
+ call eprintf ("Warning: Ignoring a Plain Text Extension.\n")
+ call flush (STDERR)
+ }
+ case GE_APPLICATION: # Application Extension
+ if (verbose == YES) {
+ call eprintf ("Warning: Ignoring an Application Extension.\n")
+ call flush (STDERR)
+ }
+ case GE_COMMENT: # Comment Extension
+ # Simply print out the comment.
+ while (gif_get_data_block (gif, Memc[buf]) != 0) {
+ if (verbose == YES) {
+ call printf ("Comment: %s\n")
+ call pargstr (Memc[buf])
+ }
+ }
+ call sfree (sp)
+ return
+ case GE_GCONTROL: # Graphic Control Extension
+ # Process the graphic control block.
+ val = gif_get_data_block (gif, Memc[buf])
+ GIF_DISPOSAL(gif) = and (int(Memc[buf]/4), 07X)
+ GIF_INPUTFLAG(gif) = and (int(Memc[buf]/2), 01X)
+ GIF_DELAYTIME(gif) = Memc[buf+1] + (256 * Memc[buf+2])
+ if (and(int(Memc[buf]),01X) == 1)
+ GIF_TRANSPARENT(gif) = Memc[buf+3]
+
+ while (gif_get_data_block (gif, Memc[buf]) != 0)
+ ;
+
+ call sfree (sp)
+ return
+ default:
+ call eprintf ("Warning: Unknown extension label (0x%02x).\n")
+ call pargc (label)
+ call flush (STDERR)
+ }
+
+ # If we get here then we've ignored an extension but still need to
+ # eat the data blocks.
+ while (gif_get_data_block (gif, Memc[buf]) != 0)
+ ;
+
+ call sfree (sp)
+end
+
+
+# GIF_LZW_INIT - Initialize the LZW decompression variables.
+
+procedure gif_lzw_init (gif, input_code_size)
+
+pointer gif #i GIF struct pointer
+char input_code_size #i input code size
+
+int i, shifti()
+
+begin
+ GIF_SET_CODE_SIZE(gif) = input_code_size
+ GIF_CODE_SIZE(gif) = GIF_SET_CODE_SIZE(gif) + 1
+ GIF_CLEAR_CODE(gif) = shifti (1, GIF_SET_CODE_SIZE(gif))
+ GIF_END_CODE(gif) = GIF_CLEAR_CODE(gif) + 1
+ GIF_MAX_CODE_SIZE(gif) = 2 * GIF_CLEAR_CODE(gif)
+ GIF_MAX_CODE(gif) = GIF_CLEAR_CODE(gif) + 2
+
+ GIF_CURBIT(gif) = 0 # initialize the code vars
+ GIF_LASTBIT(gif) = 0
+ GIF_DONE(gif) = NO
+
+ GIF_FRESH(gif) = YES
+
+ # Initialize the code table.
+ for (i = 0; i < GIF_CLEAR_CODE(gif); i=i+1) {
+ CODETAB(gif,0,i) = 0
+ CODETAB(gif,1,i) = i
+ }
+ for (; i < MAX_CODE_ENTRIES; i=i+1) {
+ CODETAB(gif,0,i) = 0
+ CODETAB(gif,1,0) = 0
+ }
+
+ GIF_SP(gif) = 0
+end
+
+
+
+# GIF_LZW_RDBYTE -
+
+int procedure gif_lzw_rdbyte (gif)
+
+pointer gif #i GIF struct pointer
+
+pointer sp, buf
+int i, count
+int code, incode
+
+int gif_get_code(), gif_get_data_block()
+
+begin
+ if (GIF_FRESH(gif) == YES) {
+ GIF_FRESH(gif) = NO
+ repeat {
+ GIF_OLD_CODE(gif) = gif_get_code (gif, GIF_CODE_SIZE(gif))
+ GIF_FIRST_CODE(gif) = GIF_OLD_CODE(gif)
+ } until (GIF_FIRST_CODE(gif) != GIF_CLEAR_CODE(gif))
+ return (GIF_FIRST_CODE(gif))
+ }
+
+ if (GIF_SP(gif) > 0) {
+ GIF_SP(gif) = GIF_SP(gif) - 1
+ return (STACK(gif,GIF_SP(gif)))
+ }
+
+ code = gif_get_code (gif, GIF_CODE_SIZE(gif))
+ while (code >= 0) {
+
+ # The Clear Code sets everything back to its initial value, then
+ # reads the immediately subsequent code as uncompressed data.
+ if (code == GIF_CLEAR_CODE(gif)) {
+ for (i = 0; i < GIF_CLEAR_CODE(gif); i=i+1) {
+ CODETAB(gif,0,i) = 0
+ CODETAB(gif,1,i) = i
+ }
+ for ( ; i < MAX_CODE_ENTRIES; i=i+1) {
+ CODETAB(gif,0,i) = 0
+ CODETAB(gif,1,i) = 0
+ }
+ GIF_CODE_SIZE(gif) = GIF_SET_CODE_SIZE(gif) + 1
+ GIF_MAX_CODE_SIZE(gif) = 2 * GIF_CLEAR_CODE(gif)
+ GIF_MAX_CODE(gif) = GIF_CLEAR_CODE(gif) + 2
+ GIF_SP(gif) = 0
+ GIF_OLD_CODE(gif) = gif_get_code (gif, GIF_CODE_SIZE(gif))
+ GIF_FIRST_CODE(gif) = GIF_OLD_CODE(gif)
+ return (GIF_FIRST_CODE(gif))
+
+ # If this is the End Code we'll clean up a little before returning.
+ } else if (code == GIF_END_CODE(gif)) {
+ if (GIF_ZERO_DATABLOCK(gif) == YES)
+ return (ERR)
+
+ call smark (sp)
+ call salloc (buf, 260, TY_CHAR)
+
+ repeat {
+ count = gif_get_data_block (gif, Memc[buf])
+ } until (count <= 0)
+
+ if (count != 0) {
+ call eprintf (
+ "Missing EOD in data stream (common occurance)")
+ }
+ call sfree (sp)
+ return (ERR)
+ }
+
+ # Must be data so save it in incode.
+ incode = code
+
+ # If it's greater or equal than the Free Code it's not in the hash
+ # table yet, repeat the last character decoded.
+ if (code >= GIF_MAX_CODE(gif)) {
+ STACK(gif, GIF_SP(gif)) = GIF_FIRST_CODE(gif)
+ GIF_SP(gif) = GIF_SP(gif) + 1
+ code = GIF_OLD_CODE(gif)
+ }
+
+ while (code >= GIF_CLEAR_CODE(gif)) {
+ STACK(gif, GIF_SP(gif)) = CODETAB(gif,1,code)
+ GIF_SP(gif) = GIF_SP(gif) + 1
+ if (code == CODETAB(gif,0,code))
+ call error (0, "Circular GIF code table entry.")
+ code = CODETAB(gif,0,code)
+ }
+
+ GIF_FIRST_CODE(gif) = CODETAB(gif,1,code)
+ STACK(gif, GIF_SP(gif)) = GIF_FIRST_CODE(gif)
+ GIF_SP(gif) = GIF_SP(gif) + 1
+
+ if (VDEBUG) {
+ call eprintf("code=%d gmax=%d gmaxsz=%d 4096 old:%d frst:%d\n")
+ call pargi(code) ; call pargi(GIF_MAX_CODE(gif))
+ call pargi(GIF_MAX_CODE_SIZE(gif))
+ call pargi(GIF_OLD_CODE(gif))
+ call pargi(GIF_FIRST_CODE(gif))
+ }
+
+ # Point to the next slot in the table. If we exceed the current
+ # MaxCode value, increment the code size unless it's already 12.
+ # If it is, do nothing: the next code decompressed better be CLEAR
+
+ code = GIF_MAX_CODE(gif)
+ if (code < MAX_CODE_ENTRIES) {
+ CODETAB(gif,0,code) = GIF_OLD_CODE(gif)
+ CODETAB(gif,1,code) = GIF_FIRST_CODE(gif)
+ GIF_MAX_CODE(gif) = GIF_MAX_CODE(gif) + 1
+ if ((GIF_MAX_CODE(gif) >= GIF_MAX_CODE_SIZE(gif)) &&
+ (GIF_MAX_CODE_SIZE(gif) < MAX_CODE_ENTRIES)) {
+ GIF_MAX_CODE_SIZE(gif) = GIF_MAX_CODE_SIZE(gif) * 2
+ GIF_CODE_SIZE(gif) = GIF_CODE_SIZE(gif) + 1
+ }
+ }
+
+ GIF_OLD_CODE(gif) = incode
+
+ if (GIF_SP(gif) > 0) {
+ GIF_SP(gif) = GIF_SP(gif) - 1
+ return (STACK(gif,GIF_SP(gif)))
+ }
+
+ code = gif_get_code (gif, GIF_CODE_SIZE(gif))
+ }
+ return code
+end
+
+
+# GIF_GET_CODE - Fetch the next code from the raster data stream. The codes
+# can be any length from 3 to 12 bits, packed into 8-bit bytes, so we have to
+# maintain our location in the Raster array as a BIT Offset. We compute the
+# byte Offset into the raster array by dividing this by 8, pick up three
+# bytes, compute the bit Offset into our 24-bit chunk, shift to bring the
+# desired code to the bottom, then mask it off and return it. Simple.
+
+int procedure gif_get_code (gif, code_size)
+
+pointer gif #i GIF struct pointer
+int code_size #i op code size
+
+int i, j, count, ret
+int val1, val2
+int btoi(), and(), shifti(), ori ()
+int gif_get_data_block()
+
+begin
+ # See if processing the next code will overflow our buffer. If so
+ # we get the next control block from the stream.
+ if ( (GIF_CURBIT(gif) + code_size) >= GIF_LASTBIT(gif)) {
+ if (GIF_DONE(gif) == YES) {
+ if (GIF_CURBIT(gif) >= GIF_LASTBIT(gif)) {
+ call error (0, "GIF_GET_CODE: Ran out of bits.\n")
+ return (ERR)
+ }
+ }
+
+ CODEBUF(gif,0) = CODEBUF(gif,GIF_LASTBYTE(gif)-2)
+ CODEBUF(gif,1) = CODEBUF(gif,GIF_LASTBYTE(gif)-1)
+
+ count = gif_get_data_block (gif, CODEBUF(gif,2))
+ if (count == 0)
+ GIF_DONE(gif) = YES
+
+ GIF_LASTBYTE(gif) = 2 + count
+ GIF_CURBIT(gif) = (GIF_CURBIT(gif) - GIF_LASTBIT(gif)) + 16
+ GIF_LASTBIT(gif) = (2 + count) * 8
+ }
+
+ # for (i = GIF_CURBIT(gif), j = 0; j < code_size; ++i, ++j)
+ # ret |= ((buf[ i / 8 ] & (1 << (i % 8))) != 0) << j;
+
+ i = GIF_CURBIT(gif)
+ j = 0
+ ret = 0
+ while (j < code_size) {
+ val1 = btoi ( and (int(CODEBUF(gif,i/8)), shifti(1,mod(i,8))) != 0 )
+ val2 = shifti (val1, j)
+ ret = ori (ret, val2)
+ i = i + 1
+ j = j + 1
+ }
+
+ GIF_CURBIT(gif) = GIF_CURBIT(gif) + code_size
+ if (VDEBUG) {
+ call eprintf (": returning %d\n");call pargi(ret);call flush(STDERR)
+ }
+
+ return (ret)
+end
+
+
+# GIF_GET_DATA_BLOCK - Get the next block of GIF data from the data stream so
+# it can be converted to raster data.
+
+int procedure gif_get_data_block (gif, buf)
+
+pointer gif #i GIF struct pointer
+char buf[ARB] #o data block
+
+char count
+int nb, btoi()
+int gif_rdbyte(), gif_getbytes()
+
+begin
+ if (gif_rdbyte (GIF_FD(gif), count) != OK) {
+ call error (0, "error in getting DataBlock size")
+ return (ERR)
+ }
+
+ GIF_ZERO_DATABLOCK(gif) = btoi (count == 0)
+ if (VDEBUG) {
+ call eprintf ("getDataBlock: count = %d "); call pargs(count) }
+ nb = count
+ if ((count != 0) && (gif_getbytes(GIF_FD(gif), buf, nb) != OK)) {
+ call error (0, "error in reading DataBlock")
+ return (ERR)
+ }
+ return count
+end
+
+
+
+# Byte I/O routines. We use the normal IMPORT procedures but localize the code
+# here to make it easier to keep track of the current file position (in bytes).
+
+# GIF_RDBYTE - Read a single byte at the current offset from the file.
+
+int procedure gif_rdbyte (fd, val)
+
+int fd #i file descriptor
+char val #o byte read
+
+short ip_getb()
+
+long filepos
+common /gifcom/ filepos
+
+begin
+ iferr (val = ip_getb (fd, filepos))
+ return (ERR)
+
+ filepos = filepos + 1
+ call ip_lseek (fd, filepos)
+
+ return (OK)
+end
+
+
+# GIF_GETBYTES - Read an array of bytes from the file at the current offset.
+
+int procedure gif_getbytes (fd, buffer, len)
+
+int fd #i file descriptor
+char buffer[ARB] #o output buffer
+int len #i no. of bytes to read
+
+pointer sp, bp
+
+long filepos
+common /gifcom/ filepos
+
+begin
+ call smark (sp)
+ call salloc (bp, len+1, TY_CHAR)
+ call aclrc (Memc[bp], len+1)
+
+ call ip_agetb (fd, bp, len) # read the bytes
+ call amovc (Memc[bp], buffer, len) # copy to output buffer
+ filepos = filepos + len
+ call ip_lseek (fd, filepos)
+
+ call sfree (sp)
+ return (OK)
+end
diff --git a/pkg/dataio/import/bltins/ipras.x b/pkg/dataio/import/bltins/ipras.x
new file mode 100644
index 00000000..100ca6dc
--- /dev/null
+++ b/pkg/dataio/import/bltins/ipras.x
@@ -0,0 +1,504 @@
+include <mach.h>
+include "../import.h"
+
+
+# IPRAS.X - Source file for the IMPORT task rasterfile builtin format.
+
+
+define SZ_RASHDR 13
+define RAS_MAGIC Memi[$1] # Magic number
+define RAS_WIDTH Memi[$1+1] # Image width (pixels per line)
+define RAS_HEIGHT Memi[$1+2] # Image height (number of lines)
+define RAS_DEPTH Memi[$1+3] # Image depth (bits per pixel)
+define RAS_LENGTH Memi[$1+4] # Image length (bytes)
+define RAS_TYPE Memi[$1+5] # File type
+define RAS_MAPTYPE Memi[$1+6] # Colormap type
+define RAS_MAPLENGTH Memi[$1+7] # Colormap length (bytes)
+
+define RAS_CMAP Memi[$1+10] # Colormap (ptr)
+define RAS_COUNT Memi[$1+11] # RLE decoding var
+define RAS_CH Memi[$1+12] # RLE decoding var
+
+# Rasterfile magic number
+define RAS_MAGIC_NUM 59A66A95X
+define RAS_RLE 80X
+
+# Sun supported ras_types
+define RT_OLD 0 # Raw pixrect image in 68000 byte order
+define RT_STANDARD 1 # Raw pixrect image in 68000 byte order
+define RT_BYTE_ENCODED 2 # Run-length compression of bytes
+define RT_FORMAT_RGB 3 # XRGB or RGB instead of XBGR or BGR
+define RT_FORMAT_TIFF 4 # tiff <-> standard rasterfile
+define RT_FORMAT_IFF 5 # iff (TAAC format) <-> standard rasterfile
+define RT_EXPERIMENTAL 65535 # Reserved for testing
+
+# Sun supported ras_maptypes
+define RMT_NONE 0 # ras_maplength is expected to be 0
+define RMT_EQUAL_RGB 1 # red[ras_maplength/3],green[],blue[]
+define RMT_RAW 2
+
+
+
+# IP_RAS - Read and process a Sun Rasterfile into an IRAF image.
+
+procedure ip_ras (ip, fname, info_only, verbose)
+
+pointer ip #i import struct pointer
+char fname[ARB] #i file name
+int info_only #i print out image info only?
+int verbose #i verbosity flag
+
+pointer ras
+int fd, w, nchars
+pointer ras_open()
+
+long filepos
+common /rascom/ filepos
+
+begin
+ # Allocate the ras struct pointer.
+ ras = ras_open ()
+ fd = IP_FD(ip)
+
+ # Initialize the file position.
+ filepos = 1
+ call ip_lseek (fd, BOF)
+
+ # Read in the rasterfile header, dump it directly to the task struct.
+ call ip_ageti (fd, ras, 8)
+ filepos = filepos + SZ_INT32 * SZB_CHAR * 8
+ call ip_lseek (fd, filepos)
+
+ # Now do some sanity checking on the values.
+ if (RAS_MAGIC(ras) != RAS_MAGIC_NUM)
+ call error (0, "Not a Sun rasterfile.")
+ if (RAS_TYPE(ras) == RT_OLD && RAS_LENGTH(ras) == 0)
+ RAS_LENGTH(ras) = RAS_WIDTH(ras) * RAS_HEIGHT(ras) *
+ RAS_DEPTH(ras) / 8
+
+ # See if we really want to convert this thing.
+ if (info_only == YES) {
+ call ip_ras_info (ip, ras, fname, verbose)
+ call ras_close (ras)
+ return
+ }
+
+ # Get the colormap (if any).
+ call ras_rdcmap (fd, ras, RAS_CMAP(ras))
+ IP_CMAP(ip) = RAS_CMAP(ras)
+
+ # Round up to account for 16 bit line blocking.
+ w = RAS_WIDTH(ras) * (RAS_DEPTH(ras) / 8)
+ nchars = w + mod (w, SZB_CHAR)
+
+
+ # Patch up the pixtype param if needed.
+ call ip_fix_pixtype (ip)
+
+ # See if we need to create any outbands operands if the user didn't.
+ if (IP_NBANDS(ip) == ERR)
+ call ip_fix_outbands (ip)
+
+ # Now process the image.
+ switch (RAS_DEPTH(ras)) {
+ case 1:
+ call eprintf ("Bitmap rasterfiles aren not supported.")
+ call flush (STDERR)
+
+ case 8:
+ # Standard or byte encoded 8-bit rasterfile.
+ if (RAS_TYPE(ras) == RT_OLD || RAS_TYPE(ras) == RT_STANDARD) {
+ call ip_prband (ip, fd, IP_IM(ip), RAS_CMAP(ras))
+
+ } else if (RAS_TYPE(ras) == RT_BYTE_ENCODED) {
+ call ras_rle8 (ip, ras, fd, nchars)
+
+ } else {
+ call eprintf ("Unsupported 8-bit RAS_TYPE: %d\n")
+ call pargi (RAS_TYPE(ras))
+ call flush (STDERR)
+ }
+
+ case 24, 32:
+ # 24 or 32-bit rasterfiles have no colormap (at least they
+ # shouldn't) and are pixel-interleaved. We already know how to
+ # do this so just call the right routines for processing.
+
+ if (RAS_TYPE(ras) == RT_BYTE_ENCODED) {
+ call ip_fix_pixtype (ip)
+ call ras_rle24 (ip, ras, fd, nchars)
+ } else {
+ call ip_fix_pixtype (ip)
+ call ip_prpix (ip, fd, IP_IM(ip), NULL)
+ }
+
+ default:
+ call eprintf ("Invalid pixel size.")
+ call flush (STDERR)
+ }
+
+ # Clean up.
+ call ras_close (ras)
+ IP_CMAP(ip) = NULL
+end
+
+
+# IP_RAS_INFO - Print information about the raster file.
+
+procedure ip_ras_info (ip, ras, fname, verbose)
+
+pointer ip #i ip struct pointer
+pointer ras #i ras struct pointer
+char fname[ARB] #i file name
+int verbose #i verbosity flag
+
+begin
+ # If not verbose print a one-liner.
+ if (verbose == NO) {
+# call printf ("Input file:\n\t")
+ call printf ("%s: %20t%d x %d \t\t%d-bit Sun Rasterfile\n")
+ call pargstr (fname)
+ call pargi (RAS_WIDTH(ras))
+ call pargi (RAS_HEIGHT(ras))
+ call pargi (RAS_DEPTH(ras))
+
+ # Print out the format comment if any.
+# if (IP_COMPTR(ip) != NULL) {
+# if (COMMENT(ip) != '\0') {
+# call printf ("%s\n")
+# call pargstr (COMMENT(ip))
+# }
+# call strcpy ("\0", COMMENT(ip), SZ_LINE)
+# }
+# if (RAS_DEPTH(ras) > 8) {
+# if (RAS_TYPE(ras) != RT_FORMAT_RGB && RAS_TYPE(ras) != RT_OLD) {
+# call eprintf ("\tNote: %d-bit rasterfile is stored as %s\n")
+# call pargi (RAS_DEPTH(ras))
+# call pargstr ("ABGR and not ARGB")
+# }
+# }
+ return
+ }
+
+ # Print a more verbose description.
+ call printf ("%s: %20tSun Rasterfile\n")
+ call pargstr (fname)
+
+ # Print out the format comment if any.
+ if (IP_COMPTR(ip) != NULL) {
+ if (COMMENT(ip) != '\0') {
+ call printf ("%s\n")
+ call pargstr (COMMENT(ip))
+ }
+ call strcpy ("\0", COMMENT(ip), SZ_LINE)
+ }
+ if (RAS_DEPTH(ras) > 8) {
+ if (RAS_TYPE(ras) != RT_FORMAT_RGB && RAS_TYPE(ras) != RT_OLD) {
+ call eprintf ("\tNote: %d-bit rasterfile is stored as %s\n")
+ call pargi (RAS_DEPTH(ras))
+ call pargstr ("ABGR and not ARGB")
+ }
+ }
+
+ call printf ("%20tByte Order:%38t%s\n")
+ if (IP_SWAP(ip) == S_NONE && BYTE_SWAP2 == NO )
+ call pargstr ("Most Significant Byte First")
+ else
+ call pargstr ("Least Significant Byte First")
+
+ call printf ("%20tResolution:%38t%d x %d\n")
+ call pargi (RAS_WIDTH(ras))
+ call pargi (RAS_HEIGHT(ras))
+
+ call printf ("%20tType: %38t%d-bit %s %s\n")
+ call pargi (RAS_DEPTH(ras))
+ switch (RAS_TYPE(ras)) {
+ case RT_OLD:
+ call pargstr ("Old")
+ case RT_STANDARD:
+ call pargstr ("Standard")
+ case RT_BYTE_ENCODED:
+ call pargstr ("Byte Encoded")
+ case RT_FORMAT_RGB:
+ call pargstr ("RGB")
+ case RT_FORMAT_TIFF:
+ call pargstr ("TIFF")
+ case RT_FORMAT_IFF:
+ call pargstr ("IFF")
+ default:
+ call pargstr ("Experimental (or unknown)")
+ }
+ if (RAS_MAPLENGTH(ras) > 0)
+ call pargstr ("Color Index")
+ else
+ call pargstr ("")
+
+ if (RAS_MAPLENGTH(ras) > 0) {
+ call printf ("%20tColormap:%38t%d entries\n")
+ if (RAS_MAPTYPE(ras) == RMT_EQUAL_RGB)
+ call pargi (RAS_MAPLENGTH(ras)/3)
+ else
+ call pargi (RAS_MAPLENGTH(ras))
+ } else
+ call printf ("%20tColormap:%38tnone\n")
+
+ call printf ("%20tCompression: %38t%s\n")
+ if (RAS_TYPE(ras) == RT_BYTE_ENCODED)
+ call pargstr ("Run Length Encoded")
+ else
+ call pargstr ("None")
+
+ call printf ("%20tAlpha Channel: %38t%s\n")
+ if (RAS_DEPTH(ras) == 32)
+ call pargstr ("yes")
+ else
+ call pargstr ("none")
+end
+
+
+# RAS_OPEN - Open the RAS structure descriptor.
+
+pointer procedure ras_open ()
+
+pointer ras
+
+begin
+ iferr (call calloc (ras, SZ_RASHDR, TY_STRUCT))
+ call error (0, "Error allocating RAS structure.")
+ RAS_CMAP(ras) = NULL
+
+ return (ras)
+end
+
+
+# RAS_CLOSE - Close the RAS structure descriptor.
+
+procedure ras_close (ras)
+
+pointer ras #i RAS struct pointer
+
+begin
+ if (RAS_CMAP(ras) != NULL)
+ call mfree (RAS_CMAP(ras), TY_CHAR)
+ call mfree (ras, TY_STRUCT)
+end
+
+
+# RAS_RDCMAP - Read the colormap from the image if necessary.
+
+procedure ras_rdcmap (fd, ras, cmap)
+
+int fd #i file descriptor
+pointer ras #i RAS struct pointer
+pointer cmap #i colormap array ptr
+
+int ncolors
+
+long filepos
+common /rascom/ filepos
+
+begin
+ # Now read the colormap, allocate the pointer if we need to.
+ ncolors = RAS_MAPLENGTH(ras)
+ if (RAS_MAPTYPE(ras) == RMT_EQUAL_RGB && ncolors > 0) {
+ if (cmap == NULL)
+ call calloc (cmap, ncolors*3, TY_CHAR)
+ call ip_agetb (fd, cmap, ncolors)
+
+ } else if (RAS_MAPTYPE(ras) == RMT_RAW) {
+ call eprintf ("Warning: Can't handle RMT_RAW maptype - ignoring.\n")
+ call flush (STDERR)
+
+ # Skip over the bytes anyway.
+ filepos = filepos + ncolors
+ call ip_lseek (fd, filepos)
+ return
+ }
+
+ filepos = filepos + ncolors
+ call ip_lseek (fd, filepos)
+end
+
+
+# RAS_RLE8 - Process an 8-bit rasterfile into an IRAF image. This
+# procedure handles both standard and RLE files.
+
+procedure ras_rle8 (ip, ras, fd, nchars)
+
+pointer ip #i ip struct pointer
+pointer ras #i ras struct pointer
+int fd #i input file descriptor
+int nchars #i line size
+
+pointer im, data, op
+int i, percent
+
+long filepos
+common /rascom/ filepos
+
+begin
+ im = IP_IM(ip)
+ op = PTYPE(ip,1)
+ call malloc (data, nchars, TY_CHAR)
+ IO_DATA(op) = data
+ IO_NPIX(op) = RAS_WIDTH(ras)
+
+ percent = 0
+ do i = 1, RAS_HEIGHT(ras) {
+ call ras_read_rle (ras, fd, Memc[data], nchars)
+
+ # Apply the colormap since this is just an index.
+ if (RAS_MAPLENGTH(ras) != 0 && IP_USE_CMAP(ip) == YES)
+ call ip_gray_cmap (Memc[data], RAS_WIDTH(ras),
+ RAS_CMAP(ras))
+
+ # Evaluate and write the outbands expressions.
+ call ip_probexpr (ip, im, RAS_WIDTH(ras), i)
+
+ # Print percent done if being verbose
+ if (IP_VERBOSE(ip) == YES) {
+ if (i * 100 / RAS_HEIGHT(ras) >= percent + 10) {
+ percent = percent + 10
+ call printf (" Status: %2d%% complete\r")
+ call pargi (percent)
+ call flush (STDOUT)
+ }
+ }
+
+ }
+
+ if (IP_VERBOSE(ip) == YES) {
+ call printf (" Status: Done \n")
+ call flush (STDOUT)
+ }
+end
+
+
+# RAS_RLE24 - Process an 24-bit rasterfile into an IRAF image. This
+# procedure handles both standard and RLE files.
+
+procedure ras_rle24 (ip, ras, fd, nchars)
+
+pointer ip #i ip struct pointer
+pointer ras #i ras struct pointer
+int fd #i input file descriptor
+int nchars #i line size
+
+pointer im, data, op
+int i, percent, npix
+
+long filepos
+common /rascom/ filepos
+
+begin
+ im = IP_IM(ip)
+ op = PTYPE(ip,1)
+ call malloc (data, nchars, TY_SHORT)
+ IO_DATA(op) = data
+ IO_NPIX(op) = RAS_WIDTH(ras)
+
+ # See if we need to create any outbands operands if the user didn't.
+ if (IP_NBANDS(ip) == ERR)
+ call ip_fix_outbands (ip)
+
+ # Allocate the pixtype data pointers.
+ npix = RAS_WIDTH(ras)
+ do i = 1, IP_NPIXT(ip) {
+ op = PTYPE(ip,i)
+ IO_NPIX(op) = npix
+ call calloc (IO_DATA(op), npix, TY_SHORT)
+ }
+
+ percent = 0
+ do i = 1, RAS_HEIGHT(ras) {
+ call ras_read_rle (ras, fd, Memc[data], nchars)
+
+ # Separate pixels into different vectors.
+ call ip_upkpix (ip, data, npix)
+
+ # Evaluate and write the outbands expressions.
+ call ip_probexpr (ip, im, npix, i)
+
+ # Print percent done if being verbose
+ if (IP_VERBOSE(ip) == YES) {
+ if (i * 100 / RAS_HEIGHT(ras) >= percent + 10) {
+ percent = percent + 10
+ call printf (" Status: %2d%% complete\r")
+ call pargi (percent)
+ call flush (STDOUT)
+ }
+ }
+
+ }
+ if (IP_VERBOSE(ip) == YES) {
+ call printf (" Status: Done \n")
+ call flush (STDOUT)
+ }
+end
+
+
+# RAS_READ_RLE - Read a line of RLE encoded data from the file.
+
+procedure ras_read_rle (ras, fd, data, nchars)
+
+pointer ras #i ras struct pointer
+int fd #i file descriptor
+char data[ARB] #u output pixels
+int nchars #i number of pixels to read
+
+int i
+short pix, ras_rdbyte()
+
+long filepos
+common /rascom/ filepos
+
+begin
+ i = 1
+ while (i <= nchars) {
+ if (RAS_COUNT(ras) > 0) {
+ data[i] = RAS_CH(ras)
+ i = i + 1
+ RAS_COUNT(ras) = RAS_COUNT(ras) - 1
+
+ } else {
+ pix = ras_rdbyte (fd)
+ if (pix == RAS_RLE) {
+ RAS_COUNT(ras) = ras_rdbyte (fd)
+ if (RAS_COUNT(ras) == 0) {
+ data[i] = pix
+ i = i + 1
+ } else {
+ RAS_CH(ras) = ras_rdbyte (fd)
+ data[i] = RAS_CH(ras)
+ i = i + 1
+ }
+ } else {
+ data[i] = pix
+ i = i + 1
+ }
+ }
+ }
+end
+
+
+# RAS_RDBYTE - Read a single byte at the current offset from the file.
+
+short procedure ras_rdbyte (fd)
+
+int fd #i file descriptor
+
+short val
+short ip_getb()
+
+long filepos
+common /rascom/ filepos
+
+begin
+ iferr (val = ip_getb (fd, filepos))
+ return (ERR)
+
+ filepos = filepos + 1
+ call ip_lseek (fd, filepos)
+
+ return (val)
+end
diff --git a/pkg/dataio/import/bltins/ipxwd.x b/pkg/dataio/import/bltins/ipxwd.x
new file mode 100644
index 00000000..62a48ff7
--- /dev/null
+++ b/pkg/dataio/import/bltins/ipxwd.x
@@ -0,0 +1,188 @@
+# IPXWD.X - Source file for the IMPORT task X Window Dump builtin format.
+
+include <mach.h>
+include "../import.h"
+
+
+# IP_XWD - Read and process an X Window Dump into an IRAF image.
+
+procedure ip_xwd (ip, fname, info_only, verbose)
+
+pointer ip #i import struct pointer
+char fname[ARB] #i file name
+int info_only #i print out image info only?
+int verbose #i verbosity flag
+
+int fd
+pointer im, cmap
+int nchars
+long depth, cmap_entries, hdr_size
+long hskip, lpad, width,height
+
+long ip_getl()
+
+begin
+ # Get the input file descriptor and initialize the file position.
+ fd = IP_FD(ip)
+ im = IP_IM(ip)
+ call ip_lseek (fd, BOF)
+
+ # Get some information from the header we'll need for processing.
+ hdr_size = ip_getl (fd, 1)
+ width = IP_AXLEN(ip,1)
+ height = IP_AXLEN(ip,2)
+ depth = ip_getl (fd, 45)
+ hskip = IP_HSKIP(ip)
+ lpad = IP_LPAD(ip)
+ cmap_entries = ip_getl (fd, 73)
+ nchars = width + lpad
+
+ # See if we really want to convert this thing.
+ if (info_only == YES) {
+ call ip_xwd_info (ip, fname, depth, cmap_entries, verbose)
+ return
+ }
+
+ # Now process the image. For 24-bit or 32-bit files we have an RGB
+ # image and can process normally, if this is an 8-bit image see if
+ # we have a colormap we need to use.
+
+ if (depth > 8) {
+ call ip_prpix (ip, fd, im, NULL)
+ } else {
+ cmap = NULL
+ if (cmap_entries > 0)
+ call xwd_rdcmap (ip, fd, hdr_size, cmap_entries, cmap)
+ call ip_prband (ip, fd, im, cmap)
+ }
+ IP_CMAP(ip) = NULL
+end
+
+
+# IP_XWD_INFO - Print information about the xwd file.
+
+procedure ip_xwd_info (ip, fname, depth, ncolors, verbose)
+
+pointer ip #i ip struct pointer
+char fname[ARB] #i file name
+int depth #i bits per pixel
+int ncolors #i number of colors
+int verbose #i verbosity flag
+
+begin
+ # If not verbose print a one-liner.
+ if (verbose == NO) {
+ #call printf ("Input file:\n\t")
+ call printf ("%s: %20t%d x %d \t%d-bit X11 Window Dump\n")
+ call pargstr (fname)
+ call pargi (IP_AXLEN(ip,1))
+ call pargi (IP_AXLEN(ip,2))
+ call pargi (depth)
+
+ # Print out the format comment if any.
+ if (IP_COMPTR(ip) != NULL) {
+ if (COMMENT(ip) != '\0') {
+ call printf ("%s\n")
+ call pargstr (COMMENT(ip))
+ }
+ call strcpy ("\0", COMMENT(ip), SZ_LINE)
+ }
+ return
+ }
+
+ # Print a more verbose description.
+ call printf ("%s: %20tX11 Window Dump\n")
+ call pargstr (fname)
+
+ # Print out the format comment if any.
+ if (IP_COMPTR(ip) != NULL) {
+ if (COMMENT(ip) != '\0') {
+ call printf ("%s\n")
+ call pargstr (COMMENT(ip))
+ }
+ call strcpy ("\0", COMMENT(ip), SZ_LINE)
+ }
+
+ call printf ("%20tByte Order:%38t%s\n")
+ if (IP_SWAP(ip) == S_NONE && BYTE_SWAP2 == NO )
+ call pargstr ("Most Significant Byte First")
+ else
+ call pargstr ("Least Significant Byte First")
+
+ call printf ("%20tResolution:%38t%d x %d\n")
+ call pargi (IP_AXLEN(ip,1))
+ call pargi (IP_AXLEN(ip,2))
+
+ call printf ("%20tType: %38t%d-bit %s\n")
+ call pargi (depth)
+ if (ncolors > 0)
+ call pargstr ("Color Index")
+ else
+ call pargstr ("")
+
+ call printf ("%20tHeader size:%38t%d bytes\n")
+ call pargi (IP_HSKIP(ip))
+
+ if (ncolors > 0) {
+ call printf ("%20tColormap:%38t%d entries\n")
+ call pargi (ncolors)
+ } else
+ call printf ("%20tColormap:%38tnone\n")
+
+ call printf ("%20tAlpha Channel: %38t%s\n")
+ if (depth == 32)
+ call pargstr ("8-bit")
+ else
+ call pargstr ("none")
+end
+
+
+# XWD_RDCMAP - Read colormap from an X11 Window Dump file and return a
+# pointer to it.
+
+procedure xwd_rdcmap (ip, fd, hdr_size, ncolors, cmap)
+
+pointer ip #i task struct pointer
+int fd #i file descriptor
+int hdr_size #i header size
+int ncolors #i number of colormap entries
+pointer cmap #i colormap pointer
+
+int i
+long filepos, pixel
+int r, g, b
+char flags, pad
+
+short ip_getb()
+int ip_getu()
+long ip_getl()
+
+define SZ_X11_CSTRUCT 12
+
+begin
+ # Now read the colormap, allocate the pointer if we need to.
+ cmap = NULL
+ if (ncolors == 0)
+ return
+ else
+ call calloc (cmap, CMAP_SIZE*3, TY_CHAR)
+
+ filepos = hdr_size + 3
+ call ip_lseek (fd, filepos)
+ do i = 1, ncolors {
+ pixel = ip_getl (fd, filepos)
+ r = ip_getu (fd, filepos+4)
+ g = ip_getu (fd, filepos+6)
+ b = ip_getu (fd, filepos+8)
+ flags = ip_getb (fd, filepos+10)
+ pad = ip_getb (fd, filepos+11)
+
+ CMAP(cmap,IP_RED,i) = r * 255 / 65535
+ CMAP(cmap,IP_GREEN,i) = g * 255 / 65535
+ CMAP(cmap,IP_BLUE,i) = b * 255 / 65535
+
+ filepos = filepos + SZ_X11_CSTRUCT
+ call ip_lseek (fd, filepos)
+ }
+ IP_CMAP(ip) = cmap
+end
diff --git a/pkg/dataio/import/bltins/mkpkg b/pkg/dataio/import/bltins/mkpkg
new file mode 100644
index 00000000..88c4cadb
--- /dev/null
+++ b/pkg/dataio/import/bltins/mkpkg
@@ -0,0 +1,13 @@
+# Mkpkg file for building the IMPORT task builtin formats.
+
+$checkout libpkg.a ../
+$update libpkg.a
+$checkin libpkg.a ../
+$exit
+
+libpkg.a:
+ ipcmap.x ../import.h
+ ipgif.x ../import.h
+ ipras.x ../import.h <mach.h>
+ ipxwd.x ../import.h <mach.h>
+ ;