# 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: "PS" --> "filtered PS" converter
#      input - input file name
#      OUTF  - output file name
#      CVM   - conversion method
#      TMPSX - temporary PostScript file name
#
# P: Konwerter "PS" --> "filtered PS"
#      wej/scie - nazwa pliku konwertowanego
#      OUTF     - nazwa pliku wyj/sciowego
#      CVM      - metoda konwersji PS-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!~/[BbHh8]/) CVM=CVM "8"    # Domy/slna metoda kodowania i kompresji
 printf "COP ver. " ver_no ", coding:"
 if (is_A85()) printf " A85"
 if (is_HEX()) printf " Hex"
 if (is_BIN()) printf " Bin"
 if (is_LZW()) printf ", LZW"
 if (is_RLE()) printf ", RLE"
 if (is_ZIP()) printf ", Flate (non-standard in PostScript Level 2!)"
 print ""
}

NR==1 && /^%!PS-Adobe/ {hdline=$0}

/^%%BoundingBox:/ {bbline=$0; if (/\(atend\)/) flag=1; if (!flag) exit}

END {
  # WRITE PostScript ENCODING PROGRAM | TWORZENIE PROGRAMU Postscript-owego
 out_ps_errorhandler()
  # create preamble | tworzenie preambu/ly
 out_ps("(" ps_fname(OUTF) ") (w) file /w_file exch def")
 out_ps("(" ps_fname(FILENAME) ") (r) file /r_file exch def")
 out_ps("/p_string 4096 string def")
 out_ps("/b_string 4096 string def")
 out_ps("/flushclose {dup flushfile closefile} def")
 if (hdline=="") hdline="%!PS-Adobe-3.0"
 hdline=hdline " COP-" ver_no
 out_ps("w_file (" hdline "\\n) writestring")
 if (bbline!="") out_ps("w_file (" bbline "\\n) writestring")
 out_ps("w_file (" banner() "\\n) writestring")
 out_ps("w_file (" source() "\\n) writestring")
  # 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("{r_file b_string readstring not")
 out_ps("exch 2 index exch writestring")
 out_ps("{exit} if} loop")
 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")
  # create postamble | tworzenie postambu/ly
 out_ps("w_file (\\n%%EOF) writestring")
 out_ps("w_file flushclose r_file closefile quit")
 printf "."
}


function banner() {return "%%Creator: COP 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_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")
 }

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

function source() {
 s="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 " cvx exec"
 return s
}