Skip to content

Commit

Permalink
WRaster: add functions to save image on disk
Browse files Browse the repository at this point in the history
This patch adds the RSaveTitledImage() function to the WRaster lib
to be able to save file on disk either as a PNG or a JPEG file.
Those two formats depends on optional external libs.
The function can take an optional title/comment which will
be save inside the file.

The WRaster lib and header versions are bumped.
  • Loading branch information
dmaciejak authored and crmafra committed Mar 2, 2023
1 parent 3cc5808 commit c8883fd
Show file tree
Hide file tree
Showing 10 changed files with 285 additions and 15 deletions.
4 changes: 2 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,9 @@ dnl 6. If any interfaces have been removed or changed since the last
dnl public release, then set age to 0.
dnl
dnl libwraster
WRASTER_CURRENT=6
WRASTER_CURRENT=7
WRASTER_REVISION=0
WRASTER_AGE=0
WRASTER_AGE=1
WRASTER_VERSION=$WRASTER_CURRENT:$WRASTER_REVISION:$WRASTER_AGE
AC_SUBST(WRASTER_VERSION)
dnl
Expand Down
2 changes: 2 additions & 0 deletions wrlib/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
- added RSaveTitledImage()

- removed obsoleted RDestroyImage()
- removed Hermes code.
- Put back asm/mmx optimized code.
Expand Down
2 changes: 2 additions & 0 deletions wrlib/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@ endif

if USE_JPEG
libwraster_la_SOURCES += load_jpeg.c
libwraster_la_SOURCES += save_jpeg.c
endif

if USE_PNG
libwraster_la_SOURCES += load_png.c
libwraster_la_SOURCES += save_png.c
endif

if USE_TIFF
Expand Down
15 changes: 13 additions & 2 deletions wrlib/NEWS
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
** API and ABI modifications since wmaker 0.92.0
** API and ABI modifications
----------------------------------------------------

RLightImage: ADDED
Sat 25 Feb 2023

RSaveImage: Improved
Able to save image on disk as PNG or JPEG file

RSaveTitledImage: Added
Image title can be set on the image to be saved

----------------------------------------------------
Since wmaker 0.92.0

RLightImage: ADDED

----------------------------------------------------

Expand Down
10 changes: 8 additions & 2 deletions wrlib/imgformat.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
#ifndef IMGFORMAT_INTERNAL_H
#define IMGFORMAT_INTERNAL_H


typedef enum {
IM_ERROR = -1,
IM_UNKNOWN = 0,
Expand Down Expand Up @@ -82,8 +81,15 @@ void RReleaseMagick(void);
/*
* Function for Saving in a specific format
*/
Bool RSaveXPM(RImage *image, const char *file);
Bool RSaveXPM(RImage *image, const char *filename);

#ifdef USE_PNG
Bool RSavePNG(RImage *image, const char *filename, char *title);
#endif

#ifdef USE_JPEG
Bool RSaveJPEG(RImage *image, const char *filename, char *title);
#endif

/*
* Function to terminate properly
Expand Down
29 changes: 22 additions & 7 deletions wrlib/save.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Raster graphics library
*
* Copyright (c) 1998-2003 Alfredo K. Kojima
* Copyright (c) 2013-2023 Window Maker Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
Expand All @@ -29,18 +30,32 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <time.h>

#include "wraster.h"
#include "imgformat.h"
#include "wr_i18n.h"

Bool RSaveImage(RImage *image, const char *filename, const char *format)
{
return RSaveTitledImage(image, filename, format, NULL);
}

Bool RSaveImage(RImage * image, const char *filename, const char *format)
Bool RSaveTitledImage(RImage *image, const char *filename, const char *format, char *title)
{
if (strcmp(format, "XPM") != 0) {
RErrorCode = RERR_BADFORMAT;
return False;
}
return RSaveXPM(image, filename);
#ifdef USE_PNG
if (strcasecmp(format, "PNG") == 0)
return RSavePNG(image, filename, title);
#endif
#ifdef USE_JPEG
if (strcasecmp(format, "JPG") == 0)
return RSaveJPEG(image, filename, title);

if (strcasecmp(format, "JPEG") == 0)
return RSaveJPEG(image, filename, title);
#endif
if (strcasecmp(format, "XPM") == 0)
return RSaveXPM(image, filename);

RErrorCode = RERR_BADFORMAT;
return False;
}
104 changes: 104 additions & 0 deletions wrlib/save_jpeg.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
/* save_jpeg.c - save JPEG image
*
* Raster graphics library
*
* Copyright (c) 2023 Window Maker Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/

#include <config.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <jpeglib.h>

#include "wraster.h"
#include "imgformat.h"
#include "wr_i18n.h"

/*
* Save RImage to JPEG image
*/

Bool RSaveJPEG(RImage *img, const char *filename, char *title)
{
FILE *file;
int x, y, img_depth;
char *buffer;
RColor pixel;
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
JSAMPROW row_pointer;

file = fopen(filename, "wb");
if (!file) {
RErrorCode = RERR_OPEN;
return False;
}

if (img->format == RRGBAFormat)
img_depth = 4;
else
img_depth = 3;

/* collect separate RGB values to a buffer */
buffer = malloc(sizeof(char) * 3 * img->width * img->height);
for (y = 0; y < img->height; y++) {
for (x = 0; x < img->width; x++) {
RGetPixel(img, x, y, &pixel);
buffer[y*img->width*3+x*3+0] = (char)(pixel.red);
buffer[y*img->width*3+x*3+1] = (char)(pixel.green);
buffer[y*img->width*3+x*3+2] = (char)(pixel.blue);
}
}

/* Setup Exception handling */
cinfo.err = jpeg_std_error(&jerr);

/* Initialize cinfo structure */
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, file);

cinfo.image_width = img->width;
cinfo.image_height = img->height;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;

jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 85, TRUE);
jpeg_start_compress(&cinfo, TRUE);

