| 121 | } |
| 122 | |
| 123 | int main(int argc, char * argv[]) |
| 124 | { |
| 125 | if (argc != 2) { |
| 126 | fprintf(stderr, "avif_example_decode_streaming [filename.avif]\n"); |
| 127 | return 1; |
| 128 | } |
| 129 | const char * inputFilename = argv[1]; |
| 130 | |
| 131 | int returnCode = 1; |
| 132 | avifDecoder * decoder = NULL; |
| 133 | |
| 134 | // Read entire file into fileBuffer |
| 135 | FILE * f = NULL; |
| 136 | uint8_t * fileBuffer = NULL; |
| 137 | f = fopen(inputFilename, "rb"); |
| 138 | if (!f) { |
| 139 | fprintf(stderr, "Cannot open file for read: %s\n", inputFilename); |
| 140 | goto cleanup; |
| 141 | } |
| 142 | fseek(f, 0, SEEK_END); |
| 143 | long fileSize = ftell(f); |
| 144 | if (fileSize < 0) { |
| 145 | fprintf(stderr, "Truncated file: %s\n", inputFilename); |
| 146 | goto cleanup; |
| 147 | } |
| 148 | fseek(f, 0, SEEK_SET); |
| 149 | fileBuffer = malloc(fileSize); |
| 150 | long bytesRead = (long)fread(fileBuffer, 1, fileSize, f); |
| 151 | if (bytesRead != fileSize) { |
| 152 | fprintf(stderr, "Cannot read file: %s\n", inputFilename); |
| 153 | goto cleanup; |
| 154 | } |
| 155 | |
| 156 | decoder = avifDecoderCreate(); |
| 157 | if (!decoder) { |
| 158 | fprintf(stderr, "Memory allocation failure\n"); |
| 159 | goto cleanup; |
| 160 | } |
| 161 | // Override decoder defaults here (codecChoice, requestedSource, ignoreExif, ignoreXMP, etc) |
| 162 | |
| 163 | avifIOStreamingReader * io = avifIOCreateStreamingReader(fileBuffer, fileSize); |
| 164 | if (!io) { |
| 165 | fprintf(stderr, "Memory allocation failure\n"); |
| 166 | goto cleanup; |
| 167 | } |
| 168 | avifDecoderSetIO(decoder, (avifIO *)io); |
| 169 | |
| 170 | for (int pass = 0; pass < 2; ++pass) { |
| 171 | // This shows the difference in how much data avifDecoderParse() needs from the file |
| 172 | // depending on whether or not Exif/XMP metadata is necessary. If the caller plans to |
| 173 | // interpret this metadata, avifDecoderParse() will continue to return |
| 174 | // AVIF_RESULT_WAITING_ON_IO until it has those payloads in their entirety (if they exist). |
| 175 | decoder->ignoreExif = decoder->ignoreXMP = (pass > 0); |
| 176 | |
| 177 | // Slowly pretend to have streamed-in / downloaded more and more bytes by incrementing io->downloadedBytes |
| 178 | avifResult parseResult = AVIF_RESULT_UNKNOWN_ERROR; |
| 179 | for (io->downloadedBytes = 0; io->downloadedBytes <= io->io.sizeHint; ++io->downloadedBytes) { |
| 180 | parseResult = avifDecoderParse(decoder); |
nothing calls this directly
no test coverage detected