bool save_image_file (agg::rendering_buffer& rbuf, const char *fn) { FILE* fd = fopen(fn, "wb"); if(fd == 0) return false; unsigned w = rbuf.width(); unsigned h = rbuf.height(); fprintf(fd, "P6\n%d %d\n255\n", w, h); unsigned y; agg::pod_array<unsigned char> row_buf(w * 3); unsigned char *tmp_buf = row_buf.data(); for(y = 0; y < rbuf.height(); y++) { const unsigned char* src = rbuf.row_ptr(app_flip_y ? h - 1 - y : y); agg::color_conv_row(tmp_buf, src, w, agg::color_conv_bgr24_to_rgb24()); fwrite(tmp_buf, 1, w * 3, fd); } fclose(fd); return true; }
bool JPEG::Encode (ImageBuffer *imageBuffer, Bytes *bytes, int quality) { struct jpeg_compress_struct cinfo; struct ErrorData jpegError; cinfo.err = jpeg_std_error (&jpegError.base); jpegError.base.error_exit = OnError; jpegError.base.output_message = OnOutput; MyDestManager dest; int w = imageBuffer->width; int h = imageBuffer->height; QuickVec<unsigned char> row_buf (w * 3); jpeg_create_compress (&cinfo); if (setjmp (jpegError.on_error)) { jpeg_destroy_compress (&cinfo); return false; } cinfo.dest = (jpeg_destination_mgr *)&dest; cinfo.image_width = w; cinfo.image_height = h; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults (&cinfo); jpeg_set_quality (&cinfo, quality, true); jpeg_start_compress (&cinfo, true); JSAMPROW row_pointer = &row_buf[0]; unsigned char* imageData = imageBuffer->data->Data(); int stride = imageBuffer->Stride (); while (cinfo.next_scanline < cinfo.image_height) { const unsigned char *src = (const unsigned char *)(imageData + (stride * cinfo.next_scanline)); unsigned char *dest = &row_buf[0]; for(int x = 0; x < w; x++) { dest[0] = src[0]; dest[1] = src[1]; dest[2] = src[2]; dest += 3; src += 4; } jpeg_write_scanlines (&cinfo, &row_pointer, 1); } jpeg_finish_compress (&cinfo); bytes->Set (dest.mOutput); return true; }