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