示例#1
0
文件: _webp.c 项目: dvska/Pillow
// Encoder functions
PyObject* _anim_encoder_new(PyObject* self, PyObject* args)
{
    int width, height;
    uint32_t bgcolor;
    int loop_count;
    int minimize_size;
    int kmin, kmax;
    int allow_mixed;
    int verbose;
    WebPAnimEncoderOptions enc_options;
    WebPAnimEncoderObject* encp = NULL;
    WebPAnimEncoder* enc = NULL;

    if (!PyArg_ParseTuple(args, "iiIiiiiii",
        &width, &height, &bgcolor, &loop_count, &minimize_size,
        &kmin, &kmax, &allow_mixed, &verbose)) {
        return NULL;
    }

    // Setup and configure the encoder's options (these are animation-specific)
    if (!WebPAnimEncoderOptionsInit(&enc_options)) {
        PyErr_SetString(PyExc_RuntimeError, "failed to initialize encoder options");
        return NULL;
    }
    enc_options.anim_params.bgcolor = bgcolor;
    enc_options.anim_params.loop_count = loop_count;
    enc_options.minimize_size = minimize_size;
    enc_options.kmin = kmin;
    enc_options.kmax = kmax;
    enc_options.allow_mixed = allow_mixed;
    enc_options.verbose = verbose;

    // Validate canvas dimensions
    if (width <= 0 || height <= 0) {
        PyErr_SetString(PyExc_ValueError, "invalid canvas dimensions");
        return NULL;
    }

    // Create a new animation encoder and picture frame
    encp = PyObject_New(WebPAnimEncoderObject, &WebPAnimEncoder_Type);
    if (encp) {
        if (WebPPictureInit(&(encp->frame))) {
            enc = WebPAnimEncoderNew(width, height, &enc_options);
            if (enc) {
                encp->enc = enc;
                return (PyObject*) encp;
            }
            WebPPictureFree(&(encp->frame));
        }
        PyObject_Del(encp);
    }
    PyErr_SetString(PyExc_RuntimeError, "could not create encoder object");
    return NULL;
}
示例#2
0
/* Save an animation to disk */
gboolean save_animation(gint32          nLayers,
                        gint32         *allLayers,
                        FILE           *outfile,
                        WebPSaveParams *params,
                        GError        **error)
{
    gboolean               status          = FALSE;
    gboolean               innerStatus     = TRUE;
    WebPAnimEncoderOptions enc_options;
    WebPAnimEncoder       *enc             = NULL;
    int                    frame_timestamp = 0;
    WebPData               webp_data       = {0};
    WebPMux               *mux;
    WebPMuxAnimParams      anim_params     = {0};

    /* Prepare for encoding an animation */
    WebPAnimEncoderOptionsInit(&enc_options);

    do {
        int i;
        gint32 drawable_ID = allLayers[0];

        /* Create the encoder */
        enc = WebPAnimEncoderNew(gimp_drawable_width(drawable_ID),
                                 gimp_drawable_height(drawable_ID),
                                 &enc_options);

        /* Encode each layer */
        for (i = 0; i < nLayers; i++) {
            if ((innerStatus = save_layer(allLayers[i],
                                          NULL,
                                          NULL,
                                          TRUE,
                                          enc,
                                          frame_timestamp,
                                          params,
                                          error)) == FALSE) {
                break;
            }
        }

        /* Check to make sure each layer was encoded correctly */
        if (innerStatus == FALSE) {
            break;
        }

        /* Add NULL frame */
        WebPAnimEncoderAdd(enc, NULL, frame_timestamp, NULL);

        /* Initialize the WebP image structure */
        WebPDataInit(&webp_data);

        /* Write the animation to the image */
        if (!WebPAnimEncoderAssemble(enc, &webp_data)) {
            g_set_error(error,
                        G_FILE_ERROR,
                        0,
                        "Encoding error: '%s'",
                        WebPAnimEncoderGetError(enc));
            break;
        }

        /* Create a Mux */
        mux = WebPMuxCreate(&webp_data, 1);

        /* Set animation parameters */
        anim_params.loop_count = params->loop == TRUE ? 0 : 1;
        WebPMuxSetAnimationParams(mux, &anim_params);

        /* Assemble the image */
        WebPMuxAssemble(mux, &webp_data);

        /* Write to disk */
        if (fwrite(webp_data.bytes, webp_data.size, 1, outfile) != 1) {
            break;
        }

        /* Everything succeeded */
        status = TRUE;

    } while(0);

    /* Free image data */
    WebPDataClear(&webp_data);

    /* Free the animation encoder */
    if (enc) {
        WebPAnimEncoderDelete(enc);
    }

    return status;
}