#define _CRT_SECURE_NO_WARNINGS#include <limits.h> // for XXX_MAX#include <memory.h> // for memset, memcpy#include <stdio.h> // for FILE#include "avif/avif.h"#pragma comment(linker, "/export:avifFree")static void copyRows(char* dst, const char* src, const int width, const int srcWidthStride, const int height) {for (int y = 0; y < height; y++) {memcpy(dst, src, width);dst += width;src += srcWidthStride;}}extern "C" __declspec(dllexport) int __cdecl avifDecode(const void* const pSrcData, const int srcSize,void** const ppDstData, int* const pDstWidth, int* const pDstHeight, int* const pDstDepth) {if (ppDstData)*ppDstData = 0;if (pDstWidth)*pDstWidth = 0;if (pDstHeight)*pDstHeight = 0;if (pDstDepth)*pDstDepth = 0;if (!pSrcData)return -1;if (srcSize <= 0)return -2;avifDecoder* const decoder = avifDecoderCreate();if (!decoder)return -3;decoder->strictFlags = AVIF_STRICT_DISABLED;decoder->codecChoice = AVIF_CODEC_CHOICE_DAV1D;avifResult r = avifDecoderSetIOMemory(decoder, (const uint8_t*)pSrcData, (size_t)srcSize);if (r != AVIF_RESULT_OK) {avifDecoderDestroy(decoder);return -100 - r;}r = avifDecoderParse(decoder);if (r != AVIF_RESULT_OK) {avifDecoderDestroy(decoder);return -200 - r;}if (decoder->imageCount < 1) {avifDecoderDestroy(decoder);return -4;}r = avifDecoderNextImage(decoder);if (r != AVIF_RESULT_OK) {avifDecoderDestroy(decoder);return -300 - r;}const avifImage* const image = decoder->image;if (pDstWidth)*pDstWidth = (int)image->width;if (pDstHeight)*pDstHeight = (int)image->height;int depth = image->alphaPlane != 0;if (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400)depth++;else if (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV420|| image->yuvFormat == AVIF_PIXEL_FORMAT_YUV444|| image->yuvFormat == AVIF_PIXEL_FORMAT_YUV422)depth += 3;if (pDstDepth)*pDstDepth = depth;if (ppDstData && depth > 0) {void* const pDstData = avifAlloc((size_t)image->width * image->height * depth);if (!pDstData) {avifDecoderDestroy(decoder);return -5;}if (depth == 1) {if (image->depth > 8) { //TODOavifFree(pDstData);avifDecoderDestroy(decoder);return -6;}if (image->yuvFormat == AVIF_PIXEL_FORMAT_YUV400) {copyRows((char*)pDstData, (const char*)image->yuvPlanes[AVIF_CHAN_Y],image->width, image->yuvRowBytes[AVIF_CHAN_Y], image->height);} else {copyRows((char*)pDstData, (const char*)image->alphaPlane,image->width, image->alphaRowBytes, image->height);}} else if (depth == 2) { //TODOavifFree(pDstData);avifDecoderDestroy(decoder);return -7;} else {avifRGBImage rgb;memset(&rgb, 0, sizeof(rgb));avifRGBImageSetDefaults(&rgb, image);rgb.depth = 8;rgb.format = depth == 3 ? AVIF_RGB_FORMAT_RGB : AVIF_RGB_FORMAT_RGBA;rgb.pixels = (uint8_t*)pDstData;rgb.rowBytes = image->width * depth;r = avifImageYUVToRGB(image, &rgb);if (r != AVIF_RESULT_OK) {avifFree(pDstData);avifDecoderDestroy(decoder);return -400 - r;}}*ppDstData = pDstData;}avifDecoderDestroy(decoder);return 0;}struct avifIOEx : avifIO {FILE* fp;uint64_t offset;avifRWData buffer;};static void avifIOExDestroy(avifIO* const io) {avifIOEx* const reader = (avifIOEx*)io;if (reader->fp) {fclose(reader->fp);reader->fp = 0;}avifRWDataFree(&reader->buffer);avifFree(io);}static avifResult avifIOExRead(avifIO* const io, const uint32_t readFlags, const uint64_t offset, size_t size, avifROData* const out) {if (readFlags != 0)return AVIF_RESULT_IO_ERROR; // unsupportedavifIOEx* const reader = (avifIOEx*)io;if (!reader->fp || offset > reader->sizeHint)return AVIF_RESULT_IO_ERROR; // past the EOFconst size_t availableSize = (size_t)(reader->sizeHint - offset);if (size > availableSize)size = availableSize;if (size > 0) {if (offset > LONG_MAX)return AVIF_RESULT_IO_ERROR;if (reader->buffer.size < size) {const avifResult r = avifRWDataRealloc(&reader->buffer, size);if (r != AVIF_RESULT_OK)return r;}#ifdef _MSC_VERif (_fseeki64(reader->fp, (__int64)(reader->offset + offset), SEEK_SET) != 0)#elseif (fseek(reader->fp, (long)(reader->offset + offset), SEEK_SET) != 0)#endifreturn AVIF_RESULT_IO_ERROR;const size_t bytesRead = fread(reader->buffer.data, 1, size, reader->fp);if (size != bytesRead) {if (ferror(reader->fp))return AVIF_RESULT_IO_ERROR;size = bytesRead;}}out->data = reader->buffer.data;out->size = size;return AVIF_RESULT_OK;}extern "C" __declspec(dllexport) avifDecoder* __cdecl avifOpenFile(const char* const filename, const uint64_t offset, uint64_t size) {avifIOEx* const reader = (avifIOEx*)avifAlloc(sizeof(avifIOEx));if (!reader)return (avifDecoder*)-1LL;memset(reader, 0, sizeof(*reader));reader->fp = fopen(filename, "rb");if (!reader->fp) {avifIOExDestroy(reader);return (avifDecoder*)-2LL;}if ((int64_t)size < 0) {fseek(reader->fp, 0, SEEK_END);#ifdef _MSC_VERsize = (uint64_t)_ftelli64(reader->fp);#elsesize = (uint64_t)ftell(reader->fp);#endifsize -= offset;if ((int64_t)size < 0) {avifIOExDestroy(reader);return (avifDecoder*)-3LL;}}reader->offset = offset;reader->destroy = avifIOExDestroy;reader->read = avifIOExRead;reader->sizeHint = size;reader->persistent = AVIF_FALSE;if (avifRWDataRealloc(&reader->buffer, 1024) != AVIF_RESULT_OK) {avifIOExDestroy(reader);return (avifDecoder*)-4LL;}avifDecoder* const decoder = avifDecoderCreate();if (!decoder) {avifIOExDestroy(reader);return (avifDecoder*)-5LL;}decoder->strictFlags = AVIF_STRICT_DISABLED;decoder->codecChoice = AVIF_CODEC_CHOICE_DAV1D;if ((int64_t)decoder < 0) {avifDecoderDestroy(decoder);avifIOExDestroy(reader);return (avifDecoder*)-6LL;}avifDecoderSetIO(decoder, reader);const avifResult r = avifDecoderParse(decoder);if (r != AVIF_RESULT_OK) {avifDecoderDestroy(decoder);return (avifDecoder*)(-100LL - r);}return decoder;}extern "C" __declspec(dllexport) int __cdecl avifDecodeFile(avifDecoder* const decoder, const int frameIdx) {if ((int64_t)decoder < 0)return -1;const avifResult r = frameIdx >= 0 ? avifDecoderNthImage(decoder, frameIdx) : avifDecoderNextImage(decoder);if (r != AVIF_RESULT_OK) {avifDecoderDestroy(decoder);return -100 - r;}return 0;}extern "C" __declspec(dllexport) void __cdecl avifCloseFile(avifDecoder* const decoder) {if ((int64_t)decoder > 0)avifDecoderDestroy(decoder);}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。