🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

render to memory

Started by
11 comments, last by wwinthan 15 years, 8 months ago
I use mesa(www.mesa3d.org) to render off-screen. after that i use libjpeg to save it as jpeg. i can save it to ppm by using the example code from "mesa3d.org" and after that i use write_ppm to save it as ppm image file.it's working fine with ppm but when i pass the buffer to isavejpeg(which is part of function in jpeglib. but jpeg alignment mismatched. can't save as jpeg.since i barely have idea with image processing so please help by going through the code below plz!
thanks
winthan

<source>
GLenum type= GL_FLOAT;
GLint bits=8;
const char *filename ="C:\\image81.ppm";
const GLint z = 16;
const GLint stencil = 0;
const GLint accum = 0;
OSMesaContext ctx;
void *buffer;
GLint cBits;

assert(bits == 8 ||
bits == 16 ||
bits == 32);

assert(type == GL_UNSIGNED_BYTE ||
type == GL_UNSIGNED_SHORT ||
type == GL_FLOAT);

ctx = OSMesaCreateContextExt(OSMESA_RGBA, z, stencil, accum, NULL );
if (!ctx) {
printf("OSMesaCreateContextExt() failed!\n");
// return 0;
}

/* Allocate the image buffer */
buffer = malloc(WIDTH * HEIGHT * 4 * bits / 8);
// buffer = malloc(WIDTH * HEIGHT * 4 * bits);
if (!buffer) {
printf("Alloc image buffer failed!\n");
// return 0;
}

