ext/webp_ffi/util.c in webp-ffi-0.1.3 vs ext/webp_ffi/util.c in webp-ffi-0.1.4
- old
+ new
@@ -256,10 +256,78 @@
png_write_end(png, info);
png_destroy_write_struct(&png, &info);
return 1;
}
+static int UtilWritePPM(FILE* fout, const WebPDecBuffer* const buffer, int alpha) {
+ const uint32_t width = buffer->width;
+ const uint32_t height = buffer->height;
+ const unsigned char* const rgb = buffer->u.RGBA.rgba;
+ const int stride = buffer->u.RGBA.stride;
+ const size_t bytes_per_px = alpha ? 4 : 3;
+ uint32_t y;
+
+ if (alpha) {
+ fprintf(fout, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH 4\nMAXVAL 255\n"
+ "TUPLTYPE RGB_ALPHA\nENDHDR\n", width, height);
+ } else {
+ fprintf(fout, "P6\n%d %d\n255\n", width, height);
+ }
+ for (y = 0; y < height; ++y) {
+ if (fwrite(rgb + y * stride, width, bytes_per_px, fout) != bytes_per_px) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int UtilWriteAlphaPlane(FILE* fout, const WebPDecBuffer* const buffer) {
+ const uint32_t width = buffer->width;
+ const uint32_t height = buffer->height;
+ const unsigned char* const a = buffer->u.YUVA.a;
+ const int a_stride = buffer->u.YUVA.a_stride;
+ uint32_t y;
+ assert(a != NULL);
+ fprintf(fout, "P5\n%d %d\n255\n", width, height);
+ for (y = 0; y < height; ++y) {
+ if (fwrite(a + y * a_stride, width, 1, fout) != 1) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static int UtilWritePGM(FILE* fout, const WebPDecBuffer* const buffer) {
+ const int width = buffer->width;
+ const int height = buffer->height;
+ const WebPYUVABuffer* const yuv = &buffer->u.YUVA;
+ // Save a grayscale PGM file using the IMC4 layout
+ // (http://www.fourcc.org/yuv.php#IMC4). This is a very
+ // convenient format for viewing the samples, esp. for
+ // odd dimensions.
+ int ok = 1;
+ int y;
+ const int uv_width = (width + 1) / 2;
+ const int uv_height = (height + 1) / 2;
+ const int out_stride = (width + 1) & ~1;
+ const int a_height = yuv->a ? height : 0;
+ fprintf(fout, "P5\n%d %d\n255\n", out_stride, height + uv_height + a_height);
+ for (y = 0; ok && y < height; ++y) {
+ ok &= (fwrite(yuv->y + y * yuv->y_stride, width, 1, fout) == 1);
+ if (width & 1) fputc(0, fout); // padding byte
+ }
+ for (y = 0; ok && y < uv_height; ++y) {
+ ok &= (fwrite(yuv->u + y * yuv->u_stride, uv_width, 1, fout) == 1);
+ ok &= (fwrite(yuv->v + y * yuv->v_stride, uv_width, 1, fout) == 1);
+ }
+ for (y = 0; ok && y < a_height; ++y) {
+ ok &= (fwrite(yuv->a + y * yuv->a_stride, width, 1, fout) == 1);
+ if (width & 1) fputc(0, fout); // padding byte
+ }
+ return ok;
+}
+
static int UtilReadTIFF(const char* const filename,
WebPPicture* const pic, int keep_alpha) {
TIFF* const tif = TIFFOpen(filename, "r");
uint32 width, height;
uint32* raster;
@@ -369,21 +437,19 @@
return 0;
}
if (format == PNG) {
ok &= UtilWritePNG(fout, buffer);
- }
- /*
} else if (format == PAM) {
- ok &= WritePPM(fout, buffer, 1);
+ ok &= UtilWritePPM(fout, buffer, 1);
} else if (format == PPM) {
- ok &= WritePPM(fout, buffer, 0);
+ ok &= UtilWritePPM(fout, buffer, 0);
} else if (format == PGM) {
- ok &= WritePGM(fout, buffer);
+ ok &= UtilWritePGM(fout, buffer);
} else if (format == ALPHA_PLANE_ONLY) {
- ok &= WriteAlphaPlane(fout, buffer);
+ ok &= UtilWriteAlphaPlane(fout, buffer);
}
- */
+
if (fout) {
fclose(fout);
}
return ok;
}