source: trunk/poppler/mypoppler/poppler/DCTStream.cc @ 250

Last change on this file since 250 was 250, checked in by Eugene Romanenko, 13 years ago

PDF plugin: poppler library updated to version 0.8.3

File size: 3.9 KB
Line 
1//========================================================================
2//
3// DCTStream.cc
4//
5// Copyright 1996-2003 Glyph & Cog, LLC
6//
7//========================================================================
8
9#include "DCTStream.h"
10
11static void str_init_source(j_decompress_ptr cinfo)
12{
13}
14
15static boolean str_fill_input_buffer(j_decompress_ptr cinfo)
16{
17  int c;
18  struct str_src_mgr * src = (struct str_src_mgr *)cinfo->src;
19  if (src->index == 0) {
20    c = 0xFF;
21    src->index++;
22  }
23  else if (src->index == 1) {
24    c = 0xD8;
25    src->index++;
26  }
27  else c = src->str->getChar();
28  if (c != EOF)
29  {
30    src->buffer = c;
31    src->pub.next_input_byte = &src->buffer;
32    src->pub.bytes_in_buffer = 1;
33    return TRUE;
34  }
35  else return FALSE;
36}
37
38static void str_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
39{
40  struct str_src_mgr * src = (struct str_src_mgr *)cinfo->src;
41  if (num_bytes > 0) {
42    while (num_bytes > (long) src->pub.bytes_in_buffer) {
43      num_bytes -= (long) src->pub.bytes_in_buffer;
44      str_fill_input_buffer(cinfo);
45    }
46    src->pub.next_input_byte += (size_t) num_bytes;
47    src->pub.bytes_in_buffer -= (size_t) num_bytes;
48  }
49}
50
51static void str_term_source(j_decompress_ptr cinfo)
52{
53}
54
55DCTStream::DCTStream(Stream *strA, int colorXformA) :
56  FilterStream(strA) {
57  init();
58}
59
60DCTStream::~DCTStream() {
61  jpeg_destroy_decompress(&cinfo);
62  delete str;
63}
64
65void exitErrorHandler(jpeg_common_struct *error) {
66  j_decompress_ptr cinfo = (j_decompress_ptr)error;
67  str_src_mgr * src = (struct str_src_mgr *)cinfo->src;
68  src->abort = true;
69}
70
71void DCTStream::init()
72{
73  jpeg_create_decompress(&cinfo);
74  src.pub.init_source = str_init_source;
75  src.pub.fill_input_buffer = str_fill_input_buffer;
76  src.pub.skip_input_data = str_skip_input_data;
77  src.pub.resync_to_restart = jpeg_resync_to_restart;
78  src.pub.term_source = str_term_source;
79  src.pub.bytes_in_buffer = 0;
80  src.pub.next_input_byte = NULL;
81  src.str = str;
82  src.index = 0;
83  src.abort = false;
84  cinfo.src = (jpeg_source_mgr *)&src;
85  jpeg_std_error(&jerr);
86  jerr.error_exit = &exitErrorHandler;
87  cinfo.err = &jerr;
88  x = 0;
89  row_buffer = NULL;
90}
91
92void DCTStream::reset() {
93  int row_stride;
94
95  str->reset();
96
97  if (row_buffer)
98  {
99    jpeg_destroy_decompress(&cinfo);
100    init();
101  }
102
103  // JPEG data has to start with 0xFF 0xD8
104  // but some pdf like the one on
105  // https://bugs.freedesktop.org/show_bug.cgi?id=3299
106  // does have some garbage before that this seeks for
107  // the start marker...
108  bool startFound = false;
109  int c = 0, c2 = 0;
110  while (!startFound)
111  {
112    if (!c)
113    {
114      c = str->getChar();
115      if (c == -1)
116      {
117        error(-1, "Could not find start of jpeg data");
118        src.abort = true;
119        return;
120      }
121      if (c != 0xFF) c = 0;
122    }
123    else
124    {
125      c2 = str->getChar();
126      if (c2 != 0xD8)
127      {
128        c = 0;
129        c2 = 0;
130      }
131      else startFound = true;
132    }
133  }
134
135  jpeg_read_header(&cinfo, TRUE);
136  if (src.abort) return;
137
138  jpeg_start_decompress(&cinfo);
139
140  row_stride = cinfo.output_width * cinfo.output_components;
141  row_buffer = cinfo.mem->alloc_sarray((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
142}
143
144int DCTStream::getChar() {
145  if (src.abort) return EOF;
146 
147  int c;
148
149  if (x == 0) {
150    if (cinfo.output_scanline < cinfo.output_height)
151    {
152      if (!jpeg_read_scanlines(&cinfo, row_buffer, 1)) return EOF;
153    }
154    else return EOF;
155  }
156  c = row_buffer[0][x];
157  x++;
158  if (x == cinfo.output_width * cinfo.output_components)
159    x = 0;
160  return c;
161}
162
163int DCTStream::lookChar() {
164  if (src.abort) return EOF;
165 
166  int c;
167  c = row_buffer[0][x];
168  return c;
169}
170
171GooString *DCTStream::getPSFilter(int psLevel, char *indent) {
172  GooString *s;
173
174  if (psLevel < 2) {
175    return NULL;
176  }
177  if (!(s = str->getPSFilter(psLevel, indent))) {
178    return NULL;
179  }
180  s->append(indent)->append("<< >> /DCTDecode filter\n");
181  return s;
182}
183
184GBool DCTStream::isBinary(GBool last) {
185  return str->isBinary(gTrue);
186}
Note: See TracBrowser for help on using the repository browser.