/* Bind the buffer to the context and make it current */
if (!OSMesaMakeCurrent( ctx, buffer, type, WIDTH, HEIGHT )) {
printf("OSMesaMakeCurrent (%d bits/channel) failed!\n", bits);
free(buffer);
OSMesaDestroyContext(ctx);
glGetIntegerv(GL_RED_BITS, &cBits);
assert(cBits == bits);
glGetIntegerv(GL_GREEN_BITS, &cBits);
assert(cBits == bits);
glGetIntegerv(GL_BLUE_BITS, &cBits);
assert(cBits == bits);
glGetIntegerv(GL_ALPHA_BITS, &cBits);
assert(cBits == bits);
if (filename != NULL) {
if (type == GL_UNSIGNED_SHORT) {
GLushort *buffer16 = (GLushort *) buffer;
GLubyte *buffer8 = (GLubyte *) malloc(WIDTH * HEIGHT * 4);
int i;
for (i = 0; i < WIDTH * HEIGHT * 4; i++)
buffer8 = buffer16 >> 8;
write_ppm(filename, buffer8, WIDTH, HEIGHT);
free(buffer8);
}
else if (type == GL_FLOAT) {
bimage image1;
image1.Create(WIDTH,HEIGHT,24);
GLfloat *buffer32 = (GLfloat *) buffer;
GLubyte *buffer8 = (GLubyte *) malloc(WIDTH * HEIGHT * 4);
int i;
/* colors may be outside [0,1] so we need to clamp */
for (i = 0; i < WIDTH * HEIGHT * 4; i++)
buffer8 = (GLubyte) (buffer32 * 255.0);
iSaveJpeg(image1,buffer8,"C:\\jpgimage.jpg");
write_ppm(filename, buffer8, WIDTH, HEIGHT);
free(buffer8);
}
///////////////////////////////////////////////////////////
write_ppm function is here


void write_ppm(const char *filename, const GLubyte *buffer, int width, int height)
{
const int binary = 0;
FILE *f = fopen( filename, "w" );
if (f) {
int i, x, y;
const GLubyte *ptr = buffer;
if (binary) {
fprintf(f,"P6\n");
fprintf(f,"# ppm-file created by osdemo.c\n");
fprintf(f,"%i %i\n", width,height);
fprintf(f,"255\n");
fclose(f);
f = fopen( filename, "ab" ); /* reopen in binary append mode */
for (y=height-1; y>=0; y--) {
for (x=0; x<width; x++) {
i = (y*width + x) * 4;
fputc(ptr, f); /* write red */
fputc(ptr[i+1], f); /* write green */
fputc(ptr[i+2], f); /* write blue */
}
}
}
else {
/*ASCII*/
int counter = 0;
fprintf(f,"P3\n");
fprintf(f,"# ascii ppm file created by osdemo.c\n");
fprintf(f,"%i %i\n", width, height);
fprintf(f,"255\n");
for (y=height-1; y>=0; y--) {
for (x=0; x<width; x++) {
i = (y*width + x) * 4;
fprintf(f, " %3d %3d %3d", ptr, ptr[i+1], ptr[i+2]);
counter++;
if (counter % 5 == 0)
fprintf(f, "\n");
}
}
}
fclose(f);
}
}
////////////////////////////////////////////////////
iSaveJpeg function comes here

#include "jpeglib.h"
}

//extern JSAMPLE * image_buffer; /* Points to large array of R,G,B-order data */
//extern int image_height; /* Number of rows in image */
//extern int image_width;

/* Number of columns in image */
// It returns true, so that it can be used in ASSERT(Save()) for debugging
template <class T>
bool iSaveJpeg(cBaseImage<T>& image,unsigned char* buffersimage,char * filename)
{
JSAMPLE* image_buffer; /* Points to large array of R,G,B-order data */
int image_height; /* Number of rows in image */
int image_width;
image_height = 1000;
image_width = 1000;
image_buffer = buffersimage;

struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE * outfile; /* target file */
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row */<br>int row_stride; /* physical row width in image buffer */<br>cinfo.err = jpeg_std_error(&jerr);<br>jpeg_create_compress(&cinfo);<br><br>if ((outfile = fopen(filename, "wb")) == NULL) {<br>fprintf(stderr, "can't open %s\n", filename);<br>exit(1);<br>}<br>jpeg_stdio_dest(&cinfo, outfile);<br>cinfo.image_width = image_width; /* image width and height, in pixels */<br>cinfo.image_height = image_height;<br>cinfo.input_components = 3; /* # of color components per pixel */<br>cinfo.in_color_space = JCS_RGB; /* colorspace of input image */<br>jpeg_set_defaults(&cinfo);<br>int quality=1000;<br>jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);<br>jpeg_start_compress(&cinfo, TRUE);<br>row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */<br>while (cinfo.next_scanline &lt; cinfo.image_height) {<br>row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];<br>(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);<br>}<br>jpeg_finish_compress(&cinfo);<br>fclose(outfile);<br>jpeg_destroy_compress(&cinfo);<br>return true;<br>}<br>&lt;/source&gt;<br>
Advertisement
I use mesa(www.mesa3d.org) to render off-screen. after that i use libjpeg to save it as jpeg. i can save it to ppm by using the example code from "mesa3d.org" and after that i use write_ppm to save it as ppm image file.it's working fine with ppm but when i pass the buffer to isavejpeg(which is part of function in jpeglib. but jpeg alignment mismatched. can't save as jpeg.since i barely have idea with image processing so please help by going through the code below plz!
thanks
winthan

<source>
GLenum type= GL_FLOAT;
GLint bits=8;
const char *filename ="C:\\image81.ppm";
const GLint z = 16;
const GLint stencil = 0;
const GLint accum = 0;
OSMesaContext ctx;
void *buffer;
GLint cBits;

assert(bits == 8 ||
bits == 16 ||
bits == 32);

assert(type == GL_UNSIGNED_BYTE ||
type == GL_UNSIGNED_SHORT ||
type == GL_FLOAT);

ctx = OSMesaCreateContextExt(OSMESA_RGBA, z, stencil, accum, NULL );
if (!ctx) {
printf("OSMesaCreateContextExt() failed!\n");
// return 0;
}

/* Allocate the image buffer */
buffer = malloc(WIDTH * HEIGHT * 4 * bits / 8);
// buffer = malloc(WIDTH * HEIGHT * 4 * bits);
if (!buffer) {
printf("Alloc image buffer failed!\n");
// return 0;
}

