############################################################################ # # File: pgmtoims.icn # # Subject: Program to make an image from a PGM file # # Author: Gregg M. Townsend # # Date: May 23, 1996 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # Usage: pgmtoims [-gn] [file] # # Pgmtoims reads a PGM rawbits file and writes an Icon image string. # The "-gn" option (2 <= n <= 64) selects the palette; g41 is the # default. # # Note that only rawbits-format PGM files can be read. # ############################################################################ # # Requires: Version 9 graphics # ############################################################################ # # Links: options # ############################################################################ link options procedure main(args) local opts, g, cs, f, w, h, maxv, data, s, i, n, ln # Process options. opts := options(args, "g+") g := \opts["g"] | 41 if g < 2 | g > 64 | *args > 1 then stop("usage: ", &progname, " [-gn] [file]") # Select the set of image characters according to the palette. cs := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz{}" cs := cs[1+:g] # Open the file and read it into memory. if *args = 1 then f := open(args[1], "ru") | stop("can't open ", args[1]) else f := &input s := "" while s ||:= reads(f, 1000) # Crack the file header. s ? { ws() if ="P" & any('1346') then stop("input is not in PGM format; convert via \"ppmtopgm\"") if ="P2" then stop("input is not in *raw* PGM format") if not ="P5" then stop("input is not a PGM file") ws() w := tab(many(&digits)) # image width ws() h := tab(many(&digits)) # image height ws() maxv := tab(many(&digits)) # maximum byte value in input tab(any(' \t\r\n')) data := tab(0) # image data } # Calculate the translation from input to output data bytes. s := "" every i := 0 to maxv do s ||:= cs[1 + (g * i) / (maxv + 1)] # Figure out a reasonable line length for output, # assuming not too many backslashes. n := 79 > w / seq(1) if w % n > 0 then n +:= 1 # Translate the data a line at a time, and write. map(data, &cset, s) ? { write("\"", w, ",g", g, ",_") while not pos(0) do wdata(move(w) | tab(0), n) write("\"") } end # wdata(s, n) -- write one line of data with max linelength n procedure wdata(s, n) s ? while not pos(0) do write(image(move(n) | tab(0)) [2:-1], "_") return end # ws() -- skip whitespace. procedure ws() while tab(many(' \t\r\n')) | (="#" & tab(upto('\n'))) return end