summaryrefslogtreecommitdiff
path: root/support/pstools/cep/cep.awk
blob: 7360796e4bb1a8cba9beff91c364fee066f27fac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# This file belongs to the CEP package | Ten plik nale/zy do pakietu CEP
# This package is public domain        | Pakiet stanowi dobro powszechne
# For more info see `0CEP_LIC.ENG'     | Wi/ecej informacji w ,,0CEP_LIC.POL''
# ===========================================================================
# E: "Hex bitmap EPS" --> "filtered EPS" converter
#      input - input file name
#      OUTF  - output file name
#      CVM   - conversion method
#      TMPSX - temporary PostScript file name 
#
# P: Konwerter "Hex bitmap EPS" --> "filtered EPS"
#      wej/scie - nazwa pliku konwertowanego
#      OUTF     - nazwa pliku wyj/sciowego
#      CVM      - metoda konwersji EPS-a
#      TMPSX    - nazwa tymczasowego pliku PostScriptowego

BEGIN {
  ver_no=1.03
  gs_abort="2 2 .quit"
  RS="\015|\012|\015\012"
   # preparing temporary files | przygotowywanie plik/ow tymczasowych
  if (TMPSX=="") TMPSX="tmp.psx"
  if (CVM!~/[LlRrFfNn]/) CVM=CVM "R" # Default coding and compression method
  if (CVM!~/[Hh8]/) CVM=CVM "8"      # Domy/slna metoda kodowania i kompresji
  printf "CEP ver. " ver_no ", Coding:"
  if (is_A85()) printf " A85"
  if (is_HEX()) printf " Hex"
  if (is_LZW()) printf ", LZW"
  if (is_RLE()) printf ", RLE"
  if (is_ZIP()) printf ", Flate (non-standard in PostScript Level 2!)"
  print ""
  flag="pre"
}

 # searching for ``strange lines'' is due to the following problem:
 #   a single hex char in line or Postscript command "def" and "add" in prolog
 #   may be misunderstood for a HEX bitmap (see also ``heuristic trick'')
 # poszukiwanie ,,dziwnych wierszy'' wi/a/ze si/e z nast/epuj/acym problemem:
 #   pojedynczy znak w wierszu oraz instrukcje Postscriptu "def" i "add"
 #   stanowi/ace cz/e/s/c prologu mog/a zosta/c b/l/ednie uznane za 
 #   fragment szesnastkowej mapy bitowej (patrz ,,heurystyczny fortel'')

{is_hex_line=/^[0-9A-Fa-f]*$/
  if (flag=="hex") {
    if (is_hex_line) {hex_dig_num+=length($0)} else {flag="post"; pos_lines++}
  } else {is_odd_line=/^(def|add|[0-9A-Fa-f]|)$/
    if (flag=="pre") {
      if (is_hex_line && !is_odd_line) {flag="hex"; hex_dig_num+=length($0)}
        else {prolog=prolog $0 "\n"; pre_lines++}
    } else {
      if (is_hex_line && !is_odd_line) {flag="xhex"; exit} else {pos_lines++}
    }
  }
}

END {
  if (flag=="pre")  errmessage("HEX bitmap not found.", 1)
  if (flag=="xhex") errmessage("more than one HEX bitmap's found.", 2)

   # fix (somehow) length of bitmap bufor
   # ustalanie d/lugo/sci bufora b/ed/acej dzielnikiem d/lugo/sci mapy bitowej
  if ((hex_dig_num%2)!=0)
    errmessage("Odd number of HEX digits in the bitmap.", 3)
  hex_dig_num=hex_dig_num/2
  buff_len=8192
  while (hex_dig_num%buff_len!=0) buff_len--
  buff_num=hex_dig_num/buff_len

   # modification of the preamble of compressed EPS file
   # dostosowanie preambu/ly pliku EPS do czytania kompresowanych danych
  if (match(prolog,/\n%%BoundingBox:[^\n]*\n/))
    prolog = substr(prolog,1,RSTART+RLENGTH-1) banner() "\n" uncep_comment() "\n" substr(prolog,RSTART+RLENGTH)
  else
    errmessage("\"%%BoundingBox:\" not found.", 4)
  if (gsub(/currentfile/,"_fltrd_file",prolog)==0)
    errmessage("illegible EPS preamble.", 5)
  if (gsub(/readhexstring/,"_read_string",prolog)==0)
    errmessage("illegible EPS preamble.", 6)
  if (match(prolog, /\n[^%\n]/))
    prolog = substr(prolog,1,RSTART-1) "\n" source() substr(prolog,RSTART)
  else
    errmessage("illegible EPS preamble.", 7)
   # heuristic trick: | heurystyczny fortel:
   # odd lines at the end of prolog are to be considered as a bitmap beginning
   # dziwne linie na ko/ncu prologu nale/zy uzna/c za pocz/atek mapy bitowej
  if (match(prolog,/\n((def|add|[0-9A-Fa-f])\n)+$/)) {
    prolog = substr(prolog,1,RSTART);
    print "CEP warning: peculiar bitmap beginning."
  }
  gsub(/%/,"%%",prolog) # neutralizing printf | podmiana dla printf

   # WRITE PostScript ENCODING PROGRAM | TWORZENIE PROGRAMU Postscript-owego
  out_ps_errorhandler()
   #
  out_ps("(" ps_fname(OUTF) ") (w) file /w_file exch def")
  out_ps("(" ps_fname(FILENAME) ") (r) file /r_file exch def")
  out_ps("/l_string 255 string def")
  out_ps("/p_string 4096 string def")
  out_ps("/b_string " buff_len " string def")
  out_ps("/flushclose {dup flushfile closefile} def")
   # copy preamble | przepisywanie preambu/ly
  out_ps(pre_lines  " {r_file l_string readline pop pop} repeat")
  out_ps(pre_lines+3  " {currentfile l_string readline pop")
  out_ps("w_file exch writestring w_file (\\n) writestring} repeat")
  out_ps_block(prolog)
  out_ps("%--- PROLOG END | KONIEC PROLOGU")
   # special treatment of the ASCII85 encoded lines looking like DSC comments
   # dodatkowa obr/obka wierszy (zakodowanych jako ASCII85) zaczynaj/acych 
   # si/e tak jak komentarze DSC
  if (is_A85()) {
    out_ps("{pop (%) anchorsearch {pop w_file (%\\n ) writestring} if")
    out_ps(" {(\\n%) search not {exit} if")
    out_ps("  w_file exch writestring pop w_file (\\n%\\n ) writestring} loop")
    out_ps(" w_file exch writestring p_string}")
    out_ps("/NullEncode filter dup")
  } else out_ps("w_file")
   # prepare encoding filters | przygotowywanie filtr/ow koduj/acych
  if (is_A85()) out_ps("/ASCII85Encode filter")
  if (is_HEX()) out_ps("/ASCIIHexEncode filter")
  if (is_LZW()) out_ps("dup /LZWEncode filter")
  if (is_RLE()) out_ps("dup 0 /RunLengthEncode filter")
  if (is_ZIP()) out_ps("dup /FlateEncode filter")
   # loop encoding bitmap | p/etla koduj/aca map/e bitow/a
  out_ps(buff_num " {r_file b_string readhexstring pop")
  out_ps("1 index exch writestring} repeat")
  if (is_A85()) out_ps("flushclose flushclose")
  if (is_HEX()) out_ps("flushclose")
  if (is_LZW()) out_ps("flushclose")
  if (is_RLE()) out_ps("flushclose")
  if (is_ZIP()) out_ps("flushclose")
   # copy postamble | przepisanie postambu/ly
  out_ps(pos_lines+1 " {r_file l_string readline pop")
  out_ps("w_file exch writestring w_file (\\n) writestring} repeat")
  out_ps("w_file flushclose r_file closefile quit")
  printf "."
}

