xref: /aosp_15_r20/external/tensorflow/tensorflow/core/lib/png/png_io.h (revision b6fb3261f9314811a0f4371741dbb8839866f948)
1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 // Functions to read and write images in PNG format.
17 //
18 // The advantage over image/codec/png{enc,dec}ocder.h is that this library
19 // supports both 8 and 16 bit images.
20 //
21 // The decoding routine accepts binary image data as a StringPiece.  These are
22 // implicitly constructed from strings or char* so they're completely
23 // transparent to the caller.  They're also very cheap to construct so this
24 // doesn't introduce any additional overhead.
25 //
26 // The primary benefit of StringPieces being, in this case, that APIs already
27 // returning StringPieces (e.g., Bigtable Scanner) or Cords (e.g., IOBuffer;
28 // only when they're flat, though) or protocol buffer fields typed to either of
29 // these can be decoded without copying the data into a C++ string.
30 
31 #ifndef TENSORFLOW_LIB_PNG_PNG_IO_H_
32 #define TENSORFLOW_LIB_PNG_PNG_IO_H_
33 
34 #include <string>
35 #include <utility>
36 #include <vector>
37 
38 #include "absl/base/casts.h"
39 #include "tensorflow/core/platform/png.h"
40 #include "tensorflow/core/platform/stringpiece.h"
41 #include "tensorflow/core/platform/types.h"
42 
43 namespace tensorflow {
44 namespace png {
45 
46 // Handy container for decoding informations and struct pointers
47 struct DecodeContext {
48   const uint8* data;
49   int data_left;
50   png_structp png_ptr;
51   png_infop info_ptr;
52   png_uint_32 width, height;
53   int num_passes;
54   int color_type;
55   int bit_depth;
56   int channels;
57   bool need_to_synthesize_16;
58   bool error_condition;
DecodeContextDecodeContext59   DecodeContext() : png_ptr(nullptr), info_ptr(nullptr) {}
60 };
61 
62 bool DecodeHeader(StringPiece png_string, int* width, int* height,
63                   int* components, int* channel_bit_depth,
64                   std::vector<std::pair<std::string, std::string> >* metadata);
65 
66 // Sample usage for reading PNG:
67 //
68 // string png_string;  /* fill with input PNG format data */
69 // DecodeContext context;
70 // CHECK(CommonInitDecode(png_string, 3 /*RGB*/, 8 /*uint8*/, &context));
71 // char* image_buffer = new char[3*context.width*context.height];
72 // CHECK(CommonFinishDecode(absl::bit_cast<png_byte*>(image_buffer),
73 //       3*context.width /*stride*/, &context));
74 //
75 // desired_channels may be 0 to detected it from the input.
76 
77 bool CommonInitDecode(StringPiece png_string, int desired_channels,
78                       int desired_channel_bits, DecodeContext* context);
79 
80 bool CommonFinishDecode(png_bytep data, int row_bytes, DecodeContext* context);
81 
82 // Normally called automatically from CommonFinishDecode.  If CommonInitDecode
83 // is called but not CommonFinishDecode, call this to clean up.  Safe to call
84 // extra times.
85 void CommonFreeDecode(DecodeContext* context);
86 
87 // Sample usage for writing PNG:
88 //
89 // uint16* image_buffer = new uint16[width*height];  /* fill with pixels */
90 // string png_string;
91 // CHECK(WriteImageToBuffer(image_buffer, width, height, 2*width /*stride*/,
92 //       1 /*gray*/, 16 /*uint16*/, &png_string, NULL));
93 //
94 // compression is in [-1,9], where 0 is fast and weak compression, 9 is slow
95 // and strong, and -1 is the zlib default.
96 
97 template <typename T>
98 bool WriteImageToBuffer(
99     const void* image, int width, int height, int row_bytes, int num_channels,
100     int channel_bits, int compression, T* png_string,
101     const std::vector<std::pair<std::string, std::string> >* metadata);
102 
103 // Explicit instantiations defined in png_io.cc.
104 extern template bool WriteImageToBuffer<std::string>(
105     const void* image, int width, int height, int row_bytes, int num_channels,
106     int channel_bits, int compression, std::string* png_string,
107     const std::vector<std::pair<std::string, std::string> >* metadata);
108 extern template bool WriteImageToBuffer<tstring>(
109     const void* image, int width, int height, int row_bytes, int num_channels,
110     int channel_bits, int compression, tstring* png_string,
111     const std::vector<std::pair<std::string, std::string> >* metadata);
112 
113 }  // namespace png
114 }  // namespace tensorflow
115 
116 #endif  // TENSORFLOW_LIB_PNG_PNG_IO_H_
117