/* Bind the buffer to the context and make it current */
if (!OSMesaMakeCurrent( ctx, buffer, type, WIDTH, HEIGHT )) {
printf("OSMesaMakeCurrent (%d bits/channel) failed!\n", bits);
free(buffer);
OSMesaDestroyContext(ctx);
glGetIntegerv(GL_RED_BITS, &cBits);
assert(cBits == bits);
glGetIntegerv(GL_GREEN_BITS, &cBits);
assert(cBits == bits);
glGetIntegerv(GL_BLUE_BITS, &cBits);
assert(cBits == bits);
glGetIntegerv(GL_ALPHA_BITS, &cBits);
assert(cBits == bits);
if (filename != NULL) {
if (type == GL_UNSIGNED_SHORT) {
GLushort *buffer16 = (GLushort *) buffer;
GLubyte *buffer8 = (GLubyte *) malloc(WIDTH * HEIGHT * 4);
int i;
for (i = 0; i < WIDTH * HEIGHT * 4; i++)
buffer8 = buffer16 >> 8;
write_ppm(filename, buffer8, WIDTH, HEIGHT);
free(buffer8);
}
else if (type == GL_FLOAT) {
bimage image1;
image1.Create(WIDTH,HEIGHT,24);
GLfloat *buffer32 = (GLfloat *) buffer;
GLubyte *buffer8 = (GLubyte *) malloc(WIDTH * HEIGHT * 4);
int i;
/* colors may be outside [0,1] so we need to clamp */
for (i = 0; i < WIDTH * HEIGHT * 4; i++)
buffer8 = (GLubyte) (buffer32 * 255.0);
iSaveJpeg(image1,buffer8,"C:\\jpgimage.jpg");
write_ppm(filename, buffer8, WIDTH, HEIGHT);
free(buffer8);
}
///////////////////////////////////////////////////////////
write_ppm function is here


void write_ppm(const char *filename, const GLubyte *buffer, int width, int height)
{
const int binary = 0;
FILE *f = fopen( filename, "w" );
if (f) {
int i, x, y;
const GLubyte *ptr = buffer;
if (binary) {
fprintf(f,"P6\n");
fprintf(f,"# ppm-file created by osdemo.c\n");
fprintf(f,"%i %i\n", width,height);
fprintf(f,"255\n");
fclose(f);
f = fopen( filename, "ab" ); /* reopen in binary append mode */
for (y=height-1; y>=0; y--) {
for (x=0; x<width; x++) {
i = (y*width + x) * 4;
fputc(ptr, f); /* write red */
fputc(ptr[i+1], f); /* write green */
fputc(ptr[i+2], f); /* write blue */
}
}
}
else {
/*ASCII*/
int counter = 0;
fprintf(f,"P3\n");
fprintf(f,"# ascii ppm file created by osdemo.c\n");
fprintf(f,"%i %i\n", width, height);
fprintf(f,"255\n");
for (y=height-1; y>=0; y--) {
for (x=0; x<width; x++) {
i = (y*width + x) * 4;
fprintf(f, " %3d %3d %3d", ptr, ptr[i+1], ptr[i+2]);
counter++;
if (counter % 5 == 0)
fprintf(f, "\n");
}
}
}
fclose(f);
}
}
////////////////////////////////////////////////////
iSaveJpeg function comes here

#include "jpeglib.h"
}

//extern JSAMPLE * image_buffer; /* Points to large array of R,G,B-order data */
//extern int image_height; /* Number of rows in image */
//extern int image_width;

/* Number of columns in image */
// It returns true, so that it can be used in ASSERT(Save()) for debugging
template <class T>
bool iSaveJpeg(cBaseImage<T>& image,unsigned char* buffersimage,char * filename)
{
JSAMPLE* image_buffer; /* Points to large array of R,G,B-order data */
int image_height; /* Number of rows in image */
int image_width;
image_height = 1000;
image_width = 1000;
image_buffer = buffersimage;

struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE * outfile; /* target file */
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row */<br>int row_stride; /* physical row width in image buffer */<br>cinfo.err = jpeg_std_error(&jerr);<br>jpeg_create_compress(&cinfo);<br><br>if ((outfile = fopen(filename, "wb")) == NULL) {<br>fprintf(stderr, "can't open %s\n", filename);<br>exit(1);<br>}<br>jpeg_stdio_dest(&cinfo, outfile);<br>cinfo.image_width = image_width; /* image width and height, in pixels */<br>cinfo.image_height = image_height;<br>cinfo.input_components = 3; /* # of color components per pixel */<br>cinfo.in_color_space = JCS_RGB; /* colorspace of input image */<br>jpeg_set_defaults(&cinfo);<br>int quality=1000;<br>jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);<br>jpeg_start_compress(&cinfo, TRUE);<br>row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */<br>while (cinfo.next_scanline &lt; cinfo.image_height) {<br>row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];<br>(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);<br>}<br>jpeg_finish_compress(&cinfo);<br>fclose(outfile);<br>jpeg_destroy_compress(&cinfo);<br>return true;<br>}<br>&lt;/source&gt;<br>
I use mesa(www.mesa3d.org) to render off-screen. after that i use libjpeg to save it as jpeg. i can save it to ppm by using the example code from "mesa3d.org" and after that i use write_ppm to save it as ppm image file.it's working fine with ppm but when i pass the buffer to isavejpeg(which is part of function in jpeglib. but jpeg alignment mismatched. can't save as jpeg.since i barely have idea with image processing so please help by going through the code below plz!
thanks
winthan

