Go Job Hunting at the LQ Job Marketplace
Go Back > Blogs > SourceHorse
User Name


Rate this Entry

A random selection from Ghostscript 9.05

Posted 04-01-2012 at 10:55 AM by SourceHorse
Updated 04-01-2012 at 10:57 AM by SourceHorse (correct order of lines 4 and 5)

 _______    |\_
| o   o |   /o \\
| o   o |  (_. ||
| o   o |   /__\\
'-------'   )___(

The Source Horse
Article 1
A random selection from Ghostscript 9.05
Introducing The Source Horse: a trail log of free program execution paths. Like architecture, programming should be done with great care. This will be about reading programs, not writing them. I will start with ghostscript. Ghostscript is a portable implementation of PostScript, written in C. Postscript is a well-documented Forth-based DSL for graphical output [1]. Normally I would trace from program invokation to the execution of a code listing. This time I will skip that because of the complexity of tracing through multiple languages, virtual machines, and deeply nested preprocessor macros. As the documentation states, this is "for sophisticated developers only" [2].

I will begin by downloading the source code for ghostscript 9.05 [3]. The base, contrib, lib, psi, and toolbin directories remain after excluding the bundled 3rd party libraries. I selected a file at random and found base/gdevbjcl.c. This contains code for Canon BubbleJet printers. I selected a line at random and found the bjc_put_command() function. The code is listed below.

static void
bjc_put_hi_lo(stream *s, int value)
    spputc(s, value >> 8);
    spputc(s, value & 0xff);

static void
bjc_put_command(stream *s, int ch, int count)
    spputc(s, 033 /*ESC*/);
    spputc(s, '(');
    spputc(s, ch);
    bjc_put_lo_hi(s, count);
The style is consistent and it resembles K&R C. I like the 4 space indentation. A comment heading classifies these as utility functions. They are small and easy to analyze. They can be refactored into the following 5 line listing.

1    spputc(s, 033 /*ESC*/);
2    spputc(s, '(');
3    spputc(s, ch);
4    spputc(s, count >> 8);
5    spputc(s, count & 0xff);
The bjc_put_command() function is not used outside of base/gdevbcl.c. The listing depends on the following user-defined types and functions:
  • stream type, defined in base/stream.h
  • spputc function, defined in base/stream.c

The output resembles ANSI [4], but it is BJL. BJL is a proprietary Canon printer language that has been reverse engineered by programmers [5]. Each command contains the following bytes in order.
  • 1 byte ESC -- corresponds to line 1
  • 2 byte command -- corresponds to line 2 and 3
  • 2 byte data size -- corresponds to line 4 and 5
  • 0 to n byte data -- data portion absent from the listing

Paraphrased in plain English, bjc_put_command() sends the control portion of a Canon BJL command to an output stream. Later, spputc() or bjc_put_bytes() sends the data portion. Below is an example of typical bjc_put_command() usage.

    bjc_put_command(s, 'F', count);
    bjc_put_bytes(s, data, count);
According to the Git repository, bjc_put_command() has not changed since 1999 [6]. Older versions can be found in the Debian archives [7]. The older source code style is less consistent, but is easy enough to follow.

In ghostscript 5.10, the file gdevupd.c contains BJL, as shown in the excerpt below.

    fputc(ESC,        out);
    fputc('(',        out);
    fputc('e',        out);
    fputc(2,          out);
    fputc(0,          out);
    fputc(HIGH(1),    out);
    fputc(LOW(1),     out);
In ghostscript 3.33, the file gdevbj10.c contains BJL, as shown in the excerpt below.

			fprintf(prn_stream, "\033[g%c%c%c",
				count & 0xff, count >> 8, mode);
That is it for now. Happy traces,

The Source Horse







Posted in Uncategorized
Views 298 Comments 0
« Prev     Main     Next »
Total Comments 0




All times are GMT -5. The time now is 02:10 PM.

Main Menu

Write for LQ is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration