You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 lines
5.3 KiB

1 month ago
  1. % Copyright (C) 2001-2023 Artifex Software, Inc.
  2. % All Rights Reserved.
  3. %
  4. % This software is provided AS-IS with no warranty, either express or
  5. % implied.
  6. %
  7. % This software is distributed under license and may not be copied,
  8. % modified or distributed except as expressly authorized under the terms
  9. % of the license contained in the file LICENSE in this distribution.
  10. %
  11. % Refer to licensing information at http://www.artifex.com or contact
  12. % Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  13. % CA 94129, USA, for further information.
  14. %
  15. % viewgif.ps
  16. % Display a GIF file.
  17. /read1 % <file> read1 <int>
  18. { read pop
  19. } bind def
  20. /read2 % <file> read2 <int>
  21. { dup read1 exch read1 8 bitshift add
  22. } bind def
  23. /readGIFheader % <file> readGIFheader <dict>
  24. { 20 dict begin
  25. dup 6 string readstring pop
  26. dup (GIF87a) eq exch (GIF89a) eq or not
  27. { (Not a GIF file.\n) print cleartomark stop
  28. } if
  29. dup read2 /Width exch def
  30. dup read2 /Height exch def
  31. dup read1
  32. dup 128 ge /GlobalColor exch def
  33. dup -4 bitshift 7 and 1 add /BitsPerPixel exch def %***BOGUS?***
  34. dup 8 and 0 ne /PaletteSorted exch def
  35. 7 and 1 add dup /BitsPerPixel exch def
  36. 1 exch bitshift /PaletteSize exch def
  37. dup read1 /BackgroundIndex exch def
  38. dup read1 15 add 64 div /AspectRatio exch def
  39. GlobalColor
  40. { PaletteSize 3 mul string readstring pop
  41. /GlobalPalette exch def
  42. } {
  43. pop
  44. } ifelse
  45. currentdict end
  46. } bind def
  47. /readGIFimageHeader % <file> readGIFimageHeader <dict>
  48. % Note: GIF header must be on dict stack
  49. { 10 dict begin
  50. { dup read1
  51. dup (!) 0 get ne { exit } if pop % extension
  52. dup read1 pop
  53. { dup read1 dup 0 eq { pop exit } if { dup read1 pop } repeat
  54. } loop
  55. } loop
  56. (,) 0 get ne
  57. { (Not a GIF image.\n) print stop
  58. } if
  59. dup read2 /Left exch def
  60. dup read2 /Top exch def
  61. dup read2 /Width exch def
  62. dup read2 /Height exch def
  63. dup read1
  64. dup 128 ge /LocalColor exch def
  65. dup 64 and 0 ne /Interlaced exch def
  66. LocalColor
  67. { 7 and 1 add /BitsPerPixel exch def
  68. 1 BitsPerPixel bitshift 3 mul string readstring pop
  69. /Palette exch def
  70. }
  71. { pop pop /Palette GlobalPalette def
  72. }
  73. ifelse
  74. currentdict end
  75. } bind def
  76. /imageGIF % <imagedict> imageGIF
  77. { /ImageOut where
  78. { pop
  79. % We know BitsPerComponent = 8, Decode = [0 255].
  80. % and there is only a single data source which is
  81. % either a filter or a string whose size is exactly
  82. % the width of the row.
  83. dup /DataSource get dup type /stringtype eq
  84. { ImageOut exch writestring
  85. }
  86. { pop dup /Width get string
  87. 1 index /Height get
  88. { 1 index /DataSource get 1 index readstring pop
  89. ImageOut exch writestring
  90. }
  91. repeat pop pop
  92. }
  93. ifelse
  94. }
  95. { image
  96. }
  97. ifelse
  98. } bind def
  99. /viewGIF % <file|string> viewGIF -
  100. { save 20 dict begin
  101. /saved exch def
  102. dup type /stringtype eq { (r) file } if
  103. /F exch def
  104. /ImageOutFile where { /ImageOut ImageOutFile (w) file def } if
  105. F readGIFheader /Header exch def
  106. currentdict Header end begin begin
  107. VGIFDEBUG { Header { exch == == } forall (----------------\n) print flush } if
  108. F readGIFimageHeader /ImageHeader exch def
  109. currentdict ImageHeader end begin begin
  110. VGIFDEBUG { ImageHeader { exch == == } forall (----------------\n) print flush } if
  111. /D F
  112. << /InitialCodeLength F read1
  113. /FirstBitLowOrder true
  114. /BlockData true
  115. /EarlyChange 0
  116. >> /LZWDecode filter def
  117. [/Indexed /DeviceRGB 1 BitsPerPixel bitshift 1 sub Palette] setcolorspace
  118. matrix currentmatrix
  119. 0 1 3 { 2 copy get dup 0 ne { dup abs div } if 3 copy put pop pop } for
  120. setmatrix
  121. << /ImageType 1
  122. /ImageMatrix [1 0 0 -1 0 Height]
  123. /BitsPerComponent 8
  124. /Decode [0 255]
  125. Interlaced
  126. { /Width Width /Height 1
  127. /row Width string def
  128. /DataSource row
  129. >> /I exch def
  130. /inter % <num> <denom> inter -
  131. { /denom exch def /num exch def
  132. gsave
  133. /lines Height denom 1 sub add num sub denom idiv def
  134. 0 1 lines 1 sub {
  135. Height exch denom mul num add sub
  136. I /ImageMatrix get 5 3 -1 roll put
  137. D row readstring pop pop
  138. I imageGIF
  139. } for
  140. grestore
  141. }
  142. bind def
  143. 0 8 inter
  144. 4 8 inter
  145. 2 4 inter
  146. 1 2 inter
  147. }
  148. { /Width Width /Height Height
  149. /DataSource D
  150. >> imageGIF
  151. }
  152. ifelse
  153. saved end end end restore
  154. } bind def
  155. % This lets you do stuff on the command line like:
  156. % gs -sDEVICE=pdfwrite -o stuff%03d.pdf viewgif.ps -c "(image.gif) << /PageSize 2 index viewGIFgetsize 2 array astore /HWResolution [ 72 72 ] >> setpagedevice viewGIF"
  157. % so the output size is influenced by the original image.
  158. /viewGIFgetsize % <file|string> ==> [width height]
  159. {
  160. save 20 dict begin
  161. /saved exch def
  162. dup type /stringtype eq { (r) file } if
  163. /F exch def
  164. F readGIFheader /Header exch def
  165. currentdict Header end begin begin
  166. VGIFDEBUG { Header { exch == == } forall (----------------\n) print flush } if
  167. F readGIFimageHeader /ImageHeader exch def
  168. currentdict ImageHeader end begin begin
  169. F 0 setfileposition % reset file pointer
  170. Width Height
  171. saved end end end restore
  172. } bind def