function banner() {return "%%Creator: CEP ver. " ver_no " by BOP s.c."}

function ps_fname(s) {gsub(/\\/,"/",s); return(s)}

function out_ps(s) {print s > TMPSX}
function out_ps_block(block) {printf block > TMPSX}

function out_ps_errorhandler() {
  out_ps("/errq {" gs_abort "} def")
  out_ps("errordict begin ")
  out_ps("/typecheck {255 string cvs (filter) search")
  out_ps("  {(\\010!Filter failed) print")
  out_ps("  ( (ASCII85Encode used with GS version<3.0?)\\n\\007) print}")
  out_ps("  {(\\010!Something went wrong\\n Error: typecheck\\n\\007) print}")
  out_ps("  ifelse errq} def")
  out_ps("/ioerror {(\\010!Input/Output error occurred. (Disk full?)\\n\\007)")
  out_ps("  print errq} def")
  out_ps("/handleerror {$error begin (Something went wrong) print")
  out_ps("  (\\n Error: ) print errorname 255 string cvs print")
  out_ps("  (\\n\\007) print end errq} def")
  out_ps("end")
   #
  out_ps("systemdict /resourcestatus known not")
  out_ps("{(\\010!This version of Ghostscript doesn't support required Level 2 features\\n\\007)")
  out_ps("  print quit} if")
  if (is_A85()) {
    check_filter("ASCII85Encode", "ASCII85Encode filter")
    check_filter("NullEncode", "required Level 2 filters")
  }
  if (is_HEX()) check_filter("ASCIIHexEncode", "ASCIIHexEncode filter")
  if (is_LZW()) check_filter("LZWEncode", "LZWEncode filter")
  if (is_RLE()) check_filter("RunLengthEncode", "RunLengthEncode filter")
  if (is_ZIP()) check_filter("FlateEncode", "FlateEncode filter")
}
  function check_filter(name, expl) {
    out_ps("/" name " /Filter resourcestatus {pop pop}")
    out_ps("{(\\010!This version of Ghostscript doesn't support " expl "\\n\\007)")
    out_ps("  print errq} ifelse")
  }

function errmessage(errname, errnum) {
 print "CEP ERROR:", errname "\007"; exit(errnum)
}

 # searching for the most recent, i.e., active, options
 # poszukiwanie ostatniej (obowi/azuj/acej) opcji
function is_A85() {return (CVM~/8[^Hh]*$/) }
function is_HEX() {return (CVM~/[Hh][^8]*$/) }
function is_LZW() {return (CVM~/[Ll][^NnRrFf]*$/) }
function is_RLE() {return (CVM~/[Rr][^NnLlFf]*$/) }
function is_ZIP() {return (CVM~/[Ff][^NnLlRr]*$/) }

function uncep_comment() {
  s="%UNCEPInfo: " pre_lines+3 " " buff_num " " buff_len " " pos_lines+1
  return s
}

function source() {
  s="/_fltrd_file currentfile"
  if (is_A85()) s=s " /ASCII85Decode filter"
  if (is_HEX()) s=s " /ASCIIHexDecode filter"
  if (is_LZW()) s=s " /LZWDecode filter"
  if (is_RLE()) s=s " /RunLengthDecode filter"
  if (is_ZIP()) s=s " /FlateDecode filter"
  s=s " def /_read_string /readstring load def"
  return s
}