/src/guetzli/guetzli/jpeg_data_decoder.cc
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2016 Google Inc. |
3 | | * |
4 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
5 | | * you may not use this file except in compliance with the License. |
6 | | * You may obtain a copy of the License at |
7 | | * |
8 | | * http://www.apache.org/licenses/LICENSE-2.0 |
9 | | * |
10 | | * Unless required by applicable law or agreed to in writing, software |
11 | | * distributed under the License is distributed on an "AS IS" BASIS, |
12 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 | | * See the License for the specific language governing permissions and |
14 | | * limitations under the License. |
15 | | */ |
16 | | |
17 | | #include "guetzli/jpeg_data_decoder.h" |
18 | | |
19 | | #include "guetzli/output_image.h" |
20 | | |
21 | | namespace guetzli { |
22 | | |
23 | | // Mimic libjpeg's heuristics to guess jpeg color space. |
24 | | // Requires that the jpg has 3 components. |
25 | 4.43k | bool HasYCbCrColorSpace(const JPEGData& jpg) { |
26 | 4.43k | bool has_Adobe_marker = false; |
27 | 4.43k | uint8_t Adobe_transform = 0; |
28 | 291k | for (const std::string& app : jpg.app_data) { |
29 | 291k | if (static_cast<uint8_t>(app[0]) == 0xe0) { |
30 | 493 | return true; |
31 | 291k | } else if (static_cast<uint8_t>(app[0]) == 0xee && app.size() >= 15) { |
32 | 1.02k | has_Adobe_marker = true; |
33 | 1.02k | Adobe_transform = app[14]; |
34 | 1.02k | } |
35 | 291k | } |
36 | 3.93k | if (has_Adobe_marker) { |
37 | 51 | return (Adobe_transform != 0); |
38 | 51 | } |
39 | 3.88k | const int cid0 = jpg.components[0].id; |
40 | 3.88k | const int cid1 = jpg.components[1].id; |
41 | 3.88k | const int cid2 = jpg.components[2].id; |
42 | 3.88k | return (cid0 != 'R' || cid1 != 'G' || cid2 != 'B'); |
43 | 3.93k | } |
44 | | |
45 | 2.29k | std::vector<uint8_t> DecodeJpegToRGB(const JPEGData& jpg) { |
46 | 2.29k | if (jpg.components.size() == 1 || |
47 | 2.22k | (jpg.components.size() == 3 && |
48 | 2.27k | HasYCbCrColorSpace(jpg) && (jpg.Is420() || jpg.Is444()))) { |
49 | 2.27k | OutputImage img(jpg.width, jpg.height); |
50 | 2.27k | img.CopyFromJpegData(jpg); |
51 | 2.27k | return img.ToSRGB(); |
52 | 2.27k | } |
53 | 19 | return std::vector<uint8_t>(); |
54 | 2.29k | } |
55 | | |
56 | | } // namespace guetzli |