2014年8月23日土曜日

グレースケール

初めて画像処理をアセンブラで書いてみた
アセンブラでロジックを書くのは初めてかな
#include <cstdint>
#include <fstream>

using namespace std;

int main()
{
    static const int IMG_HEADER_SIZE = 54;
    uint8_t* hdr = new uint8_t[IMG_HEADER_SIZE];
    memset(hdr, 0, IMG_HEADER_SIZE);

    static const int IMG_DATA_SIZE = 1024*768*3; 
    uint8_t* img = new uint8_t[IMG_DATA_SIZE];
    memset(img, 0, IMG_DATA_SIZE);

    ifstream input_file("C:\\Users\\xxxxx\\Desktop\\Desert.bmp", ios::binary);
    input_file.read(reinterpret_cast<char*>(hdr), IMG_HEADER_SIZE);
    input_file.read(reinterpret_cast<char*>(img), IMG_DATA_SIZE);

    for (int i = 0; i < IMG_DATA_SIZE; i+=3)
    {
        static const int GS_R8_WEIGHT = static_cast<int>(0.298912 * 256);
        static const int GS_G8_WEIGHT = static_cast<int>(0.586611 * 256);
        static const int GS_B8_WEIGHT = static_cast<int>(0.114478 * 256);

        uint8_t r8 = img[i+0];
        uint8_t g8 = img[i+1];
        uint8_t b8 = img[i+2];
        uint16_t tmp1;
        uint8_t result;

        __asm
        {
            mov tmp1, 0x00

            mov ah, 0
            mov al, r8
            mul GS_R8_WEIGHT
            mov tmp1, ax

            mov ah, 0
            mov al, g8
            mul GS_G8_WEIGHT
            add tmp1, ax

            mov ah, 0
            mov al, b8
            mul GS_B8_WEIGHT
            add tmp1, ax
        
            shr tmp1, 8
            push tmp1
            pop result
        }

        img[i+0] = result;
        img[i+1] = result;
        img[i+2] = result;
    }

    ofstream output_file("C:\\Users\\xxxxx\\Desktop\\Desert_grayscale.bmp", ios::binary);
    output_file.write(reinterpret_cast<char*>(hdr), IMG_HEADER_SIZE);
    output_file.write(reinterpret_cast<char*>(img), IMG_DATA_SIZE);
    output_file.close();

    delete[] hdr;
    delete[] img;

    return 0;
}

0 件のコメント:

コメントを投稿

SQL で MP4 をパース

SQL でビットマップ画像の2値化は4年位前に挑戦した。 最近、それの Impala 版 を作ったときに閃いた。 「再帰CTEがあるなら、mp4 もいけるんじゃないか」と。 やってみた。 use ragingo drop table video go create...