include include include include include "rastoim.h" procedure t_rastoim () .help Convert an eight bit Sun rasterfile image to one or two IRAF (OIF or STF) images or a single group format STF file with three images. These images may be used as input to the 'celco' task (in the 'stsdas.vdisplay' package on VMS IRAF only) to obtain photographic hard copy. Most likely, the rasterfile format image would come from the capture of a workstation window. However, they may also be converted from other popular image formats (GIF, TIFF, etc.) using host-level commands such as the PBM package. .ls Sun Rasterfile Format Rasterfiles are produced by many Sun applications (SunView, OpenWindows, etc., as well as third-party software) as well as general-purpose image-manipulation and format-conversion software. Rasterfiles may be 8 bits per pixel with or without a color map, or 24-bit RGB color composite. An 8-bit rasterfile may be standard (RT_STANDARD) or byte-encoded (RT_BYTE_ENCODED) -- either will be converted. Byte-encoded images are compressed using a simple run-length encoding. Images containing areas of constant color, such as presentation graphics, benefit most from such compression. Most "real pictures", including astronomical images do not. Full-color (24-bit) images are not compressed. Bitmaps, one bit rasterfiles, are not converted. If such an image is recognized, an error message will be printed and the task will terminate. This capability is planned as an enhancement to this task. Rasterfile images may contain a colormap or palette. This specifies the color to display for each gray value stored in the one-byte pixel values. The color is specified as three one-bute values representing the range of brightness of red, green, and blue. Some rasterfiles have short colormaps -- that is, fewer than 256 colors. In this case, the output colormap will still have 256 colors, but the excess values will be zero (black), but this doesn't matter, since these colors should not be referenced in the image. See Chapter 6 in the Sun "Pixrect Reference Manual." My copy is dated 9 May 1988. It seems to be a bit out of date since there's no discussion of 24-bit images. I don't know of a more recent reference. .le .ls Colormap If the rasterfile contains a colormap (8-bit files only) and the 'outcmap' parameter specifies a file name (i.e., it is not null), the colormap is written as an IRAF image. This output colormap is a two-dimensional image consisting of three lines and the number of pixels in the rasterfile colormap. The maximum range of colormap values (0:255) is scaled to the range 0:1 in the floating point output colormap image. No output colormap file is created if the input rasterfile has no colormap, if the 'outcmap' parameter is null, if the 'gray' parameter is yes, indicating to convert the RGB colors to gray values, or if the input rasterfile is 24-bit color composite. To use the output colormap image with the celco task, it must be an STF (.hhh) image. Explicitly include the extension or use imtype=".hhh" in the cl. .le .ls Color to Gray Optionally, the color palette (map) may be converted to gray values in the output image. In this case, no output colormap image is created. The gray values are computed from the RGB using the NTSC formula: .nf gray = 0.299*red + 0.587*green + 0.114*blue .fi .le .ls Full Color Images This task will recognize 24-bit rasterfiles and create a color-separated image. The output image must specify an STF (".hhh") image since the task will create a "group-format" image (a single physical file containing multiple images, analagous to the FITS group format extension), containing three images, representing the red, green, and blue channels of the rasterfile. If the 'gray' parameter is yes, then only a single image will be created, containing pixel values mapped from the colors as above. .le The output short integer pixel image has the same dimensions as the rasterfile. Rasterfiles have the origin (pixel 1,1) at the top left, while IRAF images have the origin at the lower left. To flip the image, use the 'flip' parameter (the default is "yes"). .ls Verbose Output Some explanatory text may be written to STDOUT if desired. The 'verbosity' parameter specifies which information is written: .nf verbosity text --------- ---- 0 none 1 image size 2 image name, depth, colormap size 3 colormap values .fi .le This task should be fully portable. It does not depend on Sun libraries. .endhelp # 6/10/91 Added code to force the min and max pixel to 0 and 255, # respectively. This kludges a bug in the Celco code that causes the # image to stretch, resulting in a mismatch between the image and the # color map. ZGL # 12/21/92 Generalize to rasterfiles having odd-length # colormaps and rasters. Use mii and read the whole file into # memory. # 12/23/92 Modified grasbyt() to simply get the next pixel from the # input buffer. Prevent access to output colormap image if no input # colormap specified. Make sure the header min and max parameters are # correct. # 1/4/93 Add option to convert RGB from colormap to gray levels # (using NTSC formula) with no output colormap file. # 1/8/93 Add option to preserve RGB composite (24-bit) images by # writing multi-group (STF) image. # Next, recognize 1-bit images (true bitmaps) and possibly do color # quantization. pointer sp pointer rasfile # Raster file name pointer rf # Raster file descriptor pointer outimg # Output image file name pointer outcmap # Output colormap file name int width, height # Image size int depth # Image depth (bits per pixel) int length # Data size int type # Raster file type int maptype # Color map type int maplength # Map size bool flip # Flip the image vertically? bool gray # Convert RGB to gray? int verbosity # Verbosity of output short dmin, dmax int pmin[2], pmax[2] int bytsiz, chsiz, nch int totsiz pointer rs, rb bool clgetb() int open(), clgeti(), read(), miipksize() begin call smark (sp) call salloc (rasfile, SZ_FNAME, TY_CHAR) call salloc (outimg, SZ_FNAME, TY_CHAR) call salloc (outcmap, SZ_FNAME, TY_CHAR) # Get task parameters call clgstr ("rasfile", Memc[rasfile], SZ_FNAME) call clgstr ("outimg", Memc[outimg], SZ_FNAME) call clgstr ("outcmap", Memc[outcmap], SZ_FNAME) # Flags flip = clgetb ("flip") verbosity = clgeti ("verbosity") gray = clgetb ("gray") if (gray && Memc[outcmap] != EOS) { Memc[outcmap] = EOS call eprintf ("Warning: Converting RGB to gray, no output colormap\n") } if (verbosity > 1) { call eprintf ("# %s --> %s\n") call pargstr (Memc[rasfile]) call pargstr (Memc[outimg]) } # Open the rasterfile rf = open (Memc[rasfile], READ_ONLY, BINARY_FILE) # Read the header -- fixed, eight ints call rashead (rf, width, height, length, depth, type, maptype, maplength, verbosity) # Full file size (color map + pixels, excluding header) # In chars -- the number of chars to read totsiz = maplength + length bytsiz = ((totsiz - 1) / 2 + 1) * 2 chsiz = miipksize (bytsiz, MII_BYTE) call calloc (rb, chsiz, TY_CHAR) call calloc (rs, bytsiz, TY_SHORT) # Read the colormap and image nch = read (rf, Memc[rb], chsiz) if (verbosity > 2) { call eprintf ("# Read %d chars\n") call pargi (nch) } # Unpack mii into shorts call miiupk (Memc[rb], Mems[rs], bytsiz, MII_BYTE, TY_SHORT) switch (depth) { case 8: # Write the pixel image call piximg (Mems[rs+maplength], type, length, flip, Memc[outimg], width, height, gray, Mems[rs], maplength, dmin, dmax, pmin, pmax) case 24: # 24-bit RGB if (Memc[outcmap] != EOS) { Memc[outcmap] = EOS call eprintf ("Warning: 24-bit RGB image; no colormap output\n") } call ri_rgbim (Mems[rs+maplength], length, flip, Memc[outimg], width, height, gray) } if (Memc[outcmap] != EOS && maplength > 0) { # Write the colormap image call cmapimg (Mems[rs], maptype, Memc[outcmap], maplength, verbosity) # Kludge the image and map to force maximum dynamic range so # celco doesn't go nuts. call fiximg (Memc[outimg], Memc[outcmap], dmin, dmax, pmin, pmax) } call sfree (sp) end procedure rashead (rf, width, height, length, depth, type, maptype, maplength, verbosity) # Read the rasterfile header (8 ints) pointer rf # Raster file descriptor int width, height # Image size int length # Data size int depth # Image depth (bits per pixel) int type # Raster file type int maptype # Color map type int maplength # Map size int verbosity # Verbosity of output pointer sp pointer rh # Rasterfile header descriptor int read() begin call smark (sp) call salloc (rh, SZ_RASHEAD, TY_INT) # Read the header (8 ints), filling the header structure if (read (rf, Memi[rh], SZ_RASHEAD*SZ_INT) != SZ_RASHEAD*SZ_INT) call error (0, "Can't read rasterfile header") if (RAS_MAGIC(rh) != RF_MAGIC_NUM) call error (0, "Not a rasterfile") width = RAS_WIDTH(rh) height = RAS_HEIGHT(rh) type = RAS_TYPE(rh) if (RAS_DEPTH(rh) == 1) call error (0, "We can't handle bitmaps yet") if (RAS_DEPTH(rh) == 24 && RAS_TYPE(rh) != RT_STANDARD) call error (0, "24 bit images assumed to be standard (not run-length encoded") if (RAS_TYPE(rh) == RT_OLD) # Compute the file size length = RAS_WIDTH(rh) * RAS_HEIGHT(rh) * RAS_DEPTH(rh) / 8 else length = RAS_LENGTH(rh) depth = RAS_DEPTH(rh) maptype = RAS_MAPTYPE(rh) maplength = RAS_MAPLENGTH(rh) if (verbosity > 0) { call eprintf ("# %d x %d File size %d\n") call pargi (width) call pargi (height) call pargi (length) call eprintf ("# Depth %d, Raster type %d\n") call pargi (depth) call pargi (type) call eprintf ("# Map type %d, size %d\n") call pargi (maptype) call pargi (maplength) } end procedure rasmap (incm, outcm, maplength) # Rescale a sigle color of the input colormap and write it to the # output colormap buffer as reals scaled 0:1. short incm[ARB] # Single color of input colormap real outcm[ARB] # Single color of output colormap int maplength # Map size (single color) int elem int nelem begin nelem = min (maplength, OUTCM_SIZE) do elem = 1, maplength { # Get the colormap element by element outcm[elem] = real (incm[elem]) / real (CMAP_MAX) } end procedure prtmap (red, green, blue, size) real red[ARB], green[ARB], blue[ARB] int size int i begin do i = 1, size { call printf ("%5d%5d%5d%5d\n") call pargi (i) call pargi (int (255.0 * red[i])) call pargi (int (255.0 * green[i])) call pargi (int (255.0 * blue[i])) } call flush (STDOUT) end procedure rldcode (raspix, ip, length, sect, width, height) # Decode a byte-encoded (run-length encoded) rasterfile # (RT_BYTE_ENCODED). A description of byte-encoding is in the Sun # Pixrect Reference Manual, section 6.1. The output buffer is the # entire image since a run may wrap around an image line. short raspix[ARB] # Rasterfile pixels pointer ip # (Byte) Index into rasterfile pixel buffer int length # Data size short sect[ARB] # Image section int width, height # Image size short run # Run length short val # Pixel value int pix # Pixel number in line int i int npix #int line short grasbyt() define ESC 128 begin npix = width * height pix = 0 repeat { val = grasbyt (raspix, ip) if (val == ESC) { val = grasbyt (raspix, ip) if (val == 0) { # Single in image pix = pix + 1 sect[pix] = ESC } else if (val == 1) { # in image val = grasbyt (raspix, ip) pix = pix + 1 sect[pix] = ESC pix = pix + 1 sect[pix] = ESC } else { # () run = val + 1 val = grasbyt (raspix, ip) do i = 1, run { pix = pix + 1 sect[pix] = val } } } else { # Not encoded pix = pix + 1 sect[pix] = val } if (pix > npix) return } until (ip > length) end procedure stdcode (raspix, ip, line, width) # Read a line of an unencoded (RT_STANDARD) rasterfile. short raspix[ARB] # Rasterfile pixels pointer ip # Index into rasterfile pixel buffer short line[ARB] # Image line pixels int width # Size of image lines int pix # Pixel number in line short grasbyt() begin do pix = 1, width line[pix] = grasbyt (raspix, ip) # Lines padded to 16 bit boundaries if (mod (width, 2) != 0) # Skip the last byte on the line ip = ip + 1 end short procedure grasbyt (raspix, ip) # Get the next byte from a short buffer short raspix[ARB] int ip short val begin val = raspix[ip] ip = ip + 1 return (val) end procedure cmapimg (cmap, maptype, cmapname, maplength, verbosity) # Read the colormap in a rasterfile and write the colormap image file. short cmap[ARB] # Color map int maptype # Color map type char cmapname[ARB] # Output colormap file name int maplength # Total colormap size (all colors) int verbosity # Output verosity pointer cm # Output image descriptor int onecol # Size of one colormap color (maplength/3) pointer red, green, blue # Colormap lines int roff, goff, boff # Offsets of each color vector into colormap pointer impl2r(), immap() begin if (maptype == RMT_NONE) { if (maplength != 0) call error (0, "Invalid colormap length") return } else if (maptype == RMT_RAW) call error (0, "We can't handle raw colormaps -- yet") else if (maptype != RMT_EQUAL_RGB) call error (0, "Invalid colormap type") onecol = maplength / 3 # Map the colormap image cm = immap (cmapname, NEW_FILE, 0) # Header stuff IM_NDIM(cm) = 2 IM_LEN(cm, 1) = OUTCM_SIZE IM_LEN(cm, 2) = 3 IM_PIXTYPE(cm) = TY_REAL # Each color red = impl2r (cm, 1) green = impl2r (cm, 2) blue = impl2r (cm, 3) call aclrr (Memr[red], OUTCM_SIZE) call aclrr (Memr[green], OUTCM_SIZE) call aclrr (Memr[blue], OUTCM_SIZE) roff = 1 goff = onecol + 1 boff = 2 * onecol + 1 # Scale the colormap one color at a time call rasmap (cmap[roff], Memr[red], onecol) call rasmap (cmap[goff], Memr[green], onecol) call rasmap (cmap[boff], Memr[blue], onecol) if (verbosity > 2) # Print the colormap call prtmap (Memr[red], Memr[green], Memr[blue], onecol) # Force the data range 0:1 call updnxh (cm, 0.0, 1.0) # Close the colormap image call imunmap (cm) end procedure piximg (pixels, type, length, flip, outimg, width, height, gray, cmap, maplength, dmin, dmax, pmin, pmax) # Read the pixels in a rasterfile and write the pixel image file. short pixels[ARB] # Rasterfile pixels int type # Raster file type int length # Data size bool flip # Flip the image vertically? char outimg[ARB] # Output pixel image name int width, height # Image size bool gray # Convert RGB to gray? short cmap[ARB] # Colormap (3 vectors) int maplength # Total colormap size (all colors) short dmin, dmax int pmin[2], pmax[2] pointer om # Output image descriptor int l1, l2 # Limits on image lines to write int dl pointer lp, op # Image line buffer pointer ip # Offset into rasterfile pointer line # Image line int onecol # Size of one colormap color (maplength/3) int roff, goff, boff # Offsets of each color vector into colormap pointer imgl2s(), impl2s(), immap(), imps2s() begin # Open the output pixel image om = immap (outimg, NEW_IMAGE, 0) # Header stuff IM_NDIM(om) = 2 IM_LEN(om, 1) = width IM_LEN(om, 2) = height IM_PIXTYPE(om) = TY_SHORT if (flip) { # Flip the image vertically l1 = height l2 = 1 dl = -1 } else { # Don't flip l1 = 1 l2 = height dl = 1 } onecol = maplength / 3 roff = 1 goff = onecol + 1 boff = 2 * onecol + 1 dmin = MAX_SHORT dmax = -MAX_SHORT ip = 1 if (type == RT_BYTE_ENCODED) { lp = imps2s (om, 1, width, l1, l2) # Expand the runs call rldcode (pixels, ip, length, Mems[lp], width, height) call imunmap (om) # Reopen the image so we can get the min, max om = immap (outimg, READ_WRITE, 0) do line = l1, l2, dl { # Each image line if (gray && maplength > 0) { # Convert RGB from map into gray lp = imgl2s (om, line) op = impl2s (om, line) call rgbmgray (Mems[lp], Mems[op], width, cmap[roff], cmap[goff], cmap[boff], onecol) } else op = imgl2s (om, line) call mnmxpx (Mems[op], width, line, dmin, dmax, pmin, pmax) call poutln (line, height, flip) } } else if (type == RT_STANDARD) { do line = l1, l2, dl { # Each image line lp = impl2s (om, line) # MOve the pixels to the output line call stdcode (pixels, ip, Mems[lp], width) if (gray && maplength > 0) # Convert RGB from map into gray call rgbmgray (Mems[lp], Mems[lp], width, cmap[roff], cmap[goff], cmap[boff], onecol) call mnmxpx (Mems[lp], width, line, dmin, dmax, pmin, pmax) call poutln (line, height, flip) } } call eprintf ("\n") # Close the image call imunmap (om) end procedure rgbmgray (inimage, outimage, imsize, red, green, blue, cmsize) # rgbmgray -- convert RGB pixel values from index into colormap to gray # using the NTSC formula. short inimage[ARB] # Input image pixels (index into map) short outimage[ARB] # Output image pixels (index into map) int imsize # Image size short red[ARB], green[ARB], blue[ARB] # Color map int cmsize # Map size short px real r, g, b int i begin do i = 1, imsize { px = inimage[i] + 1 r = real (red[px]) g = real (green[px]) b = real (blue[px]) outimage[i] = short (NTSC_RED_F * r + NTSC_GRN_F * g + NTSC_BLU_F * b) } end procedure mnmxpx (dline, npix, ln, dmin, dmax, pmin, pmax) short dline[ARB] # Data line int npix # Number of pixels in line int ln # Line number short dmin, dmax # Data min and max int pmin[2], pmax[2] # Coordinates of min and max int pix short val begin do pix = 1, npix { val = dline[pix] if (val < dmin) { dmin = val pmin[1] = pix pmin[2] = ln } if (val > dmax) { dmax = val pmax[1] = pix pmax[2] = ln } } end procedure poutln (line, height, flip) pointer line # Image line int height # Image size bool flip # Flip image top to bottom? int perc begin if (flip) perc = (100 * (height - line + 1)) / height else perc = (100 * line) / height call eprintf ("# Line %4d/%d %3d%%\r") call pargi (line) call pargi (height) call pargi (perc) call flush (STDERR) end procedure fiximg (outimg, outcmap, dmin, dmax, pmin, pmax) char outimg[ARB] # Output pixel image name char outcmap[ARB] # Output colormap file name pointer om # Image descriptor pointer cm # Colormap descriptor pointer icp, ocp pointer ip short dmin, dmax int pmin[2], pmax[2] pointer immap(), imps2s(), imgs2r(), imps2r() begin # Map the image om = immap (outimg, READ_WRITE, 0) # Map the colormap cm = immap (outcmap, READ_WRITE, 0) # Force the min and max pixel to 0:255 icp = imgs2r (cm, 1, 256, 1, 3) ocp = imps2r (cm, 1, 256, 1, 3) call fixcmap (Memr[icp], Memr[ocp], 256, 3, dmin, dmax) ip = imps2s (om, pmin[1], pmin[1], pmin[2], pmin[2]) Mems[ip] = 0 ip = imps2s (om, pmax[1], pmax[1], pmax[2], pmax[2]) Mems[ip] = 255 # Force the data range 0:255 in the header call updnxh (om, 0.0, 255.0) call updnxh (cm, 0.0, 1.0) call eprintf ("# Min: %d [%d,%d] --> 0, Max: %d [%d,%d] --> 255\n") call pargs (dmin) call pargi (pmin[1]) call pargi (pmin[2]) call pargs (dmax) call pargi (pmax[1]) call pargi (pmax[2]) # Close the images call imunmap (om) call imunmap (cm) end procedure updnxh (im, dmin, dmax) pointer im # Image descriptor real dmin, dmax # Data range begin IM_MIN(im) = dmin IM_MAX(im) = dmax # Update the header IM_LIMTIME(im) = IM_MTIME(im) + 1 end procedure fixcmap (icmap, ocmap, np, nc, dmin, dmax) real icmap[np,nc] real ocmap[np,nc] int np, nc short dmin, dmax begin # call eprintf ("# Min\tMax\n") # call eprintf ("# In: %d %d %d\t%d %d %d\n") # call pargi (int (ocmap[1,1] * 255.0)) # call pargi (int (ocmap[1,2] * 255.0)) # call pargi (int (ocmap[1,3] * 255.0)) # call pargi (int (ocmap[256,1] * 255.0)) # call pargi (int (ocmap[256,2] * 255.0)) # call pargi (int (ocmap[256,3] * 255.0)) call amovr (icmap, ocmap, np*nc) ocmap[1,1] = icmap[dmin+1,1] ocmap[1,2] = icmap[dmin+1,2] ocmap[1,3] = icmap[dmin+1,3] ocmap[256,1] = icmap[dmax+1,1] ocmap[256,2] = icmap[dmax+1,2] ocmap[256,3] = icmap[dmax+1,3] call eprintf ("# %d %d %d\t\t %d %d %d\n") call pargi (int (ocmap[1,1] * 255.0)) call pargi (int (ocmap[1,2] * 255.0)) call pargi (int (ocmap[1,3] * 255.0)) call pargi (int (ocmap[256,1] * 255.0)) call pargi (int (ocmap[256,2] * 255.0)) call pargi (int (ocmap[256,3] * 255.0)) end procedure ri_rgbim (pixels, length, flip, outimg, width, height, gray) # Read the pixels in a rasterfile and write the pixel image file. short pixels[ARB] # Rasterfile pixels int length # Data size bool flip # Flip the image vertically? char outimg[ARB] # Output pixel image name int width, height # Image size bool gray # Convert RGB to gray? pointer sp pointer red, green, blue pointer rim, gim, bim pointer om # Output image descriptor int l1, l2 # Limits on image lines to write int dl pointer lp # Image line buffer pointer ip # Offset into rasterfile pointer line # Image line pointer rlin, glin, blin # Image line pointer junk pointer impl2s(), immap() begin call smark (sp) if (flip) { # Flip the image vertically l1 = height l2 = 1 dl = -1 } else { # Don't flip l1 = 1 l2 = height dl = 1 } ip = 1 if (gray) { # Combine colors to gray # Open the output pixel image om = immap (outimg, NEW_IMAGE, 0) # Header stuff IM_NDIM(om) = 2 IM_LEN(om, 1) = width IM_LEN(om, 2) = height IM_PIXTYPE(om) = TY_SHORT ip = 1 do line = l1, l2, dl { # For each (output) image line # Get an image line lp = impl2s (om, line) # Convert the raster scan line to the image line call rgbcgray (pixels, ip, Mems[lp], width) call poutln (line, height, flip) } call updnxh (om, 0.0, 255.0) call imunmap (om) } else { # Maintain color separation in output # Need three groups call salloc (red, SZ_FNAME, TY_CHAR) call salloc (green, SZ_FNAME, TY_CHAR) call salloc (blue, SZ_FNAME, TY_CHAR) call strcpy (outimg, Memc[red], SZ_FNAME) call strcat ("[1/3]", Memc[red], SZ_FNAME) call strcpy (outimg, Memc[green], SZ_FNAME) call strcat ("[2]", Memc[green], SZ_FNAME) call strcpy (outimg, Memc[blue], SZ_FNAME) call strcat ("[3]", Memc[blue], SZ_FNAME) # Open the red image rim = immap (Memc[red], NEW_IMAGE, 0) # Header stuff IM_NDIM(rim) = 2 IM_LEN(rim, 1) = width IM_LEN(rim, 2) = height IM_PIXTYPE(rim) = TY_SHORT # Set the image characteristics call imaddb (rim, "bytepack", false) call imaddi (rim, "bytenax", 2) call imaddi (rim, "bytenax1", width) call imaddi (rim, "bytenax2", height) call imaddi (rim, "nimgrps", 3) call imaddi (rim, "ngrgrps", 0) # Dummy write to establish the pixel file junk = impl2s (rim, 1) call updnxh (rim, 0.0, 255.0) # Close it to clean up call imunmap (rim) # Reopen them group by group to update the min and max call strcpy (outimg, Memc[red], SZ_FNAME) call strcat ("[1]", Memc[red], SZ_FNAME) gim = immap (Memc[green], NEW_IMAGE, 0) call updnxh (gim, 0.0, 255.0) call imunmap (gim) bim = immap (Memc[blue], NEW_IMAGE, 0) call updnxh (bim, 0.0, 255.0) call imunmap (bim) rim = immap (Memc[red], READ_WRITE, 0) gim = immap (Memc[green], READ_WRITE, 0) bim = immap (Memc[blue], READ_WRITE, 0) ip = 1 do line = l1, l2, dl { # For each (output) image line # Get an image line rlin = impl2s (rim, line) glin = impl2s (gim, line) blin = impl2s (bim, line) # Convert the raster scan line to the image line call rgbdcode (pixels, ip, Mems[rlin], Mems[glin], Mems[blin], width) call poutln (line, height, flip) } call imunmap (bim) call imunmap (gim) call imunmap (rim) } call eprintf ("\n") end procedure rgbdcode (raspix, ip, rline, gline, bline, width) # Read a line of a 24 bit, unencoded (RT_STANDARD) rasterfile. short raspix[3,ARB] # Rasterfile pixels pointer ip # Index into rasterfile pixel buffer short rline[ARB] # Image line pixels short gline[ARB] # Image line pixels short bline[ARB] # Image line pixels int width # Size of image lines int pix # Pixel number in line begin do pix = 1, width { rline[pix] = raspix[1,ip] gline[pix] = raspix[2,ip] bline[pix] = raspix[3,ip] ip = ip + 1 } # Lines padded to 16 bit boundaries if (mod (width, 2) != 0) # Skip the last byte on the line ip = ip + 1 end procedure rgbcgray (inimage, ip, outimage, imsize) # rgbcgray -- convert RGB pixel values to gray using the NTSC formula. short inimage[3,ARB] # Input RGB image pixels int ip # Index into input image short outimage[ARB] # Output gray image pixels int imsize # Image size int px real r, g, b begin do px = 1, imsize { r = real (inimage[1,ip]) g = real (inimage[2,ip]) b = real (inimage[3,ip]) outimage[px] = short (NTSC_RED_F * r + NTSC_GRN_F * g + NTSC_BLU_F * b) ip = ip + 1 } end