<source>
GLenum type= GL_FLOAT;
GLint bits=8;
const char *filename ="C:\\image81.ppm";
const GLint z = 16;
const GLint stencil = 0;
const GLint accum = 0;
OSMesaContext ctx;
void *buffer;
GLint cBits;

assert(bits == 8 ||
bits == 16 ||
bits == 32);

assert(type == GL_UNSIGNED_BYTE ||
type == GL_UNSIGNED_SHORT ||
type == GL_FLOAT);

ctx = OSMesaCreateContextExt(OSMESA_RGBA, z, stencil, accum, NULL );
if (!ctx) {
printf("OSMesaCreateContextExt() failed!\n");
// return 0;
}

/* Allocate the image buffer */
buffer = malloc(WIDTH * HEIGHT * 4 * bits / 8);
// buffer = malloc(WIDTH * HEIGHT * 4 * bits);
if (!buffer) {
printf("Alloc image buffer failed!\n");
// return 0;
}

/* Bind the buffer to the context and make it current */
if (!OSMesaMakeCurrent( ctx, buffer, type, WIDTH, HEIGHT )) {
printf("OSMesaMakeCurrent (%d bits/channel) failed!\n", bits);
free(buffer);
OSMesaDestroyContext(ctx);
glGetIntegerv(GL_RED_BITS, &cBits);
assert(cBits == bits);
glGetIntegerv(GL_GREEN_BITS, &cBits);
assert(cBits == bits);
glGetIntegerv(GL_BLUE_BITS, &cBits);
assert(cBits == bits);
glGetIntegerv(GL_ALPHA_BITS, &cBits);
assert(cBits == bits);
if (filename != NULL) {
if (type == GL_UNSIGNED_SHORT) {
GLushort *buffer16 = (GLushort *) buffer;
GLubyte *buffer8 = (GLubyte *) malloc(WIDTH * HEIGHT * 4);
int i;
for (i = 0; i < WIDTH * HEIGHT * 4; i++)
buffer8 = buffer16 >> 8;
write_ppm(filename, buffer8, WIDTH, HEIGHT);
free(buffer8);
}
else if (type == GL_FLOAT) {
bimage image1;
image1.Create(WIDTH,HEIGHT,24);
GLfloat *buffer32 = (GLfloat *) buffer;
GLubyte *buffer8 = (GLubyte *) malloc(WIDTH * HEIGHT * 4);
int i;
/* colors may be outside [0,1] so we need to clamp */
for (i = 0; i < WIDTH * HEIGHT * 4; i++)
buffer8 = (GLubyte) (buffer32 * 255.0);
iSaveJpeg(image1,buffer8,"C:\\jpgimage.jpg");
write_ppm(filename, buffer8, WIDTH, HEIGHT);
free(buffer8);
}
///////////////////////////////////////////////////////////
write_ppm function is here


void write_ppm(const char *filename, const GLubyte *buffer, int width, int height)
{
const int binary = 0;
FILE *f = fopen( filename, "w" );
if (f) {
int i, x, y;
const GLubyte *ptr = buffer;
if (binary) {
fprintf(f,"P6\n");
fprintf(f,"# ppm-file created by osdemo.c\n");
fprintf(f,"%i %i\n", width,height);
fprintf(f,"255\n");
fclose(f);
f = fopen( filename, "ab" ); /* reopen in binary append mode */
for (y=height-1; y>=0; y--) {
for (x=0; x<width; x++) {
i = (y*width + x) * 4;
fputc(ptr, f); /* write red */
fputc(ptr[i+1], f); /* write green */
fputc(ptr[i+2], f); /* write blue */
}
}
}
else {
/*ASCII*/
int counter = 0;
fprintf(f,"P3\n");
fprintf(f,"# ascii ppm file created by osdemo.c\n");
fprintf(f,"%i %i\n", width, height);
fprintf(f,"255\n");
for (y=height-1; y>=0; y--) {
for (x=0; x<width; x++) {
i = (y*width + x) * 4;
fprintf(f, " %3d %3d %3d", ptr, ptr[i+1], ptr[i+2]);
counter++;
if (counter % 5 == 0)
fprintf(f, "\n");
}
}
}
fclose(f);
}
}
////////////////////////////////////////////////////
iSaveJpeg function comes here

#include "jpeglib.h"
}

//extern JSAMPLE * image_buffer; /* Points to large array of R,G,B-order data */
//extern int image_height; /* Number of rows in image */
//extern int image_width;

/* Number of columns in image */
// It returns true, so that it can be used in ASSERT(Save()) for debugging
template <class T>
bool iSaveJpeg(cBaseImage<T>& image,unsigned char* buffersimage,char * filename)
{
JSAMPLE* image_buffer; /* Points to large array of R,G,B-order data */
int image_height; /* Number of rows in image */
int image_width;
image_height = 1000;
image_width = 1000;
image_buffer = buffersimage;

struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE * outfile; /* target file */
JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row */<br>int row_stride; /* physical row width in image buffer */<br>cinfo.err = jpeg_std_error(&jerr);<br>jpeg_create_compress(&cinfo);<br><br>if ((outfile = fopen(filename, "wb")) == NULL) {<br>fprintf(stderr, "can't open %s\n", filename);<br>exit(1);<br>}<br>jpeg_stdio_dest(&cinfo, outfile);<br>cinfo.image_width = image_width; /* image width and height, in pixels */<br>cinfo.image_height = image_height;<br>cinfo.input_components = 3; /* # of color components per pixel */<br>cinfo.in_color_space = JCS_RGB; /* colorspace of input image */<br>jpeg_set_defaults(&cinfo);<br>int quality=1000;<br>jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);<br>jpeg_start_compress(&cinfo, TRUE);<br>row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */<br>while (cinfo.next_scanline &lt; cinfo.image_height) {<br>row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride];<br>(void) jpeg_write_scanlines(&cinfo, row_pointer, 1);<br>}<br>jpeg_finish_compress(&cinfo);<br>fclose(outfile);<br>jpeg_destroy_compress(&cinfo);<br>return true;<br>}<br>&lt;/source&gt;<br>

This topic is closed to new replies.

Advertisement