代码拉取完成,页面将自动刷新
#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) { //TODO
avifFree(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) { //TODO
avifFree(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; // unsupported
avifIOEx* const reader = (avifIOEx*)io;
if (!reader->fp || offset > reader->sizeHint)
return AVIF_RESULT_IO_ERROR; // past the EOF
const 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_VER
if (_fseeki64(reader->fp, (__int64)(reader->offset + offset), SEEK_SET) != 0)
#else
if (fseek(reader->fp, (long)(reader->offset + offset), SEEK_SET) != 0)
#endif
return 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_VER
size = (uint64_t)_ftelli64(reader->fp);
#else
size = (uint64_t)ftell(reader->fp);
#endif
size -= 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);
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。