因為不知名的原因,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: