Drake's Weblog

2 minute read

因為不知名的原因,The Foundry 並沒有在 Nuke 裏頭支援 .BMP。雖然說,.BMP 是個一點都不專業,用了它,還可能讓對方把你瞧低了的格式,但很不幸地,我們因為一些使用到的程式,不得不去處理 .BMP。在這個情況下,我又希望能保有使用 Nuke 的便利與強大,但又不想三不五時就使用 ImageMagick 的 convert 來轉檔(太慢了,尤其是當圖檔有上千上萬張的時候)的前提下,我用 FreeImage 給 Nuke 寫了個 bmpReader。

希望對某些人,也有幫上一點唯不足道的忙~

#include <stdio.h>
#include <string.h>

#include <freeimage.h>

#include "DDImage/DDWindows.h"
#include "DDImage/Reader.h"
#include "DDImage/Row.h"
#include "DDImage/Knob.h"
#include "DDImage/Knobs.h"
#include "DDImage/Thread.h"
#include "DDImage/Memory.h"

using namespace DD::Image;

class BmpReader : public Reader
{
    private:
        unsigned int m_bpp;
        unsigned int m_width;
        unsigned int m_height;
        FIBITMAP* m_bitmap;

        FreeImageIO m_io;
    public:
        BmpReader(Read*);
        ~BmpReader();

        void engine(int y, int x, int r, ChannelMask, Row&);
        static const Description d;
};

BmpReader::BmpReader(Read* r) : Reader(r)
{
    FreeImage_Initialise(TRUE);

    m_bpp = 0;
    m_width = 0;
    m_height = 0;

    m_bitmap = FreeImage_Load(FIF_BMP, filename(), BMP_DEFAULT);
    if( m_bitmap ) {
        m_bpp = FreeImage_GetBPP(m_bitmap);
        m_width = FreeImage_GetWidth(m_bitmap);
        m_height = FreeImage_GetHeight(m_bitmap);

        //printf("bpp: %d\n", m_bpp);
        //printf("width: %d\n", m_width);
        //printf("height: %d\n", m_height);

        set_info(m_width, m_height, m_bpp/8);
    }
    else {
    }
}

BmpReader::~BmpReader()
{
    if( m_bitmap ) {
        FreeImage_Unload(m_bitmap);
        m_bitmap = NULL;
    }
    FreeImage_DeInitialise();
}

void BmpReader::engine(int y, int x, int r, ChannelMask channels, Row& row)
{
    BYTE* pixel = FreeImage_GetScanLine(m_bitmap, y);

    // BGR !!!!
    if( channels & Mask_Blue ) {
        from_byte(Chan_Blue, row.writable(Chan_Blue)+x, pixel+0, NULL, r-x, m_bpp/8);
    }
    if( channels & Mask_Green ) {
        from_byte(Chan_Green, row.writable(Chan_Green)+x, pixel+1, NULL, r-x, m_bpp/8);
    }
    if( channels & Mask_Red ) {
        from_byte(Chan_Red, row.writable(Chan_Red)+x, pixel+2, NULL, r-x, m_bpp/8);
    }
}

static Reader* build(Read* iop, int fd, const unsigned char* b, int n)
{
    close(fd);
    return new BmpReader(iop);
}

static bool test(int fd, const unsigned char* block, int length)
{
    FreeImage_Initialise(TRUE);
    FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
    FIMEMORY* hmem = FreeImage_OpenMemory((BYTE *)block, length);
    fif = FreeImage_GetFileTypeFromMemory(hmem);
    FreeImage_DeInitialise();

    return(fif == FIF_BMP);
}

const Reader::Description BmpReader::d("bmp\0", build, test);

// vim: set hls is si et sw=4 sts=4 nu:
comments powered by Disqus

Recent posts

Categories

About

You're looking at Drake's words or statements. All opinions are my own.