/* Set title if any */
if (title)
jpeg_write_marker(&cinfo, JPEG_COM, (const JOCTET*)title, strlen(title));

while (cinfo.next_scanline < cinfo.image_height) {
row_pointer = (JSAMPROW) &buffer[cinfo.next_scanline * img_depth * img->width];
jpeg_write_scanlines(&cinfo, &row_pointer, 1);
}

jpeg_finish_compress(&cinfo);

/* Clean */
free(buffer);
fclose(file);

return True;
}
127 changes: 127 additions & 0 deletions wrlib/save_png.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
/* save_png.c - save PNG image
*
* Raster graphics library
*
* Copyright (c) 2023 Window Maker Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/

#include <config.h>

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <png.h>

#include "wraster.h"
#include "imgformat.h"
#include "wr_i18n.h"

/*
* Save RImage to PNG image
*/
Bool RSavePNG(RImage *img, const char *filename, char *title)
{
FILE *file;
png_structp png_ptr;
png_infop png_info_ptr;
png_bytep png_row;
RColor pixel;
int x, y;
int width = img->width;
int height = img->height;

file = fopen(filename, "wb");
if (file == NULL) {
RErrorCode = RERR_OPEN;
return False;
}

/* Initialize write structure */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (png_ptr == NULL) {
fclose(file);
RErrorCode = RERR_NOMEMORY;
return False;
}

/* Initialize info structure */
png_info_ptr = png_create_info_struct(png_ptr);
if (png_info_ptr == NULL) {
fclose(file);
RErrorCode = RERR_NOMEMORY;
return False;
}

/* Setup Exception handling */
if (setjmp(png_jmpbuf (png_ptr))) {
fclose(file);
RErrorCode = RERR_INTERNAL;
return False;
}

png_init_io(png_ptr, file);

/* Write header (8 bit colour depth) */
png_set_IHDR(png_ptr, png_info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
PNG_FILTER_TYPE_BASE);

/* Set title if any */
if (title) {
png_text title_text;
title_text.compression = PNG_TEXT_COMPRESSION_NONE;
title_text.key = "Title";
title_text.text = title;
png_set_text(png_ptr, png_info_ptr, &title_text, 1);
}

png_write_info(png_ptr, png_info_ptr);

/* Allocate memory for one row (3 bytes per pixel - RGB) */
png_row = (png_bytep) malloc(3 * width * sizeof(png_byte));

/* Write image data */
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
png_byte *ptr;

RGetPixel(img, x, y, &pixel);
ptr = &(png_row[x * 3]);
ptr[0] = pixel.red;
ptr[1] = pixel.green;
ptr[2] = pixel.blue;
}
png_write_row(png_ptr, png_row);
}

/* End write */
png_write_end(png_ptr, NULL);

/* Clean */
fclose(file);
if (png_info_ptr != NULL)
png_free_data(png_ptr, png_info_ptr, PNG_FREE_ALL, -1);
if (png_ptr != NULL)
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
if (png_row != NULL)
free(png_row);

return True;
}
2 changes: 1 addition & 1 deletion wrlib/save_xpm.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* nxpm.c - load "normalized" XPM image
/* save_xpm.c - save "normalized" XPM image
*
* Raster graphics library
*
Expand Down
5 changes: 4 additions & 1 deletion wrlib/wraster.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@


/* version of the header for the library */
#define WRASTER_HEADER_VERSION 24
#define WRASTER_HEADER_VERSION 25


#include <X11/Xlib.h>
Expand Down Expand Up @@ -391,6 +391,9 @@ RImage *RGetImageFromXPMData(RContext *context, char **xpmData)
Bool RSaveImage(RImage *image, const char *filename, const char *format)
__wrlib_nonnull(1, 2, 3);

Bool RSaveTitledImage(RImage *image, const char *filename, const char *format, char *title)
__wrlib_nonnull(1, 2, 3);

/*
* Area manipulation
*/
Expand Down

0 comments on commit c8883fd

Please sign in to comment.