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

Last change on this file since 277 was 277, checked in by rbri, 11 years ago

PDF plugin: Poppler library updated to version 0.12.3

File size: 4.2 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-2009 Albert Astals Cid <aacid@kde.org>
9// Copyright 2009 Ryszard Trojnacki <rysiek@menel.com>
10//
11//========================================================================
12
13#include "DCTStream.h"
14
15static void str_init_source(j_decompress_ptr cinfo)
16{
17}
18
19static boolean str_fill_input_buffer(j_decompress_ptr cinfo)
20{
21  int c;
22  struct str_src_mgr * src = (struct str_src_mgr *)cinfo->src;
23  if (src->abort) return FALSE;
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  init();
63}
64
65DCTStream::~DCTStream() {
66  jpeg_destroy_decompress(&cinfo);
67  delete str;
68}
69
70static void exitErrorHandler(jpeg_common_struct *error) {
71  j_decompress_ptr cinfo = (j_decompress_ptr)error;
72  str_src_mgr * src = (struct str_src_mgr *)cinfo->src;
73  src->abort = true;
74}
75
76void DCTStream::init()
77{
78  jpeg_std_error(&jerr);
79  jerr.error_exit = &exitErrorHandler;
80  src.pub.init_source = str_init_source;
81  src.pub.fill_input_buffer = str_fill_input_buffer;
82  src.pub.skip_input_data = str_skip_input_data;
83  src.pub.resync_to_restart = jpeg_resync_to_restart;
84  src.pub.term_source = str_term_source;
85  src.pub.bytes_in_buffer = 0;
86  src.pub.next_input_byte = NULL;
87  src.str = str;
88  src.index = 0;
89  src.abort = false;
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        src.abort = true;
126        return;
127      }
128      if (c != 0xFF) c = 0;
129    }
130    else
131    {
132      c2 = str->getChar();
133      if (c2 != 0xD8)
134      {
135        c = 0;
136        c2 = 0;
137      }
138      else startFound = true;
139    }
140  }
141
142  jpeg_read_header(&cinfo, TRUE);
143  if (src.abort) return;
144
145  if (!jpeg_start_decompress(&cinfo))
146  {
147    src.abort = true;
148    return;
149  }
150
151  row_stride = cinfo.output_width * cinfo.output_components;
152  row_buffer = cinfo.mem->alloc_sarray((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
153}
154
155int DCTStream::getChar() {
156  if (src.abort) return EOF;
157 
158  int c;
159
160  if (current == limit) {
161    if (cinfo.output_scanline < cinfo.output_height)
162    {
163      if (!jpeg_read_scanlines(&cinfo, row_buffer, 1)) return EOF;
164      current = &row_buffer[0][0];
165      limit = &row_buffer[0][(cinfo.output_width - 1) * cinfo.output_components] + cinfo.output_components;
166    }
167    else return EOF;
168  }
169  c = *current;
170  ++current;
171  return c;
172}
173
174int DCTStream::lookChar() {
175  if (src.abort) return EOF;
176 
177  return *current;
178}
179
180GooString *DCTStream::getPSFilter(int psLevel, char *indent) {
181  GooString *s;
182
183  if (psLevel < 2) {
184    return NULL;
185  }
186  if (!(s = str->getPSFilter(psLevel, indent))) {
187    return NULL;
188  }
189  s->append(indent)->append("<< >> /DCTDecode filter\n");
190  return s;
191}
192
193GBool DCTStream::isBinary(GBool last) {
194  return str->isBinary(gTrue);
195}
Note: See TracBrowser for help on using the repository browser.