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

Last change on this file since 461 was 461, checked in by Silvan Scherrer, 11 years ago

poppler update to 0.14.2

File size: 5.0 KB
Line 
1//========================================================================
2//
3// DCTStream.cc
4//
5// This file is licensed under the GPLv2 or later
6//
7// Copyright 2005 Jeff Muizelaar <jeff@infidigm.net>
8// Copyright 2005-2010 Albert Astals Cid <aacid@kde.org>
9// Copyright 2009 Ryszard Trojnacki <rysiek@menel.com>
10// Copyright 2010 Carlos Garcia Campos <carlosgc@gnome.org>
11//
12//========================================================================
13
14#include "DCTStream.h"
15
16static void str_init_source(j_decompress_ptr cinfo)
17{
18}
19
20static boolean str_fill_input_buffer(j_decompress_ptr cinfo)
21{
22  int c;
23  struct str_src_mgr * src = (struct str_src_mgr *)cinfo->src;
24  if (src->index == 0) {
25    c = 0xFF;
26    src->index++;
27  }
28  else if (src->index == 1) {
29    c = 0xD8;
30    src->index++;
31  }
32  else c = src->str->getChar();
33  if (c != EOF)
34  {
35    src->buffer = c;
36    src->pub.next_input_byte = &src->buffer;
37    src->pub.bytes_in_buffer = 1;
38    return TRUE;
39  }
40  else return FALSE;
41}
42
43static void str_skip_input_data(j_decompress_ptr cinfo, long num_bytes)
44{
45  struct str_src_mgr * src = (struct str_src_mgr *)cinfo->src;
46  if (num_bytes > 0) {
47    while (num_bytes > (long) src->pub.bytes_in_buffer) {
48      num_bytes -= (long) src->pub.bytes_in_buffer;
49      str_fill_input_buffer(cinfo);
50    }
51    src->pub.next_input_byte += (size_t) num_bytes;
52    src->pub.bytes_in_buffer -= (size_t) num_bytes;
53  }
54}
55
56static void str_term_source(j_decompress_ptr cinfo)
57{
58}
59
60DCTStream::DCTStream(Stream *strA, int colorXformA) :
61  FilterStream(strA) {
62  colorXform = colorXformA;
63  init();
64}
65
66DCTStream::~DCTStream() {
67  jpeg_destroy_decompress(&cinfo);
68  delete str;
69}
70
71static void exitErrorHandler(jpeg_common_struct *error) {
72  j_decompress_ptr cinfo = (j_decompress_ptr)error;
73  str_src_mgr * src = (struct str_src_mgr *)cinfo->src;
74  longjmp(src->setjmp_buffer, 1);
75}
76
77void DCTStream::init()
78{
79  jpeg_std_error(&jerr);
80  jerr.error_exit = &exitErrorHandler;
81  src.pub.init_source = str_init_source;
82  src.pub.fill_input_buffer = str_fill_input_buffer;
83  src.pub.skip_input_data = str_skip_input_data;
84  src.pub.resync_to_restart = jpeg_resync_to_restart;
85  src.pub.term_source = str_term_source;
86  src.pub.bytes_in_buffer = 0;
87  src.pub.next_input_byte = NULL;
88  src.str = str;
89  src.index = 0;
90  current = NULL;
91  limit = NULL;
92 
93  cinfo.err = &jerr;
94  jpeg_create_decompress(&cinfo);
95  cinfo.src = (jpeg_source_mgr *)&src;
96  row_buffer = NULL;
97}
98
99void DCTStream::reset() {
100  int row_stride;
101
102  str->reset();
103
104  if (row_buffer)
105  {
106    jpeg_destroy_decompress(&cinfo);
107    init();
108  }
109
110  // JPEG data has to start with 0xFF 0xD8
111  // but some pdf like the one on
112  // https://bugs.freedesktop.org/show_bug.cgi?id=3299
113  // does have some garbage before that this seeks for
114  // the start marker...
115  bool startFound = false;
116  int c = 0, c2 = 0;
117  while (!startFound)
118  {
119    if (!c)
120    {
121      c = str->getChar();
122      if (c == -1)
123      {
124        error(-1, "Could not find start of jpeg data");
125        return;
126      }
127      if (c != 0xFF) c = 0;
128    }
129    else
130    {
131      c2 = str->getChar();
132      if (c2 != 0xD8)
133      {
134        c = 0;
135        c2 = 0;
136      }
137      else startFound = true;
138    }
139  }
140
141  if (!setjmp(src.setjmp_buffer)) {
142    jpeg_read_header(&cinfo, TRUE);
143
144    // figure out color transform
145    if (colorXform == -1 && !cinfo.saw_Adobe_marker) {
146      if (cinfo.num_components == 3) {
147        if (cinfo.saw_JFIF_marker) {
148          colorXform = 1;
149        } else if (cinfo.cur_comp_info[0]->component_id == 82 &&
150                   cinfo.cur_comp_info[1]->component_id == 71 &&
151                   cinfo.cur_comp_info[2]->component_id == 66) { // ASCII "RGB"
152          colorXform = 0;
153        } else {
154          colorXform = 1;
155        }
156      } else {
157        colorXform = 0;
158      }
159    } else if (cinfo.saw_Adobe_marker) {
160      colorXform = cinfo.Adobe_transform;
161    }
162
163    switch (cinfo.num_components) {
164    case 3:
165            cinfo.jpeg_color_space = colorXform ? JCS_YCbCr : JCS_RGB;
166            break;
167    case 4:
168            cinfo.jpeg_color_space = colorXform ? JCS_YCCK : JCS_CMYK;
169            break;
170    }
171
172    jpeg_start_decompress(&cinfo);
173
174    row_stride = cinfo.output_width * cinfo.output_components;
175    row_buffer = cinfo.mem->alloc_sarray((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
176  }
177}
178
179int DCTStream::getChar() {
180  int c;
181
182  if (current == limit) {
183    if (cinfo.output_scanline < cinfo.output_height)
184    {
185      if (!setjmp(src.setjmp_buffer))
186      {
187        if (!jpeg_read_scanlines(&cinfo, row_buffer, 1)) return EOF;
188        current = &row_buffer[0][0];
189        limit = &row_buffer[0][(cinfo.output_width - 1) * cinfo.output_components] + cinfo.output_components;
190      }
191      else return EOF;
192    }
193    else return EOF;
194  }
195  c = *current;
196  ++current;
197  return c;
198}
199
200int DCTStream::lookChar() {
201  return *current;
202}
203
204GooString *DCTStream::getPSFilter(int psLevel, char *indent) {
205  GooString *s;
206
207  if (psLevel < 2) {
208    return NULL;
209  }
210  if (!(s = str->getPSFilter(psLevel, indent))) {
211    return NULL;
212  }
213  s->append(indent)->append("<< >> /DCTDecode filter\n");
214  return s;
215}
216
217GBool DCTStream::isBinary(GBool last) {
218  return str->isBinary(gTrue);
219}
Note: See TracBrowser for help on using the repository browser.