# Saving in !BMP?

**URL:** <https://discourse.libsdl.org/t/saving-in-bmp/4456>\
**Category:** SDL Development\
**Created:** [May 22, 2001, 9:53pm UTC](https://discourse.libsdl.org/t/saving-in-bmp/4456 "2001-05-22T21:53:27Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![hubert.feyrer\_at\_inf](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/h/58956e/32.png) [@hubert.feyrer\_at\_inf](https://discourse.libsdl.org/u/hubert.feyrer_at_inf)\
**Post date:** [May 22, 2001, 9:53pm UTC](https://discourse.libsdl.org/t/saving-in-bmp/4456/1 "2001-05-22T21:53:27Z")

</div>

I see there’s SDL\_SaveBMP(), but I’m in need of a SDL\_SaveJPG().  
Can anyone help me? I know that SDL\_Image has all sort of load  
routines, but i need to save in a different format.

As an alternative, does someone know a replacement for dumpmpeg that can  
write Jpegs? Right now it writes BMPs which isn’t really that helpful for  
me…

I’m not subscribed to this list, please keep me on tyhe CC: list. Thanks!

- Hubert–  
\*\*\* Hubert Feyrer \<@hubert.feyrer\_at\_inf\>  
\*\*\* FB Informatik, FH Regensburg, Pruefeningerstr. 58, 93048 Regensburg

---

<div class="post-metadata">

**Author:** ![Mattias\_Engdegard](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/m/49beb7/32.png) [@Mattias\_Engdegard](https://discourse.libsdl.org/u/Mattias_Engdegard)\
**Post date:** [May 23, 2001, 9:03am UTC](https://discourse.libsdl.org/t/saving-in-bmp/4456/2 "2001-05-23T09:03:48Z")

</div>

> I see there’s SDL\_SaveBMP(), but I’m in need of a SDL\_SaveJPG().  
> Can anyone help me? I know that SDL\_Image has all sort of load  
> routines, but i need to save in a different format.

I’ve been thinking about adding image saving capabilities to SDL\_image  
but the demand hasn’t been that great so far. If you need a slightly more  
capable format (which does alpha and some rudimentary compression), use the  
TGA saving code in ftp://ptah.lnf.kth.se/pub/misc/savetga.c

> As an alternative, does someone know a replacement for dumpmpeg that can  
> write Jpegs? Right now it writes BMPs which isn’t really that helpful for  
> me…

you could save them in BMP or TGA format and then use the netpbm tools  
for conversion (they should include a jpeg converter nowadays)

An alternative is writing your own saving code using libjpeg

---

<div class="post-metadata">

**Author:** ![Jiri\_Dluhos](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/j/a3d4f5/32.png) [@Jiri\_Dluhos](https://discourse.libsdl.org/u/Jiri_Dluhos)\
**Post date:** [May 23, 2001, 3:26pm UTC](https://discourse.libsdl.org/t/saving-in-bmp/4456/3 "2001-05-23T15:26:04Z")

</div>

Mattias Engdeg?rd wrote:

> > I see there’s SDL\_SaveBMP(), but I’m in need of a SDL\_SaveJPG().  
> > Can anyone help me? I know that SDL\_Image has all sort of load  
> > routines, but i need to save in a different format.
> 
> I’ve been thinking about adding image saving capabilities to SDL\_image  
> but the demand hasn’t been that great so far.

Hello,

I would like this feature, too. I think it could be very useful in some  
situations, e.g. for caching images sent through the network.

Have a nice day,

# Jiri “BlueBear” Dluhos–

It is really quite easy to imagine a square yard of multidimensional  
space, provided that you have seven brains.

```
                                      Prof. Abdullah Nightingale
                (Walter Moers: 13 1/2 lives of Captain Bluebear)

```

* * *

# Jiri “BlueBear” Dluhos Software Developer, HUMUSOFT s.r.o. ([http://www.humusoft.com](http://www.humusoft.com)) dluhos at humusoft dot com (office) dluhosj at centrum dot cz (home)

---

<div class="post-metadata">

**Author:** ![Darren\_Grant](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/d/90ced4/32.png) [@Darren\_Grant](https://discourse.libsdl.org/u/Darren_Grant)\
**Post date:** [May 23, 2001, 11:22pm UTC](https://discourse.libsdl.org/t/saving-in-bmp/4456/4 "2001-05-23T23:22:48Z")

</div>

At 11:03 AM 5/23/01 +0200, you wrote:

> > I see there’s SDL\_SaveBMP(), but I’m in need of a SDL\_SaveJPG().  
> > Can anyone help me? I know that SDL\_Image has all sort of load  
> > routines, but i need to save in a different format.
> 
> I’ve been thinking about adding image saving capabilities to SDL\_image  
> but the demand hasn’t been that great so far. If you need a slightly more  
> capable format (which does alpha and some rudimentary compression), use the  
> TGA saving code in ftp://ptah.lnf.kth.se/pub/misc/savetga.c

I’ve added basic PNG saving functionality to SDL\_image (IMG\_SavePNG\_RW)  
using the libpng example as a guide. The code block is attached, and I  
believe it can simply be appended to IMG\_png.c in the latest SDL\_image source.

There are probably bugs in this code, and I’ve only tested it in Windows,  
so I’m providing it as-as. Use at your own risk. 🙂

-------------- next part --------------  
/\* Save a PNG type image to an SDL datasource \*/  
static void png\_write\_data(png\_structp ctx, png\_bytep area, png\_size\_t size)  
{  
SDL\_RWops \*src;

```
src = (SDL_RWops *)png_get_io_ptr(ctx);
SDL_RWwrite(src, area, size, 1);

```

}

static void png\_io\_flush(png\_structp ctx)  
{  
SDL\_RWops \*src;

```
src = (SDL_RWops *)png_get_io_ptr(ctx);
/* how do I flush src? */

```

}

static int png\_colortype\_from\_surface(SDL\_Surface _surface)  
{  
int colortype = PNG\_COLOR\_MASK\_COLOR; /_ grayscale not supported \*/

```
if (surface->format->palette)
	colortype |= PNG_COLOR_MASK_PALETTE;
else if (surface->format->Amask)
	colortype |= PNG_COLOR_MASK_ALPHA;
	
return colortype;

```

}

static void png\_user\_warn(png\_structp ctx, png\_const\_charp str)  
{  
fprintf(stderr, “libpng: warning: %s\n”, str);  
}

static void png\_user\_error(png\_structp ctx, png\_const\_charp str)  
{  
fprintf(stderr, “libpng: error: %s\n”, str);  
}

int IMG\_SavePNG\_RW(SDL\_Surface \*surface, SDL\_RWops \*src)  
{  
png\_structp png\_ptr = 0;  
png\_infop info\_ptr = 0;  
png\_colorp palette = 0;  
png\_bytep \*row\_pointers = 0;  
int i;  
int colortype;  
int result = -1;

```
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, png_user_error, png_user_warn);

if (png_ptr == NULL)
{
	IMG_SetError("Couldn't allocate memory for PNG file");
	return -1;
}

/* Allocate/initialize the image information data. REQUIRED */
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
	IMG_SetError("Couldn't create image information for PNG file");
	goto done;
}

/* Set error handling. */
if (setjmp(png_ptr->jmpbuf))
{
	/* If we get here, we had a problem reading the file */
	IMG_SetError("Error writing the PNG file");
	goto done;
}

png_set_write_fn(png_ptr, src, png_write_data, png_io_flush);

/* Set the image information here. Width and height are up to 2^31,
 * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
 * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
 * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
 * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
 * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
 * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
 */
colortype = png_colortype_from_surface(surface);
png_set_IHDR(png_ptr, info_ptr, surface->w, surface->h, 8,
	colortype, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);

/* set the palette if there is one. REQUIRED for indexed-color images */
if (colortype & PNG_COLOR_MASK_PALETTE)
{
	palette = (png_colorp)malloc(surface->format->palette->ncolors * sizeof (png_color));

	if (!palette)
	{
		IMG_SetError("Couldn't allocate memory for PNG palette");
		goto done;
	}

	for (i = 0; i < surface->format->palette->ncolors; i++)
	{
		palette[i].red = surface->format->palette->colors[i].r;
		palette[i].green = surface->format->palette->colors[i].g;
		palette[i].blue = surface->format->palette->colors[i].b;
	}

	png_set_PLTE(png_ptr, info_ptr, palette, surface->format->palette->ncolors);
}

/* Write the file header information. REQUIRED */
png_write_info(png_ptr, info_ptr);

/* pack pixels into bytes */
png_set_packing(png_ptr);

/* Create the array of pointers to image data */
row_pointers = (png_bytep*) malloc(sizeof(png_bytep)*surface->h);

if ( (row_pointers == NULL) ) 
{
	IMG_SetError("Couldn't allocate PNG row pointers");
	goto done;
}

for (i = 0; i < surface->h; i++)
	row_pointers[i] = (png_bytep)(Uint8 *)surface->pixels + i*surface->pitch;

/* write out the entire image data in one call */
png_write_image(png_ptr, row_pointers);
png_write_end(png_ptr, info_ptr);
result = 0; /* success! */

```

done:  
if (row\_pointers)  
free(row\_pointers);

```
if (info_ptr->palette)
	free(info_ptr->palette);

png_destroy_write_struct(&png_ptr, (png_infopp)NULL);

return result;

```

}

---

<div class="post-metadata">

**Author:** ![Marco\_Iannaccone](https://discourse.libsdl.org/letter_avatar_proxy/v4/letter/m/ba9def/32.png) [@Marco\_Iannaccone](https://discourse.libsdl.org/u/Marco_Iannaccone)\
**Post date:** [May 24, 2001, 10:35am UTC](https://discourse.libsdl.org/t/saving-in-bmp/4456/5 "2001-05-24T10:35:32Z")

</div>

I think this feature would be very useful…–  
Marco Iannaccone  
@Marco_Iannaccone  
ICQ UIN: 18748121 MetalCoder

"This is a new ship, boy, but she’s got the right name.  
You treat her like a lady, and she’ll always bring you home."  
Dr. Leonard H. McCoy to Data - Encounter at Farpoint - Star Trek  
TNG
