iPXE
Functions | Variables
pnm.c File Reference

Portable anymap format (PNM) More...

#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
#include <ipxe/image.h>
#include <ipxe/pixbuf.h>
#include <ipxe/pnm.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
static int pnm_ascii (struct image *image, struct pnm_context *pnm)
 Extract PNM ASCII value. More...
 
static int pnm_binary (struct image *image, struct pnm_context *pnm)
 Extract PNM binary value. More...
 
static int pnm_scale (struct image *image, struct pnm_context *pnm, unsigned int value)
 Scale PNM scalar value. More...
 
static uint32_t pnm_bitmap (uint32_t composite, unsigned int index)
 Convert PNM bitmap composite value to RGB. More...
 
static uint32_t pnm_greymap (uint32_t composite, unsigned int index __unused)
 Convert PNM greymap composite value to RGB. More...
 
static uint32_t pnm_pixmap (uint32_t composite, unsigned int index __unused)
 Convert PNM pixmap composite value to RGB. More...
 
static int pnm_data (struct image *image, struct pnm_context *pnm, struct pixel_buffer *pixbuf)
 Extract PNM pixel data. More...
 
static struct pnm_typepnm_type (struct image *image)
 Determine PNM image type. More...
 
static int pnm_pixbuf (struct image *image, struct pixel_buffer **pixbuf)
 Convert PNM image to pixel buffer. More...
 
static int pnm_probe (struct image *image)
 Probe PNM image. More...
 
struct image_type pnm_image_type __image_type (PROBE_NORMAL)
 PNM image type. More...
 

Variables

static struct pnm_type pnm_types []
 PNM image types. More...
 

Detailed Description

Portable anymap format (PNM)

Definition in file pnm.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ pnm_ascii()

static int pnm_ascii ( struct image image,
struct pnm_context pnm 
)
static

Extract PNM ASCII value.

Parameters
imagePNM image
pnmPNM context
Return values
valueValue, or negative error

Definition at line 46 of file pnm.c.

46  {
47  char buf[ pnm->ascii_len + 1 /* NUL */ ];
48  char *endp;
49  size_t len;
50  int value;
51  int in_comment = 0;
52 
53  /* Skip any leading whitespace and comments */
54  for ( ; pnm->offset < image->len ; pnm->offset++ ) {
55  copy_from_user ( &buf[0], image->data, pnm->offset,
56  sizeof ( buf[0] ) );
57  if ( in_comment ) {
58  if ( buf[0] == '\n' )
59  in_comment = 0;
60  } else {
61  if ( buf[0] == '#' ) {
62  in_comment = 1;
63  } else if ( ! isspace ( buf[0] ) ) {
64  break;
65  }
66  }
67  }
68 
69  /* Fail if no value is present */
70  len = ( image->len - pnm->offset );
71  if ( len == 0 ) {
72  DBGC ( image, "PNM %s ran out of ASCII data\n", image->name );
73  return -EINVAL;
74  }
75 
76  /* Copy ASCII value to buffer and ensure string is NUL-terminated */
77  if ( len > ( sizeof ( buf ) - 1 /* NUL */ ) )
78  len = ( sizeof ( buf ) - 1 /* NUL */ );
79  copy_from_user ( buf, image->data, pnm->offset, len );
80  buf[len] = '\0';
81 
82  /* Parse value and update offset */
83  value = strtoul ( buf, &endp, 0 );
84  pnm->offset += ( endp - buf );
85 
86  /* Check and skip terminating whitespace character, if present */
87  if ( ( pnm->offset != image->len ) && ( *endp != '\0' ) ) {
88  if ( ! isspace ( *endp ) ) {
89  DBGC ( image, "PNM %s invalid ASCII integer\n",
90  image->name );
91  return -EINVAL;
92  }
93  pnm->offset++;
94  }
95 
96  return value;
97 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
userptr_t data
Raw file image.
Definition: image.h:41
unsigned long strtoul(const char *string, char **endp, int base)
Convert string to numeric value.
Definition: string.c:441
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:24
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
size_t ascii_len
Maximum length of ASCII values.
Definition: pnm.h:36
size_t len
Length of raw file image.
Definition: image.h:43
int isspace(int character)
Check to see if character is a space.
Definition: ctype.c:41
uint32_t len
Length.
Definition: ena.h:14
char * name
Name.
Definition: image.h:34
size_t offset
Current byte offset.
Definition: pnm.h:34

References pnm_context::ascii_len, copy_from_user(), image::data, DBGC, EINVAL, isspace(), len, image::len, image::name, pnm_context::offset, strtoul(), and value.

Referenced by pnm_pixbuf().

◆ pnm_binary()

static int pnm_binary ( struct image image,
struct pnm_context pnm 
)
static

Extract PNM binary value.

Parameters
imagePNM image
pnmPNM context
Return values
valueValue, or negative error

Definition at line 106 of file pnm.c.

106  {
107  uint8_t value;
108 
109  /* Sanity check */
110  if ( pnm->offset == image->len ) {
111  DBGC ( image, "PNM %s ran out of binary data\n",
112  image->name );
113  return -EINVAL;
114  }
115 
116  /* Extract value */
117  copy_from_user ( &value, image->data, pnm->offset, sizeof ( value ) );
118  pnm->offset++;
119 
120  return value;
121 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
userptr_t data
Raw file image.
Definition: image.h:41
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:24
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
size_t len
Length of raw file image.
Definition: image.h:43
unsigned char uint8_t
Definition: stdint.h:10
char * name
Name.
Definition: image.h:34
size_t offset
Current byte offset.
Definition: pnm.h:34

References copy_from_user(), image::data, DBGC, EINVAL, image::len, image::name, pnm_context::offset, and value.

◆ pnm_scale()

static int pnm_scale ( struct image image,
struct pnm_context pnm,
unsigned int  value 
)
static

Scale PNM scalar value.

Parameters
imagePNM image
pnmPNM context
valueRaw value
Return values
valueScaled value (in range 0-255)

Definition at line 131 of file pnm.c.

132  {
133 
134  if ( value > pnm->max ) {
135  DBGC ( image, "PNM %s has out-of-range value %d (max %d)\n",
136  image->name, value, pnm->max );
137  return -EINVAL;
138  }
139  return ( ( 255 * value ) / pnm->max );
140 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:24
unsigned int max
Maximum pixel value.
Definition: pnm.h:38
pseudo_bit_t value[0x00020]
Definition: arbel.h:13
char * name
Name.
Definition: image.h:34

References DBGC, EINVAL, pnm_context::max, image::name, and value.

Referenced by pnm_data().

◆ pnm_bitmap()

static uint32_t pnm_bitmap ( uint32_t  composite,
unsigned int  index 
)
static

Convert PNM bitmap composite value to RGB.

Parameters
compositeComposite value
indexPixel index within this composite value
Return values
rgb24-bit RGB value

Definition at line 149 of file pnm.c.

149  {
150 
151  /* Composite value is an 8-bit bitmask */
152  return ( ( ( composite << index ) & 0x80 ) ? 0x000000 : 0xffffff );
153 }
uint64_t index
Index of the first segment within the content.
Definition: pccrc.h:21

References index.

◆ pnm_greymap()

static uint32_t pnm_greymap ( uint32_t  composite,
unsigned int index  __unused 
)
static

Convert PNM greymap composite value to RGB.

Parameters
compositeComposite value
indexPixel index within this composite value
Return values
rgb24-bit RGB value

Definition at line 162 of file pnm.c.

162  {
163 
164  /* Composite value is an 8-bit greyscale value */
165  return ( ( composite << 16 ) | ( composite << 8 ) | composite );
166 }

◆ pnm_pixmap()

static uint32_t pnm_pixmap ( uint32_t  composite,
unsigned int index  __unused 
)
static

Convert PNM pixmap composite value to RGB.

Parameters
compositeComposite value
indexPixel index within this composite value
Return values
rgb24-bit RGB value

Definition at line 175 of file pnm.c.

175  {
176 
177  /* Composite value is already an RGB value */
178  return composite;
179 }

◆ pnm_data()

static int pnm_data ( struct image image,
struct pnm_context pnm,
struct pixel_buffer pixbuf 
)
static

Extract PNM pixel data.

Parameters
imagePNM image
pnmPNM context
pixbufPixel buffer
Return values
rcReturn status code

Definition at line 189 of file pnm.c.

190  {
191  struct pnm_type *type = pnm->type;
192  size_t offset = 0;
193  unsigned int xpos = 0;
194  int scalar;
195  uint32_t composite;
196  uint32_t rgb;
197  unsigned int i;
198 
199  /* Fill pixel buffer */
200  while ( offset < pixbuf->len ) {
201 
202  /* Extract a scaled composite scalar value from the file */
203  composite = 0;
204  for ( i = 0 ; i < type->depth ; i++ ) {
205  scalar = type->scalar ( image, pnm );
206  if ( scalar < 0 )
207  return scalar;
208  scalar = pnm_scale ( image, pnm, scalar );
209  if ( scalar < 0 )
210  return scalar;
211  composite = ( ( composite << 8 ) | scalar );
212  }
213 
214  /* Extract 24-bit RGB values from composite value */
215  for ( i = 0 ; i < type->packing ; i++ ) {
216  if ( offset >= pixbuf->len ) {
217  DBGC ( image, "PNM %s has too many pixels\n",
218  image->name );
219  return -EINVAL;
220  }
221  rgb = type->rgb ( composite, i );
222  copy_to_user ( pixbuf->data, offset, &rgb,
223  sizeof ( rgb ) );
224  offset += sizeof ( rgb );
225  if ( ++xpos == pixbuf->width ) {
226  xpos = 0;
227  break;
228  }
229  }
230  }
231 
232  return 0;
233 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
int(* scalar)(struct image *image, struct pnm_context *pnm)
Extract scalar value.
Definition: pnm.h:60
uint8_t type
Type.
Definition: ena.h:16
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:24
size_t len
Total length.
Definition: pixbuf.h:27
static userptr_t size_t offset
Offset of the first segment within the content.
Definition: deflate.h:259
static __always_inline void copy_to_user(userptr_t dest, off_t dest_off, const void *src, size_t len)
Copy data to user buffer.
Definition: uaccess.h:324
PNM type.
Definition: pnm.h:45
unsigned int uint32_t
Definition: stdint.h:12
struct pnm_type * type
PNM type.
Definition: pnm.h:32
static int pnm_scale(struct image *image, struct pnm_context *pnm, unsigned int value)
Scale PNM scalar value.
Definition: pnm.c:131
uint32_t len
Length.
Definition: ena.h:14
userptr_t data
32-bit (8:8:8:8) xRGB pixel data, in host-endian order
Definition: pixbuf.h:25
char * name
Name.
Definition: image.h:34
uint32_t(* rgb)(uint32_t composite, unsigned int index)
Convert composite value to 24-bit RGB.
Definition: pnm.h:67
unsigned int width
Width.
Definition: pixbuf.h:21

References copy_to_user(), pixel_buffer::data, DBGC, EINVAL, len, pixel_buffer::len, image::name, offset, pnm_scale(), pnm_type::rgb, pnm_type::scalar, type, pnm_context::type, and pixel_buffer::width.

Referenced by pnm_pixbuf().

◆ pnm_type()

static struct pnm_type* pnm_type ( struct image image)
static

Determine PNM image type.

Parameters
imagePNM image
Return values
typePNM image type, or NULL if not found

Definition at line 289 of file pnm.c.

289  {
290  struct pnm_signature signature;
291  struct pnm_type *type;
292  unsigned int i;
293 
294  /* Extract signature */
295  assert ( image->len >= sizeof ( signature ) );
296  copy_from_user ( &signature, image->data, 0, sizeof ( signature ) );
297 
298  /* Check for supported types */
299  for ( i = 0 ; i < ( sizeof ( pnm_types ) /
300  sizeof ( pnm_types[0] ) ) ; i++ ) {
301  type = &pnm_types[i];
302  if ( type->type == signature.type )
303  return type;
304  }
305  return NULL;
306 }
userptr_t data
Raw file image.
Definition: image.h:41
uint8_t type
Type.
Definition: ena.h:16
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
An executable image.
Definition: image.h:24
static struct pnm_type pnm_types[]
PNM image types.
Definition: pnm.c:236
u8 signature
Definition: CIB_PRM.h:35
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
size_t len
Length of raw file image.
Definition: image.h:43
PNM type.
Definition: pnm.h:45
PNM signature.
Definition: pnm.h:17
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References assert(), copy_from_user(), image::data, image::len, NULL, pnm_types, signature, and type.

Referenced by pnm_pixbuf().

◆ pnm_pixbuf()

static int pnm_pixbuf ( struct image image,
struct pixel_buffer **  pixbuf 
)
static

Convert PNM image to pixel buffer.

Parameters
imagePNM image
pixbufPixel buffer to fill in
Return values
rcReturn status code

Definition at line 315 of file pnm.c.

315  {
316  struct pnm_context pnm;
317  int width;
318  int height;
319  int max;
320  int rc;
321 
322  /* Initialise PNM context */
323  pnm.type = pnm_type ( image );
324  if ( ! pnm.type ) {
325  rc = -ENOTSUP;
326  goto err_type;
327  }
328  pnm.offset = sizeof ( struct pnm_signature );
329  pnm.ascii_len = PNM_ASCII_LEN;
330 
331  /* Extract width */
332  if ( ( width = pnm_ascii ( image, &pnm ) ) < 0 ) {
333  rc = width;
334  goto err_width;
335  }
336 
337  /* Extract height */
338  if ( ( height = pnm_ascii ( image, &pnm ) ) < 0 ) {
339  rc = height;
340  goto err_height;
341  }
342 
343  /* Extract maximum scalar value, if not predefined */
344  if ( pnm.type->flags & PNM_BITMAP ) {
345  pnm.max = ( ( 1 << pnm.type->packing ) - 1 );
346  pnm.ascii_len = 1;
347  } else {
348  if ( ( max = pnm_ascii ( image, &pnm ) ) < 0 ) {
349  rc = max;
350  goto err_max;
351  }
352  pnm.max = max;
353  }
354  if ( pnm.max == 0 ) {
355  DBGC ( image, "PNM %s has invalid maximum value 0\n",
356  image->name );
357  rc = -EINVAL;
358  goto err_max;
359  }
360  DBGC ( image, "PNM %s is type %c width %d height %d max %d\n",
361  image->name, pnm.type->type, width, height, pnm.max );
362 
363  /* Allocate pixel buffer */
364  *pixbuf = alloc_pixbuf ( width, height );
365  if ( ! *pixbuf ) {
366  rc = -ENOMEM;
367  goto err_alloc_pixbuf;
368  }
369 
370  /* Extract pixel data */
371  if ( ( rc = pnm_data ( image, &pnm, *pixbuf ) ) != 0 )
372  goto err_data;
373 
374  return 0;
375 
376  err_data:
377  pixbuf_put ( *pixbuf );
378  err_alloc_pixbuf:
379  err_max:
380  err_height:
381  err_width:
382  err_type:
383  return rc;
384 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
struct pixel_buffer * alloc_pixbuf(unsigned int width, unsigned int height)
Allocate pixel buffer.
Definition: pixbuf.c:58
#define max(x, y)
Definition: ath.h:39
#define PNM_ASCII_LEN
Default maximum length of ASCII values.
Definition: pnm.h:42
#define DBGC(...)
Definition: compiler.h:505
static struct pnm_type * pnm_type(struct image *image)
Determine PNM image type.
Definition: pnm.c:289
An executable image.
Definition: image.h:24
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
#define ENOMEM
Not enough space.
Definition: errno.h:534
static int pnm_ascii(struct image *image, struct pnm_context *pnm)
Extract PNM ASCII value.
Definition: pnm.c:46
PNM signature.
Definition: pnm.h:17
Bitmap format.
Definition: pnm.h:81
char * name
Name.
Definition: image.h:34
PNM context.
Definition: pnm.h:30
static int pnm_data(struct image *image, struct pnm_context *pnm, struct pixel_buffer *pixbuf)
Extract PNM pixel data.
Definition: pnm.c:189

References alloc_pixbuf(), pnm_context::ascii_len, DBGC, EINVAL, ENOMEM, ENOTSUP, pnm_type::flags, pnm_context::max, max, image::name, pnm_context::offset, pnm_type::packing, pnm_ascii(), PNM_ASCII_LEN, PNM_BITMAP, pnm_data(), pnm_type(), rc, pnm_context::type, and pnm_type::type.

◆ pnm_probe()

static int pnm_probe ( struct image image)
static

Probe PNM image.

Parameters
imagePNM image
Return values
rcReturn status code

Definition at line 392 of file pnm.c.

392  {
393  struct pnm_signature signature;
394 
395  /* Sanity check */
396  if ( image->len < sizeof ( signature ) ) {
397  DBGC ( image, "PNM %s is too short\n", image->name );
398  return -ENOEXEC;
399  }
400 
401  /* Check signature */
402  copy_from_user ( &signature, image->data, 0, sizeof ( signature ) );
403  if ( ! ( ( signature.magic == PNM_MAGIC ) &&
404  ( isdigit ( signature.type ) ) &&
405  ( isspace ( signature.space ) ) ) ) {
406  DBGC ( image, "PNM %s has invalid signature\n", image->name );
407  return -ENOEXEC;
408  }
409  DBGC ( image, "PNM %s is type %c\n", image->name, signature.type );
410 
411  return 0;
412 }
userptr_t data
Raw file image.
Definition: image.h:41
#define ENOEXEC
Exec format error.
Definition: errno.h:519
static __always_inline void copy_from_user(void *dest, userptr_t src, off_t src_off, size_t len)
Copy data from user buffer.
Definition: uaccess.h:337
#define DBGC(...)
Definition: compiler.h:505
An executable image.
Definition: image.h:24
u8 signature
Definition: CIB_PRM.h:35
static int isdigit(int character)
Check if character is a decimal digit.
Definition: ctype.h:18
size_t len
Length of raw file image.
Definition: image.h:43
int isspace(int character)
Check to see if character is a space.
Definition: ctype.c:41
PNM signature.
Definition: pnm.h:17
#define PNM_MAGIC
PNM magic byte.
Definition: pnm.h:27
char * name
Name.
Definition: image.h:34

References copy_from_user(), image::data, DBGC, ENOEXEC, isdigit(), isspace(), image::len, image::name, PNM_MAGIC, and signature.

◆ __image_type()

struct image_type pnm_image_type __image_type ( PROBE_NORMAL  )

PNM image type.

Variable Documentation

◆ pnm_types

struct pnm_type pnm_types[]
static

PNM image types.

Definition at line 236 of file pnm.c.

Referenced by pnm_type().