Skip to content

Commit e405534

Browse files
committed
pam: sync with new changes
support for pitch (writer) - not by GPUJPEG used (yet?)
1 parent 5048195 commit e405534

File tree

3 files changed

+62
-12
lines changed

3 files changed

+62
-12
lines changed

src/utils/image_delegate.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,8 @@ int pampnm_save_delegate(const char *filename, const struct gpujpeg_image_parame
235235
return -1;
236236
}
237237

238-
bool ret = pam_write(filename, param_image->width, param_image->height, depth, 255, (const unsigned char *) data, pnm);
238+
const bool ret = pam_write(filename, param_image->width, param_image->width, param_image->height, depth, 255,
239+
(const unsigned char*)data, pnm);
239240
return ret ? 0 : -1;
240241
}
241242

src/utils/pam.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737

3838
#include <ctype.h>
3939
#include <errno.h>
40+
#include <stddef.h>
4041
#include <stdio.h>
4142
#include <stdlib.h>
4243
#include <string.h>
@@ -227,7 +228,10 @@ bool pam_read(const char *filename, struct pam_metadata *info, unsigned char **d
227228
return true;
228229
}
229230

230-
bool pam_write(const char *filename, unsigned int width, unsigned int height, int ch_count, int maxval, const unsigned char *data, bool pnm) {
231+
bool pam_write(const char *filename, unsigned int width, unsigned int pitch,
232+
unsigned int height, int ch_count, int maxval,
233+
const unsigned char *data, bool pnm)
234+
{
231235
errno = 0;
232236
#ifdef _WIN32
233237
FILE *file = _wfopen(mbs_to_wstr(filename), L"wb");
@@ -267,9 +271,19 @@ bool pam_write(const char *filename, unsigned int width, unsigned int height, in
267271
"ENDHDR\n",
268272
width, height, ch_count, maxval, tuple_type);
269273
}
270-
size_t len = (size_t) width * height * ch_count * (maxval <= 255 ? 1 : 2);
274+
const size_t linesize = (size_t) height * ch_count * (maxval <= 255 ? 1 : 2);
275+
const size_t len = width * linesize;
271276
errno = 0;
272-
size_t bytes_written = fwrite((const char *) data, 1, len, file);
277+
size_t bytes_written = 0;
278+
if (pitch == PAM_PITCH_CONTINUOUS || width == pitch) {
279+
bytes_written = fwrite((const char *) data, 1, len, file);
280+
} else {
281+
for (unsigned y = 0; y < height; ++y) {
282+
bytes_written += fwrite((const char *)data +
283+
((size_t)y * pitch),
284+
1, linesize, file);
285+
}
286+
}
273287
if (bytes_written != len) {
274288
fprintf(stderr, "Unable to write PAM/PNM data - length %zd, written %zd: %s\n",
275289
len, bytes_written, strerror(errno));

src/utils/pam.h

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,53 @@
4949
extern "C" {
5050
#endif
5151

52+
/// metadata read from file
5253
struct pam_metadata {
53-
int width;
54-
int height;
55-
int ch_count;
56-
int maxval;
57-
bool bitmap_pbm; // bitmap data is stored in PBM format (1 bit per pixel, line aligned to whole byte, 1 is black /"ink on"/),
58-
// otherwise 1 byte per pixel, 1 is white "light on"); if .depth != 1 || .maxval != 1, this value is undefined
54+
int width; ///< image width
55+
int height; ///< image height
56+
int ch_count; ///< number of channels
57+
int maxval; ///< sample maximal value (typically but not necessarily
58+
///< 255)
59+
bool bitmap_pbm; ///< bitmap data is stored in PBM format (1 bit per
60+
///< pixel, line aligned to whole byte, 1 is black
61+
///< /"ink on"/), otherwise 1 byte per pixel, 1 is
62+
///< white "light on"); if .depth != 1 || .maxval != 1,
63+
///< this value is undefined
5964
};
6065

66+
/**
67+
* read PAM/PNM file
68+
*
69+
* @param filename file name
70+
* @param[out] info pointer to metadata struct
71+
* @param[out] data pointer to byte array, can be 0, in which case no data
72+
* are written (only metadata read )
73+
* @param[out] allocaltor allocator to alloc @ref data; if 0, no data are
74+
* read/allocated, only @ref info set
75+
*/
6176
bool pam_read(const char *filename, struct pam_metadata *info, unsigned char **data, void *(*allocator)(size_t));
62-
bool pam_write(const char *filename, unsigned int width, unsigned int height,
63-
int ch_count, int maxval, const unsigned char *data, bool pnm);
77+
78+
enum {
79+
PAM_PITCH_CONTINUOUS = 0,
80+
};
81+
82+
/**
83+
* write PAM or PNM file
84+
*
85+
* @param filename file name to be written to
86+
* @param width image width
87+
* @param pitch input line pitch in bytes; PAM_PITCH_CONTINUOUS can be used
88+
* if input pitch == width * ch_count * (maxval <= 255 ? 1 : 2)
89+
* @param height image height
90+
* @param ch_count image channel count (1-4 for output PAM, 1 or 3 for PNM, see
91+
* @ref pnm)
92+
* @param maxval maximal sample value, typically 255 for 8-bit
93+
* @param data bytes to be written
94+
* @param pnm use PNM file (instead of PAM)
95+
*/
96+
bool pam_write(const char *filename, unsigned int width, unsigned int pitch,
97+
unsigned int height, int ch_count, int maxval,
98+
const unsigned char *data, bool pnm);
6499

65100
#ifdef __cplusplus
66101
} // extern "C"

0 commit comments

Comments
 (0)