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

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

PDF plugin: Poppler library updated to version 0.10.0

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