スポンサーリンク

libavifを試す(4) avifファイルを入力

avifファイルを入力するサンプルコードを書いた。

 

#pragma comment(lib, "avif.lib")

// 4996無効
#define _CRT_SECURE_NO_WARNINGS


#include <iostream>
#include <avif/avif.h>
#include <vector>

void pnmP3_Write(const char* const fname, const int width, const int height, const unsigned char* const p);


///////////////////////////////////////////////////
///////////////////////////////////////////////////
///////////////////////////////////////////////////
// libavif で RGBデータをavifデータに変換する


int main()
{
    ///////////////////////////////////////////////
    // avifのデコーダ
    avifDecoder* decoder = avifDecoderCreate();

    ///////////////////////////////////////////////
    FILE* f = fopen(R"(output.avif)", "rb");
    // avifファイルを全て読み込む
    fseek(f, 0, SEEK_END);
    long fsize = ftell(f);
    fseek(f, 0, SEEK_SET);  //same as rewind(f);
    void* fileBuffer = malloc(fsize);
    long bytesRead = (long)fread(fileBuffer, 1, fsize, f);

    ///////////////////////////////////////////////
    avifResult result;
    result = avifDecoderSetIOMemory(decoder, (uint8_t*)fileBuffer, fsize);
    result = avifDecoderParse(decoder);
    ///////////////////////////////////////////////
    // デコード結果を取得する
    printf("Parsed AVIF: %ux%u (%ubpc)\n", decoder->image->width, decoder->image->height, decoder->image->depth);

    ///////////////////////////////////////////////
    // avifは複数の画像を持つことができるので、画像一枚ごとにループする
    while (avifDecoderNextImage(decoder) == AVIF_RESULT_OK) {

        ///////////////////////////////////////////////
        avifRGBImage rgb;
        memset(&rgb, 0, sizeof(rgb));
        avifRGBImageSetDefaults(&rgb, decoder->image);
        ///////////////////////////////////////////////
        avifRGBImageAllocatePixels(&rgb);
        avifImageYUVToRGB(decoder->image, &rgb);
        ///////////////////////////////////////////////
        if (rgb.depth <= 8) {
            uint8_t* firstPixel = (uint8_t*)rgb.pixels;

            // 1画素4byteで格納されているので、 以下で画素を取得
            //r = firstPixel[i*4 + 0]
            //g = firstPixel[i*4 + 1]
            //b = firstPixel[i*4 + 2]

            pnmP3_Write("output.ppm", rgb.width, rgb.height, firstPixel);// ファイルに保存

        }
    }

    return 0;
}

//! @brief PPM(RGB各1byte,カラー,テキスト)を書き込む
//! @param [in] fname ファイル名
//! @param [in] width 画像の幅
//! @param [in] height 画像の高さ
//! @param [in] p 画像のメモリへのアドレス
//! @details RGBRGBRGB....のメモリを渡すと、RGBテキストでファイル名fnameで書き込む
void pnmP3_Write(const char* const fname, const int width, const int height, const unsigned char* const p) { // PPM ASCII

    FILE* fp = fopen(fname, "wb");
    fprintf(fp, "P3\n%d %d\n%d\n", width, height, 255);

    size_t k = 0;
    for (size_t i = 0; i < (size_t)height; i++) {
        for (size_t j = 0; j < (size_t)width; j++) {
            fprintf(fp, "%d %d %d ", p[k * 4 + 0], p[k * 4 + 1], p[k * 4 + 2]);
            k++;
        }
        fprintf(fp, "\n");
    }

    fclose(fp);
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: