Index: source/libvpx/y4minput.c |
=================================================================== |
--- source/libvpx/y4minput.c (revision 263011) |
+++ source/libvpx/y4minput.c (working copy) |
@@ -10,10 +10,45 @@ |
* Based on code from the OggTheora software codec source code, |
* Copyright (C) 2002-2010 The Xiph.Org Foundation and contributors. |
*/ |
+#include <errno.h> |
#include <stdlib.h> |
#include <string.h> |
+ |
+#include "vpx/vpx_integer.h" |
#include "y4minput.h" |
+// Reads 'size' bytes from 'file' into 'buf' with some fault tolerance. |
+// Returns true on success. |
+static int file_read(void *buf, size_t size, FILE *file) { |
+ const int kMaxRetries = 5; |
+ int retry_count = 0; |
+ int file_error; |
+ size_t len = 0; |
+ do { |
+ const size_t n = fread((uint8_t*)buf + len, 1, size - len, file); |
+ len += n; |
+ file_error = ferror(file); |
+ if (file_error) { |
+ if (errno == EINTR || errno == EAGAIN) { |
+ clearerr(file); |
+ continue; |
+ } else { |
+ fprintf(stderr, "Error reading file: %u of %u bytes read, %d: %s\n", |
+ (uint32_t)len, (uint32_t)size, errno, strerror(errno)); |
+ return 0; |
+ } |
+ } |
+ } while (!feof(file) && len < size && ++retry_count < kMaxRetries); |
+ |
+ if (!feof(file) && len != size) { |
+ fprintf(stderr, "Error reading file: %u of %u bytes read," |
+ " error: %d, retries: %d, %d: %s\n", |
+ (uint32_t)len, (uint32_t)size, file_error, retry_count, |
+ errno, strerror(errno)); |
+ } |
+ return len == size; |
+} |
+ |
static int y4m_parse_tags(y4m_input *_y4m, char *_tags) { |
int got_w; |
int got_h; |
@@ -670,8 +705,7 @@ |
buffer[i] = *_skip++; |
_nskip--; |
} else { |
- ret = (int)fread(buffer + i, 1, 1, _fin); |
- if (ret < 1)return -1; |
+ if (!file_read(buffer + i, 1, _fin)) return -1; |
} |
if (buffer[i] == '\n')break; |
} |
@@ -853,10 +887,8 @@ |
int c_w; |
int c_h; |
int c_sz; |
- int ret; |
/*Read and skip the frame header.*/ |
- ret = (int)fread(frame, 1, 6, _fin); |
- if (ret < 6)return 0; |
+ if (!file_read(frame, 6, _fin)) return 0; |
if (memcmp(frame, "FRAME", 5)) { |
fprintf(stderr, "Loss of framing in Y4M input data\n"); |
return -1; |
@@ -864,19 +896,19 @@ |
if (frame[5] != '\n') { |
char c; |
int j; |
- for (j = 0; j < 79 && fread(&c, 1, 1, _fin) && c != '\n'; j++); |
+ for (j = 0; j < 79 && file_read(&c, 1, _fin) && c != '\n'; j++) {} |
if (j == 79) { |
fprintf(stderr, "Error parsing Y4M frame header\n"); |
return -1; |
} |
} |
/*Read the frame data that needs no conversion.*/ |
- if (fread(_y4m->dst_buf, 1, _y4m->dst_buf_read_sz, _fin) != _y4m->dst_buf_read_sz) { |
+ if (!file_read(_y4m->dst_buf, _y4m->dst_buf_read_sz, _fin)) { |
fprintf(stderr, "Error reading Y4M frame data.\n"); |
return -1; |
} |
/*Read the frame data that does need conversion.*/ |
- if (fread(_y4m->aux_buf, 1, _y4m->aux_buf_read_sz, _fin) != _y4m->aux_buf_read_sz) { |
+ if (!file_read(_y4m->aux_buf, _y4m->aux_buf_read_sz, _fin)) { |
fprintf(stderr, "Error reading Y4M frame data.\n"); |
return -1; |
} |