OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2015 Google Inc. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license that can be | |
5 * found in the LICENSE file. | |
6 */ | |
7 | |
8 #include "SkCodecPriv.h" | |
9 #include "SkJpegUtility.h" | |
10 | |
11 /* | |
12 * Initialize the source manager | |
13 */ | |
14 static void sk_init_source(j_decompress_ptr jpegInfo) { | |
15 skjpeg_source_mgr* src = (skjpeg_source_mgr*) jpegInfo->src; | |
16 src->next_input_byte = (const JOCTET*) src->fBuffer; | |
17 src->bytes_in_buffer = 0; | |
18 #ifdef SK_BUILD_FOR_ANDROID | |
19 src->current_offset = 0; | |
20 #endif | |
21 if (!src->fStream->rewind()) { | |
scroggo
2015/04/10 17:19:07
We should not need to rewind here?
msarett
2015/04/13 20:54:05
Yes agreed, this is not necessary here. This was
| |
22 SkCodecPrintf("Failure to rewind.\n"); | |
23 jpegInfo->err->error_exit((j_common_ptr) jpegInfo); | |
24 } | |
25 } | |
26 | |
27 /* | |
28 * Seek to a specific offset in the stream | |
29 */ | |
30 #ifdef SK_BUILD_FOR_ANDROID | |
31 static boolean sk_seek_input_data(j_decompress_ptr jpegInfo, long byteOffset) { | |
scroggo
2015/04/10 17:19:07
This function (and the rest of the SK_BUILD_FOR_AN
msarett
2015/04/13 20:54:05
Done.
| |
32 skjpeg_source_mgr* src = (skjpeg_source_mgr*) jpegInfo->src; | |
33 size_t offset = (size_t) byteOffset; | |
34 | |
35 if (offset > src->current_offset) { | |
36 size_t bytesToSkip = offset - src->current_offset; | |
37 if (bytesToSkip != src->fStream->skip(bytesToSkip)) { | |
38 SkCodecPrintf("Failure to skip.\n"); | |
39 jpegInfo->err->error_exit((j_common_ptr) jpegInfo); | |
40 return false; | |
41 } | |
42 } else { | |
43 if (!src->fStream->rewind()) { | |
44 SkCodecPrintf("Failure to rewind.\n"); | |
45 jpegInfo->err->error_exit((j_common_ptr) jpegInfo); | |
46 return false; | |
47 } | |
48 if (offset != src->fStream->skip(offset)) { | |
49 SkCodecPrintf("Failure to skip.\n"); | |
50 jpegInfo->err->error_exit((j_common_ptr) jpegInfo); | |
51 return false; | |
52 } | |
53 } | |
54 | |
55 src->current_offset = offset; | |
56 src->next_input_byte = (const JOCTET*) src->fBuffer; | |
57 src->bytes_in_buffer = 0; | |
58 return true; | |
59 } | |
60 #endif | |
61 | |
62 /* | |
63 * Fill the input buffer from the stream | |
64 */ | |
65 static boolean sk_fill_input_buffer(j_decompress_ptr jpegInfo) { | |
66 skjpeg_source_mgr* src = (skjpeg_source_mgr*) jpegInfo->src; | |
67 size_t bytes = src->fStream->read(src->fBuffer, skjpeg_source_mgr::kBufferSi ze); | |
68 | |
69 // libjpeg is still happy with a less than full read, as long as the result is non-zero | |
70 if (bytes == 0) { | |
71 return false; | |
72 } | |
73 | |
74 #ifdef SK_BUILD_FOR_ANDROID | |
75 src->current_offset += bytes; | |
76 #endif | |
77 src->next_input_byte = (const JOCTET*) src->fBuffer; | |
78 src->bytes_in_buffer = bytes; | |
79 return true; | |
80 } | |
81 | |
82 /* | |
83 * Skip a certain number of bytes in the stream | |
84 */ | |
85 static void sk_skip_input_data(j_decompress_ptr jpegInfo, long numBytes) { | |
86 skjpeg_source_mgr* src = (skjpeg_source_mgr*) jpegInfo->src; | |
87 size_t bytes = (size_t) numBytes; | |
88 | |
89 if (bytes > src->bytes_in_buffer) { | |
90 size_t bytesToSkip = bytes - src->bytes_in_buffer; | |
91 if (bytesToSkip != src->fStream->skip(bytesToSkip)) { | |
92 SkCodecPrintf("Failure to skip.\n"); | |
93 jpegInfo->err->error_exit((j_common_ptr)jpegInfo); | |
94 return; | |
95 } | |
96 #ifdef SK_BUILD_FOR_ANDROID | |
97 src->current_offset += bytesToSkip; | |
98 #endif | |
99 src->next_input_byte = (const JOCTET*) src->fBuffer; | |
100 src->bytes_in_buffer = 0; | |
101 } else { | |
102 src->next_input_byte += numBytes; | |
103 src->bytes_in_buffer -= numBytes; | |
104 } | |
105 } | |
106 | |
107 /* | |
108 * We do not need to do anything to terminate our stream | |
109 */ | |
110 static void sk_term_source(j_decompress_ptr jpegInfo) | |
111 {} | |
112 | |
113 /* | |
114 * Constructor for the source manager that we provide to libjpeg | |
115 * We provide skia implementations of all of the stream processing functions req uired by libjpeg | |
116 */ | |
117 skjpeg_source_mgr::skjpeg_source_mgr(SkStream* stream) | |
118 : fStream(stream) | |
119 { | |
120 init_source = sk_init_source; | |
121 fill_input_buffer = sk_fill_input_buffer; | |
122 skip_input_data = sk_skip_input_data; | |
123 resync_to_restart = jpeg_resync_to_restart; | |
124 term_source = sk_term_source; | |
125 #ifdef SK_BUILD_FOR_ANDROID | |
126 seek_input_data = sk_seek_input_data; | |
127 #endif | |
128 } | |
129 | |
130 /* | |
131 * Exit on an error | |
132 */ | |
133 void skjpeg_err_exit(j_common_ptr jpegInfo) { | |
134 // Simply return to Skia client code | |
135 // JpegAutoClean should take care of freeing memory | |
136 skjpeg_error_mgr* error = (skjpeg_error_mgr*) jpegInfo->err; | |
137 (*error->output_message) (jpegInfo); | |
138 longjmp(error->fJmpBuf, 1); | |
139 } | |
OLD | NEW |