// 写入一个字符到 buffer
void
writeToBuffer(unsigned char ch)
{
    buffer[bufferpos] = ch;
    bufferpos++;
    if (bufferpos == BUFFERSIZE) // 缓冲区满了
    {
        commitBuffer(BUFFERSIZE);
        bufferpos = 0;
    }
}
Variable blendExpression::evaluate()
{
	ImageObject* bottom = store->getImage();
	Variable topVar = arguments[0]->getResult();
	ImageObject* top = topVar.get<ImageObject>();

	setLocalVariable("x", &x);
	setLocalVariable("y", &y);
	setLocalVariable("r1", &r1);
	setLocalVariable("g1", &g1);
	setLocalVariable("b1", &b1);
	setLocalVariable("h1", &h1);
	setLocalVariable("s1", &s1);
	setLocalVariable("v1", &v1);
	setLocalVariable("a1", &a1);
	setLocalVariable("r2", &r2);
	setLocalVariable("g2", &g2);
	setLocalVariable("b2", &b2);
	setLocalVariable("h2", &h2);
	setLocalVariable("s2", &s2);
	setLocalVariable("v2", &v2);
	setLocalVariable("a2", &a2);

	for (int cx = 0; cx < std::min(top->getWidth(),bottom->getWidth()); cx++)
		for (int cy = 0; cy < std::min(top->getHeight(), bottom->getHeight()); cy++)
		{
			x = cx;
			y = cy;
			if (store->mask->getValue(cx, cy) > 0)
			{
				Colour b = bottom->getPixel(cx, cy);
				r1 = (float)b.r();
				g1 = (float)b.g();
				b1 = (float)b.b();
				h1 = (float)b.h();
				s1 = (float)b.s();
				v1 = (float)b.v();
				a1 = (float)b.a();
				Colour t = top->getPixel(cx, cy);
				r2 = (float)t.r();
				g2 = (float)t.g();
				b2 = (float)t.b();
				h2 = (float)t.h();
				s2 = (float)t.s();
				v2 = (float)t.v();
				a2 = (float)t.a();
				Variable col = arguments[1]->getResult();
				buffer->setPixel(cx, cy, *col.get<Colour>());
			}

		}
	commitBuffer();
	return Variable();
}
void ViewBackend::handleMessage(char* data, size_t size)
{
    if (size != IPC::Message::size)
        return;

    auto& message = IPC::Message::cast(data);
    switch (message.messageCode) {
    case IPC::BCMRPi::BufferCommit::code:
    {
        auto& bufferCommit = IPC::BCMRPi::BufferCommit::cast(message);
        commitBuffer(bufferCommit.handle, bufferCommit.width, bufferCommit.height);
        break;
    }
    default:
        fprintf(stderr, "ViewBackend: unhandled message\n");
    }
}
int
main(int argc, char ** argv)
{
    if (argc != 4) // 检查参数数量
    {
        showUsage();
        return 1;
    }
    else
    {
        filename = argv[1];
        // 判断文件名的后缀是不是 ".hfm"
        if (string(".hfm") != filename.substr(filename.length()-4, 4))
        {
            fprintf(stderr, "输入文件的后缀不是 .hfm 。\n");
            return 1;
        }
        treeFilename = argv[2];
        sscanf(argv[3], "%lu", &bitLength);
    }

    // 载入哈夫曼树
    HuffmanTree tree;
    tree.loadFromFile(treeFilename.c_str());

    // 构造映射表
    // 映射表是将字符映射到一个二进制序列的表
    constructMapping(&tree, vector<int>());
    
    // 打开待解码的文件
    iBitFile bin((filename).c_str());

    // 打开输出的文件
    // file 定义在了本文件头部,为了方便函数 commitBuffer 而调整。
    file = fopen((filename.substr(0, filename.length()-4)).c_str(), "wb");
    
    // 解码
    HuffmanTree * p = &tree;
    for (size_t i=0; i<bitLength; ++i)
    {
        int bit = bin.readNextBit();
        p = p->childs[bit];
        if (p == NULL)
        {
            fprintf(stderr, "待解码文件和树文件似乎不是对应的。");
            return 1;
        }
        if (p->key != -1)
        {
            writeToBuffer((unsigned char)p->key);
            p = &tree;
        }
    }

    commitBuffer(bufferpos);

    fclose(file);
    bin.close();
    fflush(stdout);

    return 0;
}