1 /*
2 * H.265 video codec.
3 * Copyright (c) 2013-2014 struktur AG, Dirk Farin <farin@struktur.de>
4 *
5 * Authors: struktur AG, Dirk Farin <farin@struktur.de>
6 *
7 * This file is part of libde265.
8 *
9 * libde265 is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation, either version 3 of
12 * the License, or (at your option) any later version.
13 *
14 * libde265 is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
18 *
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with libde265. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include "libde265/image-io.h"
24 #include <assert.h>
25
26
~ImageSource_YUV()27 ImageSource_YUV::~ImageSource_YUV()
28 {
29 if (mFH) {
30 fclose(mFH);
31 }
32 }
33
34
set_input_file(const char * filename,int w,int h)35 bool ImageSource_YUV::set_input_file(const char* filename, int w,int h)
36 {
37 assert(mFH==NULL);
38
39 mFH = fopen(filename,"rb");
40 if (mFH==NULL) {
41 return false;
42 }
43
44 width =w;
45 height=h;
46 mReachedEndOfFile = false;
47
48 return true;
49 }
50
51
read_next_image()52 de265_image* ImageSource_YUV::read_next_image()
53 {
54 if (mReachedEndOfFile) return NULL;
55
56 de265_image* img = new de265_image;
57 img->alloc_image(width,height,de265_chroma_420, NULL, false,
58 NULL, NULL, 0, NULL, false);
59 assert(img); // TODO: error handling
60
61 // --- load image ---
62
63 uint8_t* p;
64 int stride;
65
66 p = img->get_image_plane(0); stride = img->get_image_stride(0);
67 for (int y=0;y<height;y++) {
68 if (fread(p+y*stride,1,width,mFH) != width) {
69 goto check_eof;
70 }
71 }
72
73 p = img->get_image_plane(1); stride = img->get_image_stride(1);
74 for (int y=0;y<height/2;y++) {
75 if (fread(p+y*stride,1,width/2,mFH) != width/2) {
76 goto check_eof;
77 }
78 }
79
80 p = img->get_image_plane(2); stride = img->get_image_stride(2);
81 for (int y=0;y<height/2;y++) {
82 if (fread(p+y*stride,1,width/2,mFH) != width/2) {
83 goto check_eof;
84 }
85 }
86
87 // --- check for EOF ---
88
89 check_eof:
90 if (feof(mFH)) {
91 mReachedEndOfFile = true;
92 delete img;
93 return NULL;
94 }
95 else {
96 return img;
97 }
98 }
99
100
101 /*
102 ImageSource::ImageStatus ImageSource_YUV::get_status()
103 {
104 return Available;
105 }
106 */
107
get_image(bool block)108 de265_image* ImageSource_YUV::get_image(bool block)
109 {
110 de265_image* img = read_next_image();
111 return img;
112 }
113
114
skip_frames(int n)115 void ImageSource_YUV::skip_frames(int n)
116 {
117 int imageSize = width*height*3/2;
118 fseek(mFH,n * imageSize, SEEK_CUR);
119 }
120
121
122
123
~ImageSink_YUV()124 ImageSink_YUV::~ImageSink_YUV()
125 {
126 if (mFH) {
127 fclose(mFH);
128 }
129 }
130
set_filename(const char * filename)131 bool ImageSink_YUV::set_filename(const char* filename)
132 {
133 assert(mFH==NULL);
134
135 mFH = fopen(filename,"wb");
136
137 return true;
138 }
139
send_image(const de265_image * img)140 void ImageSink_YUV::send_image(const de265_image* img)
141 {
142 // --- write image ---
143
144 const uint8_t* p;
145 int stride;
146
147 int width = img->get_width();
148 int height= img->get_height();
149
150 p = img->get_image_plane(0); stride = img->get_image_stride(0);
151 for (int y=0;y<height;y++) {
152 fwrite(p+y*stride,1,width,mFH);
153 }
154
155 p = img->get_image_plane(1); stride = img->get_image_stride(1);
156 for (int y=0;y<height/2;y++) {
157 fwrite(p+y*stride,1,width/2,mFH);
158 }
159
160 p = img->get_image_plane(2); stride = img->get_image_stride(2);
161 for (int y=0;y<height/2;y++) {
162 fwrite(p+y*stride,1,width/2,mFH);
163 }
164 }
165
166
167
~PacketSink_File()168 LIBDE265_API PacketSink_File::~PacketSink_File()
169 {
170 if (mFH) {
171 fclose(mFH);
172 }
173 }
174
175
set_filename(const char * filename)176 LIBDE265_API void PacketSink_File::set_filename(const char* filename)
177 {
178 assert(mFH==NULL);
179
180 mFH = fopen(filename,"wb");
181 }
182
183
send_packet(const uint8_t * data,int n)184 LIBDE265_API void PacketSink_File::send_packet(const uint8_t* data, int n)
185 {
186 uint8_t startCode[3];
187 startCode[0] = 0;
188 startCode[1] = 0;
189 startCode[2] = 1;
190
191 fwrite(startCode,1,3,mFH);
192 fwrite(data,1,n,mFH);
193 fflush(mFH);
194 }
195