size_t os_fread_mbs(FILE *file, char **pstr) { size_t size = 0; size_t len = 0; fseek(file, 0, SEEK_END); size = (size_t)os_ftelli64(file); *pstr = NULL; if (size > 0) { char *mbstr = bmalloc(size+1); fseek(file, 0, SEEK_SET); size = fread(mbstr, 1, size, file); if (size == 0) { bfree(mbstr); return 0; } mbstr[size] = 0; len = os_mbs_to_utf8_ptr(mbstr, size, pstr); bfree(mbstr); } return len; }
int64_t os_fgetsize(FILE *file) { int64_t cur_offset = os_ftelli64(file); int64_t size; int errval = 0; if (fseek(file, 0, SEEK_END) == -1) return -1; size = os_ftelli64(file); if (size == -1) errval = errno; if (os_fseeki64(file, cur_offset, SEEK_SET) != 0 && errval != 0) errno = errval; return size; }
static void flv_output_stop(void *data) { struct flv_output *stream = data; if (stream->active) { if (stream->file) write_file_info(stream->file, stream->last_packet_ts, os_ftelli64(stream->file)); fclose(stream->file); obs_output_end_data_capture(stream->output); stream->active = false; stream->sent_headers = false; info("FLV file output complete"); } }
size_t os_fread_utf8(FILE *file, char **pstr) { size_t size = 0; size_t len = 0; *pstr = NULL; fseek(file, 0, SEEK_END); size = (size_t)os_ftelli64(file); if (size > 0) { char bom[3]; char *utf8str; off_t offset; bom[0] = 0; bom[1] = 0; bom[2] = 0; /* remove the ghastly BOM if present */ fseek(file, 0, SEEK_SET); fread(bom, 1, 3, file); offset = (astrcmp_n(bom, "\xEF\xBB\xBF", 3) == 0) ? 3 : 0; size -= offset; if (size == 0) return 0; utf8str = bmalloc(size+1); fseek(file, offset, SEEK_SET); size = fread(utf8str, 1, size, file); if (size == 0) { bfree(utf8str); return 0; } utf8str[size] = 0; *pstr = utf8str; } return len; }
static bool init_animated_gif(gs_image_file_t *image, const char *path) { bool is_animated_gif = true; gif_result result; uint64_t max_size; size_t size; FILE *file; image->bitmap_callbacks.bitmap_create = bi_def_bitmap_create; image->bitmap_callbacks.bitmap_destroy = bi_def_bitmap_destroy; image->bitmap_callbacks.bitmap_get_buffer = bi_def_bitmap_get_buffer; image->bitmap_callbacks.bitmap_modified = bi_def_bitmap_modified; image->bitmap_callbacks.bitmap_set_opaque = bi_def_bitmap_set_opaque; image->bitmap_callbacks.bitmap_test_opaque = bi_def_bitmap_test_opaque; gif_create(&image->gif, &image->bitmap_callbacks); file = os_fopen(path, "rb"); if (!file) { blog(LOG_WARNING, "Failed to open file '%s'", path); goto fail; } fseek(file, 0, SEEK_END); size = (size_t)os_ftelli64(file); fseek(file, 0, SEEK_SET); image->gif_data = bmalloc(size); fread(image->gif_data, 1, size, file); do { result = gif_initialise(&image->gif, size, image->gif_data); if (result < 0) { blog(LOG_WARNING, "Failed to initialize gif '%s', " "possible file corruption", path); goto fail; } } while (result != GIF_OK); if (image->gif.width > 4096 || image->gif.height > 4096) { blog(LOG_WARNING, "Bad texture dimensions (%dx%d) in '%s'", image->gif.width, image->gif.height, path); goto fail; } max_size = (uint64_t)image->gif.width * (uint64_t)image->gif.height * (uint64_t)image->gif.frame_count * 4LLU; if ((uint64_t)get_full_decoded_gif_size(image) != max_size) { blog(LOG_WARNING, "Gif '%s' overflowed maximum pointer size", path); goto fail; } image->is_animated_gif = (image->gif.frame_count > 1 && result >= 0); if (image->is_animated_gif) { gif_decode_frame(&image->gif, 0); image->animation_frame_cache = bzalloc( image->gif.frame_count * sizeof(uint8_t*)); image->animation_frame_data = bzalloc( get_full_decoded_gif_size(image)); for (unsigned int i = 0; i < image->gif.frame_count; i++) { if (gif_decode_frame(&image->gif, i) != GIF_OK) blog(LOG_WARNING, "Couldn't decode frame %u " "of '%s'", i, path); } gif_decode_frame(&image->gif, 0); image->cx = (uint32_t)image->gif.width; image->cy = (uint32_t)image->gif.height; image->format = GS_RGBA; } else { gif_finalise(&image->gif); bfree(image->gif_data); image->gif_data = NULL; is_animated_gif = false; goto not_animated; } image->loaded = true; fail: if (!image->loaded) gs_image_file_free(image); not_animated: if (file) fclose(file); return is_animated_gif; }