int
DynamicPngStack::EIO_PngEncode(eio_req *req)
{
    encode_request *enc_req = (encode_request *)req->data;
    DynamicPngStack *png = (DynamicPngStack *)enc_req->png_obj;

    std::pair<Point, Point> optimal = png->optimal_dimension();
    Point top = optimal.first, bot = optimal.second;

    // printf("width, height: %d, %d\n", bot.x - top.x, bot.y - top.y);

    png->offset = top;
    png->width = bot.x - top.x;
    png->height = bot.y - top.y;

    unsigned char *data = (unsigned char*)malloc(sizeof(*data) * png->width * png->height * 4);
    if (!data) {
        enc_req->error = strdup("malloc failed in DynamicPngStack::EIO_PngEncode.");
        return 0;
    }
    memset(data, 0xFF, png->width*png->height*4);

    png->construct_png_data(data, top);

    buffer_type pbt = (png->buf_type == BUF_BGR || png->buf_type == BUF_BGRA) ?
        BUF_BGRA : BUF_RGBA;

    try {
        PngEncoder encoder(data, png->width, png->height, pbt);
        encoder.encode();
        free(data);
        enc_req->png_len = encoder.get_png_len();
        enc_req->png = (char *)malloc(sizeof(*enc_req->png)*enc_req->png_len);
        if (!enc_req->png) {
            enc_req->error = strdup("malloc in DynamicPngStack::EIO_PngEncode failed.");
            return 0;
        }
        else {
            memcpy(enc_req->png, encoder.get_png(), enc_req->png_len);
        }
    }
    catch (const char *err) {
        enc_req->error = strdup(err);
    }

    return 0;
}