/src/libwebp/imageio/imageio_util.c
Line | Count | Source (jump to first uncovered line) |
1 | | // Copyright 2016 Google Inc. All Rights Reserved. |
2 | | // |
3 | | // Use of this source code is governed by a BSD-style license |
4 | | // that can be found in the COPYING file in the root of the source |
5 | | // tree. An additional intellectual property rights grant can be found |
6 | | // in the file PATENTS. All contributing project authors may |
7 | | // be found in the AUTHORS file in the root of the source tree. |
8 | | // ----------------------------------------------------------------------------- |
9 | | // |
10 | | // Utility functions used by the image decoders. |
11 | | // |
12 | | |
13 | | #include "./imageio_util.h" |
14 | | |
15 | | #if defined(_WIN32) |
16 | | #include <fcntl.h> // for _O_BINARY |
17 | | #include <io.h> // for _setmode() |
18 | | #endif |
19 | | #include <stdlib.h> |
20 | | #include <string.h> |
21 | | #include "../examples/unicode.h" |
22 | | |
23 | | // ----------------------------------------------------------------------------- |
24 | | // File I/O |
25 | | |
26 | 0 | FILE* ImgIoUtilSetBinaryMode(FILE* file) { |
27 | | #if defined(_WIN32) |
28 | | if (_setmode(_fileno(file), _O_BINARY) == -1) { |
29 | | fprintf(stderr, "Failed to reopen file in O_BINARY mode.\n"); |
30 | | return NULL; |
31 | | } |
32 | | #endif |
33 | 0 | return file; |
34 | 0 | } |
35 | | |
36 | 0 | int ImgIoUtilReadFromStdin(const uint8_t** data, size_t* data_size) { |
37 | 0 | static const size_t kBlockSize = 16384; // default initial size |
38 | 0 | size_t max_size = 0; |
39 | 0 | size_t size = 0; |
40 | 0 | uint8_t* input = NULL; |
41 | |
|
42 | 0 | if (data == NULL || data_size == NULL) return 0; |
43 | 0 | *data = NULL; |
44 | 0 | *data_size = 0; |
45 | |
|
46 | 0 | if (!ImgIoUtilSetBinaryMode(stdin)) return 0; |
47 | | |
48 | 0 | while (!feof(stdin)) { |
49 | | // We double the buffer size each time and read as much as possible. |
50 | 0 | const size_t extra_size = (max_size == 0) ? kBlockSize : max_size; |
51 | | // we allocate one extra byte for the \0 terminator |
52 | 0 | void* const new_data = realloc(input, max_size + extra_size + 1); |
53 | 0 | if (new_data == NULL) goto Error; |
54 | 0 | input = (uint8_t*)new_data; |
55 | 0 | max_size += extra_size; |
56 | 0 | size += fread(input + size, 1, extra_size, stdin); |
57 | 0 | if (size < max_size) break; |
58 | 0 | } |
59 | 0 | if (ferror(stdin)) goto Error; |
60 | 0 | if (input != NULL) input[size] = '\0'; // convenient 0-terminator |
61 | 0 | *data = input; |
62 | 0 | *data_size = size; |
63 | 0 | return 1; |
64 | | |
65 | 0 | Error: |
66 | 0 | free(input); |
67 | 0 | fprintf(stderr, "Could not read from stdin\n"); |
68 | 0 | return 0; |
69 | 0 | } |
70 | | |
71 | | int ImgIoUtilReadFile(const char* const file_name, |
72 | 0 | const uint8_t** data, size_t* data_size) { |
73 | 0 | int ok; |
74 | 0 | uint8_t* file_data; |
75 | 0 | size_t file_size; |
76 | 0 | FILE* in; |
77 | 0 | const int from_stdin = (file_name == NULL) || !WSTRCMP(file_name, "-"); |
78 | |
|
79 | 0 | if (from_stdin) return ImgIoUtilReadFromStdin(data, data_size); |
80 | | |
81 | 0 | if (data == NULL || data_size == NULL) return 0; |
82 | 0 | *data = NULL; |
83 | 0 | *data_size = 0; |
84 | |
|
85 | 0 | in = WFOPEN(file_name, "rb"); |
86 | 0 | if (in == NULL) { |
87 | 0 | WFPRINTF(stderr, "cannot open input file '%s'\n", (const W_CHAR*)file_name); |
88 | 0 | return 0; |
89 | 0 | } |
90 | 0 | fseek(in, 0, SEEK_END); |
91 | 0 | file_size = ftell(in); |
92 | 0 | fseek(in, 0, SEEK_SET); |
93 | | // we allocate one extra byte for the \0 terminator |
94 | 0 | file_data = (uint8_t*)WebPMalloc(file_size + 1); |
95 | 0 | if (file_data == NULL) { |
96 | 0 | fclose(in); |
97 | 0 | WFPRINTF(stderr, "memory allocation failure when reading file %s\n", |
98 | 0 | (const W_CHAR*)file_name); |
99 | 0 | return 0; |
100 | 0 | } |
101 | 0 | ok = (fread(file_data, file_size, 1, in) == 1); |
102 | 0 | fclose(in); |
103 | |
|
104 | 0 | if (!ok) { |
105 | 0 | WFPRINTF(stderr, "Could not read %d bytes of data from file %s\n", |
106 | 0 | (int)file_size, (const W_CHAR*)file_name); |
107 | 0 | WebPFree(file_data); |
108 | 0 | return 0; |
109 | 0 | } |
110 | 0 | file_data[file_size] = '\0'; // convenient 0-terminator |
111 | 0 | *data = file_data; |
112 | 0 | *data_size = file_size; |
113 | 0 | return 1; |
114 | 0 | } |
115 | | |
116 | | // ----------------------------------------------------------------------------- |
117 | | |
118 | | int ImgIoUtilWriteFile(const char* const file_name, |
119 | 0 | const uint8_t* data, size_t data_size) { |
120 | 0 | int ok; |
121 | 0 | FILE* out; |
122 | 0 | const int to_stdout = (file_name == NULL) || !WSTRCMP(file_name, "-"); |
123 | |
|
124 | 0 | if (data == NULL) { |
125 | 0 | return 0; |
126 | 0 | } |
127 | 0 | out = to_stdout ? ImgIoUtilSetBinaryMode(stdout) : WFOPEN(file_name, "wb"); |
128 | 0 | if (out == NULL) { |
129 | 0 | WFPRINTF(stderr, "Error! Cannot open output file '%s'\n", |
130 | 0 | (const W_CHAR*)file_name); |
131 | 0 | return 0; |
132 | 0 | } |
133 | 0 | ok = (fwrite(data, data_size, 1, out) == 1); |
134 | 0 | if (out != stdout) fclose(out); |
135 | 0 | return ok; |
136 | 0 | } |
137 | | |
138 | | // ----------------------------------------------------------------------------- |
139 | | |
140 | | void ImgIoUtilCopyPlane(const uint8_t* src, int src_stride, |
141 | 0 | uint8_t* dst, int dst_stride, int width, int height) { |
142 | 0 | while (height-- > 0) { |
143 | 0 | memcpy(dst, src, width * sizeof(*dst)); |
144 | 0 | src += src_stride; |
145 | 0 | dst += dst_stride; |
146 | 0 | } |
147 | 0 | } |
148 | | |
149 | | // ----------------------------------------------------------------------------- |
150 | | |
151 | 9.24k | int ImgIoUtilCheckSizeArgumentsOverflow(uint64_t stride, size_t height) { |
152 | 9.24k | const uint64_t total_size = stride * height; |
153 | 9.24k | int ok = (total_size == (size_t)total_size); |
154 | | // check that 'stride' is representable as int: |
155 | 9.24k | ok = ok && ((uint64_t)(int)stride == stride); |
156 | 9.24k | #if defined(WEBP_MAX_IMAGE_SIZE) |
157 | 9.24k | ok = ok && (total_size <= (uint64_t)WEBP_MAX_IMAGE_SIZE); |
158 | 9.24k | #endif |
159 | 9.24k | return ok; |
160 | 9.24k | } |
161 | | |
162 | | // ----------------------------------------------------------------------------- |