Browse Source

[pnm] Add support for PNM images

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 11 years ago
parent
commit
0ee89338dd
7 changed files with 803 additions and 0 deletions
  1. 3
    0
      src/config/config.c
  2. 1
    0
      src/config/general.h
  3. 415
    0
      src/image/pnm.c
  4. 1
    0
      src/include/ipxe/errfile.h
  5. 86
    0
      src/include/ipxe/pnm.h
  6. 296
    0
      src/tests/pnm_test.c
  7. 1
    0
      src/tests/tests.c

+ 3
- 0
src/config/config.c View File

@@ -194,6 +194,9 @@ REQUIRE_OBJECT ( efi_image );
194 194
 #ifdef IMAGE_SDI
195 195
 REQUIRE_OBJECT ( sdi );
196 196
 #endif
197
+#ifdef IMAGE_PNM
198
+REQUIRE_OBJECT ( pnm );
199
+#endif
197 200
 
198 201
 /*
199 202
  * Drag in all requested commands

+ 1
- 0
src/config/general.h View File

@@ -103,6 +103,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
103 103
 //#define	IMAGE_COMBOOT		/* SYSLINUX COMBOOT image support */
104 104
 //#define	IMAGE_EFI		/* EFI image support */
105 105
 //#define	IMAGE_SDI		/* SDI image support */
106
+//#define	IMAGE_PNM		/* PNM image support */
106 107
 
107 108
 /*
108 109
  * Command-line commands to include

+ 415
- 0
src/image/pnm.c View File

@@ -0,0 +1,415 @@
1
+/*
2
+ * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17
+ * 02110-1301, USA.
18
+ */
19
+
20
+FILE_LICENCE ( GPL2_OR_LATER );
21
+
22
+/** @file
23
+ *
24
+ * Portable anymap format (PNM)
25
+ *
26
+ */
27
+
28
+#include <stdlib.h>
29
+#include <errno.h>
30
+#include <ctype.h>
31
+#include <ipxe/image.h>
32
+#include <ipxe/pixbuf.h>
33
+#include <ipxe/pnm.h>
34
+
35
+/**
36
+ * Extract PNM ASCII value
37
+ *
38
+ * @v image		PNM image
39
+ * @v pnm		PNM context
40
+ * @ret value		Value, or negative error
41
+ */
42
+static int pnm_ascii ( struct image *image, struct pnm_context *pnm ) {
43
+	char buf[ pnm->ascii_len + 1 /* NUL */ ];
44
+	char *endp;
45
+	size_t len;
46
+	int value;
47
+	int in_comment = 0;
48
+
49
+	/* Skip any leading whitespace and comments */
50
+	for ( ; pnm->offset < image->len ; pnm->offset++ ) {
51
+		copy_from_user ( &buf[0], image->data, pnm->offset,
52
+				 sizeof ( buf[0] ) );
53
+		if ( in_comment ) {
54
+			if ( buf[0] == '\n' )
55
+				in_comment = 0;
56
+		} else {
57
+			if ( buf[0] == '#' ) {
58
+				in_comment = 1;
59
+			} else if ( ! isspace ( buf[0] ) ) {
60
+				break;
61
+			}
62
+		}
63
+	}
64
+
65
+	/* Fail if no value is present */
66
+	len = ( image->len - pnm->offset );
67
+	if ( len == 0 ) {
68
+		DBGC ( image, "PNM %s ran out of ASCII data\n", image->name );
69
+		return -EINVAL;
70
+	}
71
+
72
+	/* Copy ASCII value to buffer and ensure string is NUL-terminated */
73
+	if ( len > ( sizeof ( buf ) - 1 /* NUL */ ) )
74
+		len = ( sizeof ( buf ) - 1 /* NUL */ );
75
+	copy_from_user ( buf, image->data, pnm->offset, len );
76
+	buf[len] = '\0';
77
+
78
+	/* Parse value and update offset */
79
+	value = strtoul ( buf, &endp, 0 );
80
+	pnm->offset += ( endp - buf );
81
+
82
+	/* Check and skip terminating whitespace character, if present */
83
+	if ( ( pnm->offset != image->len ) && ( *endp != '\0' ) ) {
84
+		if ( ! isspace ( *endp ) ) {
85
+			DBGC ( image, "PNM %s invalid ASCII integer\n",
86
+			       image->name );
87
+			return -EINVAL;
88
+		}
89
+		pnm->offset++;
90
+	}
91
+
92
+	return value;
93
+}
94
+
95
+/**
96
+ * Extract PNM binary value
97
+ *
98
+ * @v image		PNM image
99
+ * @v pnm		PNM context
100
+ * @ret value		Value, or negative error
101
+ */
102
+static int pnm_binary ( struct image *image, struct pnm_context *pnm ) {
103
+	uint8_t value;
104
+
105
+	/* Sanity check */
106
+	if ( pnm->offset == image->len ) {
107
+		DBGC ( image, "PNM %s ran out of binary data\n",
108
+		       image->name );
109
+		return -EINVAL;
110
+	}
111
+
112
+	/* Extract value */
113
+	copy_from_user ( &value, image->data, pnm->offset, sizeof ( value ) );
114
+	pnm->offset++;
115
+
116
+	return value;
117
+}
118
+
119
+/**
120
+ * Scale PNM scalar value
121
+ *
122
+ * @v image		PNM image
123
+ * @v pnm		PNM context
124
+ * @v value		Raw value
125
+ * @ret value		Scaled value (in range 0-255)
126
+ */
127
+static int pnm_scale ( struct image *image, struct pnm_context *pnm,
128
+		       unsigned int value ) {
129
+
130
+	if ( value > pnm->max ) {
131
+		DBGC ( image, "PNM %s has out-of-range value %d (max %d)\n",
132
+		       image->name, value, pnm->max );
133
+		return -EINVAL;
134
+	}
135
+	return ( ( 255 * value ) / pnm->max );
136
+}
137
+
138
+/**
139
+ * Convert PNM bitmap composite value to RGB
140
+ *
141
+ * @v composite		Composite value
142
+ * @v index		Pixel index within this composite value
143
+ * @ret rgb		24-bit RGB value
144
+ */
145
+static uint32_t pnm_bitmap ( uint32_t composite, unsigned int index ) {
146
+
147
+	/* Composite value is an 8-bit bitmask */
148
+	return ( ( ( composite << index ) & 0x80 ) ? 0x000000 : 0xffffff );
149
+}
150
+
151
+/**
152
+ * Convert PNM greymap composite value to RGB
153
+ *
154
+ * @v composite		Composite value
155
+ * @v index		Pixel index within this composite value
156
+ * @ret rgb		24-bit RGB value
157
+ */
158
+static uint32_t pnm_greymap ( uint32_t composite, unsigned int index __unused ){
159
+
160
+	/* Composite value is an 8-bit greyscale value */
161
+	return ( ( composite << 16 ) | ( composite << 8 ) | composite );
162
+}
163
+
164
+/**
165
+ * Convert PNM pixmap composite value to RGB
166
+ *
167
+ * @v composite		Composite value
168
+ * @v index		Pixel index within this composite value
169
+ * @ret rgb		24-bit RGB value
170
+ */
171
+static uint32_t pnm_pixmap ( uint32_t composite, unsigned int index __unused ) {
172
+
173
+	/* Composite value is already an RGB value */
174
+	return composite;
175
+}
176
+
177
+/**
178
+ * Extract PNM pixel data
179
+ *
180
+ * @v image		PNM image
181
+ * @v pnm		PNM context
182
+ * @v pixbuf		Pixel buffer
183
+ * @ret rc		Return status code
184
+ */
185
+static int pnm_data ( struct image *image, struct pnm_context *pnm,
186
+		      struct pixel_buffer *pixbuf ) {
187
+	struct pnm_type *type = pnm->type;
188
+	size_t offset = 0;
189
+	unsigned int xpos = 0;
190
+	int scalar;
191
+	uint32_t composite;
192
+	uint32_t rgb;
193
+	unsigned int i;
194
+
195
+	/* Fill pixel buffer */
196
+	while ( offset < pixbuf->len ) {
197
+
198
+		/* Extract a scaled composite scalar value from the file */
199
+		composite = 0;
200
+		for ( i = 0 ; i < type->depth ; i++ ) {
201
+			scalar = type->scalar ( image, pnm );
202
+			if ( scalar < 0 )
203
+				return scalar;
204
+			scalar = pnm_scale ( image, pnm, scalar );
205
+			if ( scalar < 0 )
206
+				return scalar;
207
+			composite = ( ( composite << 8 ) | scalar );
208
+		}
209
+
210
+		/* Extract 24-bit RGB values from composite value */
211
+		for ( i = 0 ; i < type->packing ; i++ ) {
212
+			if ( offset >= pixbuf->len ) {
213
+				DBGC ( image, "PNM %s has too many pixels\n",
214
+				       image->name );
215
+				return -EINVAL;
216
+			}
217
+			rgb = type->rgb ( composite, i );
218
+			copy_to_user ( pixbuf->data, offset, &rgb,
219
+				       sizeof ( rgb ) );
220
+			offset += sizeof ( rgb );
221
+			if ( ++xpos == pixbuf->width ) {
222
+				xpos = 0;
223
+				break;
224
+			}
225
+		}
226
+	}
227
+
228
+	return 0;
229
+}
230
+
231
+/** PNM image types */
232
+static struct pnm_type pnm_types[] = {
233
+	{
234
+		.type = '1',
235
+		.depth = 1,
236
+		.packing = 1,
237
+		.flags = PNM_BITMAP,
238
+		.scalar = pnm_ascii,
239
+		.rgb = pnm_bitmap,
240
+	},
241
+	{
242
+		.type = '2',
243
+		.depth = 1,
244
+		.packing = 1,
245
+		.scalar = pnm_ascii,
246
+		.rgb = pnm_greymap,
247
+	},
248
+	{
249
+		.type = '3',
250
+		.depth = 3,
251
+		.packing = 1,
252
+		.scalar = pnm_ascii,
253
+		.rgb = pnm_pixmap,
254
+	},
255
+	{
256
+		.type = '4',
257
+		.depth = 1,
258
+		.packing = 8,
259
+		.flags = PNM_BITMAP,
260
+		.scalar = pnm_binary,
261
+		.rgb = pnm_bitmap,
262
+	},
263
+	{
264
+		.type = '5',
265
+		.depth = 1,
266
+		.packing = 1,
267
+		.scalar = pnm_binary,
268
+		.rgb = pnm_greymap,
269
+	},
270
+	{
271
+		.type = '6',
272
+		.depth = 3,
273
+		.packing = 1,
274
+		.scalar = pnm_binary,
275
+		.rgb = pnm_pixmap,
276
+	},
277
+};
278
+
279
+/**
280
+ * Determine PNM image type
281
+ *
282
+ * @v image		PNM image
283
+ * @ret type		PNM image type, or NULL if not found
284
+ */
285
+static struct pnm_type * pnm_type ( struct image *image ) {
286
+	struct pnm_signature signature;
287
+	struct pnm_type *type;
288
+	unsigned int i;
289
+
290
+	/* Extract signature */
291
+	assert ( image->len >= sizeof ( signature ) );
292
+	copy_from_user ( &signature, image->data, 0, sizeof ( signature ) );
293
+
294
+	/* Check for supported types */
295
+	for ( i = 0 ; i < ( sizeof ( pnm_types ) /
296
+			    sizeof ( pnm_types[0] ) ) ; i++ ) {
297
+		type = &pnm_types[i];
298
+		if ( type->type == signature.type )
299
+			return type;
300
+	}
301
+	return NULL;
302
+}
303
+
304
+/**
305
+ * Convert PNM image to pixel buffer
306
+ *
307
+ * @v image		PNM image
308
+ * @v pixbuf		Pixel buffer to fill in
309
+ * @ret rc		Return status code
310
+ */
311
+static int pnm_pixbuf ( struct image *image, struct pixel_buffer **pixbuf ) {
312
+	struct pnm_context pnm;
313
+	int width;
314
+	int height;
315
+	int max;
316
+	int rc;
317
+
318
+	/* Initialise PNM context */
319
+	pnm.type = pnm_type ( image );
320
+	if ( ! pnm.type ) {
321
+		rc = -ENOTSUP;
322
+		goto err_type;
323
+	}
324
+	pnm.offset = sizeof ( struct pnm_signature );
325
+	pnm.ascii_len = PNM_ASCII_LEN;
326
+
327
+	/* Extract width */
328
+	if ( ( width = pnm_ascii ( image, &pnm ) ) < 0 ) {
329
+		rc = width;
330
+		goto err_width;
331
+	}
332
+
333
+	/* Extract height */
334
+	if ( ( height = pnm_ascii ( image, &pnm ) ) < 0 ) {
335
+		rc = height;
336
+		goto err_height;
337
+	}
338
+
339
+	/* Extract maximum scalar value, if not predefined */
340
+	if ( pnm.type->flags & PNM_BITMAP ) {
341
+		pnm.max = ( ( 1 << pnm.type->packing ) - 1 );
342
+		pnm.ascii_len = 1;
343
+	} else {
344
+		if ( ( max = pnm_ascii ( image, &pnm ) ) < 0 ) {
345
+			rc = max;
346
+			goto err_max;
347
+		}
348
+		pnm.max = max;
349
+	}
350
+	if ( pnm.max == 0 ) {
351
+		DBGC ( image, "PNM %s has invalid maximum value 0\n",
352
+		       image->name );
353
+		rc = -EINVAL;
354
+		goto err_max;
355
+	}
356
+	DBGC ( image, "PNM %s is type %c width %d height %d max %d\n",
357
+	       image->name, pnm.type->type, width, height, pnm.max );
358
+
359
+	/* Allocate pixel buffer */
360
+	*pixbuf = alloc_pixbuf ( width, height );
361
+	if ( ! *pixbuf ) {
362
+		rc = -ENOMEM;
363
+		goto err_alloc_pixbuf;
364
+	}
365
+
366
+	/* Extract pixel data */
367
+	if ( ( rc = pnm_data ( image, &pnm, *pixbuf ) ) != 0 )
368
+		goto err_data;
369
+
370
+	return 0;
371
+
372
+ err_data:
373
+	pixbuf_put ( *pixbuf );
374
+ err_alloc_pixbuf:
375
+ err_max:
376
+ err_height:
377
+ err_width:
378
+ err_type:
379
+	return rc;
380
+}
381
+
382
+/**
383
+ * Probe PNM image
384
+ *
385
+ * @v image		PNM image
386
+ * @ret rc		Return status code
387
+ */
388
+static int pnm_probe ( struct image *image ) {
389
+	struct pnm_signature signature;
390
+
391
+	/* Sanity check */
392
+	if ( image->len < sizeof ( signature ) ) {
393
+		DBGC ( image, "PNM %s is too short\n", image->name );
394
+		return -ENOEXEC;
395
+	}
396
+
397
+	/* Check signature */
398
+	copy_from_user ( &signature, image->data, 0, sizeof ( signature ) );
399
+	if ( ! ( ( signature.magic == PNM_MAGIC ) &&
400
+		 ( isdigit ( signature.type ) ) &&
401
+		 ( isspace ( signature.space ) ) ) ) {
402
+		DBGC ( image, "PNM %s has invalid signature\n", image->name );
403
+		return -ENOEXEC;
404
+	}
405
+	DBGC ( image, "PNM %s is type %c\n", image->name, signature.type );
406
+
407
+	return 0;
408
+}
409
+
410
+/** PNM image type */
411
+struct image_type pnm_image_type __image_type ( PROBE_NORMAL ) = {
412
+	.name = "PNM",
413
+	.probe = pnm_probe,
414
+	.pixbuf = pnm_pixbuf,
415
+};

+ 1
- 0
src/include/ipxe/errfile.h View File

@@ -227,6 +227,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
227 227
 #define ERRFILE_segment		      ( ERRFILE_IMAGE | 0x00030000 )
228 228
 #define ERRFILE_efi_image	      ( ERRFILE_IMAGE | 0x00040000 )
229 229
 #define ERRFILE_embedded	      ( ERRFILE_IMAGE | 0x00050000 )
230
+#define ERRFILE_pnm		      ( ERRFILE_IMAGE | 0x00060000 )
230 231
 
231 232
 #define ERRFILE_asn1		      ( ERRFILE_OTHER | 0x00000000 )
232 233
 #define ERRFILE_chap		      ( ERRFILE_OTHER | 0x00010000 )

+ 86
- 0
src/include/ipxe/pnm.h View File

@@ -0,0 +1,86 @@
1
+#ifndef _IPXE_PNM_H
2
+#define _IPXE_PNM_H
3
+
4
+/** @file
5
+ *
6
+ * Portable anymap format (PNM)
7
+ *
8
+ */
9
+
10
+FILE_LICENCE ( GPL2_OR_LATER );
11
+
12
+#include <stdint.h>
13
+#include <ipxe/uaccess.h>
14
+#include <ipxe/image.h>
15
+
16
+/** PNM signature */
17
+struct pnm_signature {
18
+	/** Magic byte ('P') */
19
+	char magic;
20
+	/** PNM type */
21
+	char type;
22
+	/** Whitespace */
23
+	char space;
24
+} __attribute__ (( packed ));
25
+
26
+/** PNM magic byte */
27
+#define PNM_MAGIC 'P'
28
+
29
+/** PNM context */
30
+struct pnm_context {
31
+	/** PNM type */
32
+	struct pnm_type *type;
33
+	/** Current byte offset */
34
+	size_t offset;
35
+	/** Maximum length of ASCII values */
36
+	size_t ascii_len;
37
+	/** Maximum pixel value */
38
+	unsigned int max;
39
+};
40
+
41
+/** Default maximum length of ASCII values */
42
+#define PNM_ASCII_LEN 16
43
+
44
+/** PNM type */
45
+struct pnm_type {
46
+	/** PNM type */
47
+	char type;
48
+	/** Number of scalar values per pixel */
49
+	uint8_t depth;
50
+	/** Number of pixels per composite value */
51
+	uint8_t packing;
52
+	/** Flags */
53
+	uint8_t flags;
54
+	/** Extract scalar value
55
+	 *
56
+	 * @v image		PNM image
57
+	 * @v pnm		PNM context
58
+	 * @ret value		Value, or negative error
59
+	 */
60
+	int ( * scalar ) ( struct image *image, struct pnm_context *pnm );
61
+	/** Convert composite value to 24-bit RGB
62
+	 *
63
+	 * @v composite		Composite value
64
+	 * @v index		Pixel index within this composite value
65
+	 * @ret rgb		24-bit RGB value
66
+	 */
67
+	uint32_t ( * rgb ) ( uint32_t composite, unsigned int index );
68
+};
69
+
70
+/** PNM flags */
71
+enum pnm_flags {
72
+	/** Bitmap format
73
+	 *
74
+	 * If set, this flag indicates that:
75
+	 *
76
+	 * - the maximum scalar value is predefined as being equal to
77
+	 *   (2^packing-1), and is not present within the file, and
78
+	 *
79
+	 * - the maximum length of ASCII values is 1.
80
+	 */
81
+	PNM_BITMAP = 0x01,
82
+};
83
+
84
+extern struct image_type pnm_image_type __image_type ( PROBE_NORMAL );
85
+
86
+#endif /* _IPXE_PNM_H */

+ 296
- 0
src/tests/pnm_test.c View File

@@ -0,0 +1,296 @@
1
+/*
2
+ * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
3
+ *
4
+ * This program is free software; you can redistribute it and/or
5
+ * modify it under the terms of the GNU General Public License as
6
+ * published by the Free Software Foundation; either version 2 of the
7
+ * License, or any later version.
8
+ *
9
+ * This program is distributed in the hope that it will be useful, but
10
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
+ * General Public License for more details.
13
+ *
14
+ * You should have received a copy of the GNU General Public License
15
+ * along with this program; if not, write to the Free Software
16
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17
+ * 02110-1301, USA.
18
+ */
19
+
20
+FILE_LICENCE ( GPL2_OR_LATER );
21
+
22
+/** @file
23
+ *
24
+ * PNM self-tests
25
+ *
26
+ */
27
+
28
+/* Forcibly enable assertions */
29
+#undef NDEBUG
30
+
31
+#include <string.h>
32
+#include <assert.h>
33
+#include <ipxe/pixbuf.h>
34
+#include <ipxe/pnm.h>
35
+#include <ipxe/test.h>
36
+
37
+/** Define inline pixel data */
38
+#define DATA(...) { __VA_ARGS__ }
39
+
40
+/** A PNM test */
41
+struct pnm_test {
42
+	/** Source image */
43
+	struct image *image;
44
+	/** Pixel data */
45
+	const uint32_t *data;
46
+	/** Length of pixel data */
47
+	size_t len;
48
+	/** Width */
49
+	unsigned int width;
50
+	/** Height */
51
+	unsigned int height;
52
+};
53
+
54
+/** Define a PNM test */
55
+#define PNM( NAME, FILE, WIDTH, HEIGHT, DATA )				\
56
+	static const char NAME ## _file[] = FILE;			\
57
+	static const uint32_t NAME ## _data[] = DATA;			\
58
+	static struct image NAME ## _image = {				\
59
+		.refcnt = REF_INIT ( ref_no_free ),			\
60
+		.name = #NAME,						\
61
+		.data = ( userptr_t ) ( NAME ## _file ),		\
62
+		.len = sizeof ( NAME ## _file ),			\
63
+	};								\
64
+	static struct pnm_test NAME = {					\
65
+		.image = & NAME ## _image,				\
66
+		.data = NAME ## _data,					\
67
+		.len = sizeof ( NAME ## _data ),			\
68
+		.width = WIDTH,						\
69
+		.height = HEIGHT,					\
70
+	};
71
+
72
+/** PBM ASCII example (from Wikipedia) */
73
+PNM ( pbm_ascii,
74
+      "P1\n"
75
+      "# This is an example bitmap of the letter \"J\"\n"
76
+      "6 10\n"
77
+      "0 0 0 0 1 0\n"
78
+      "0 0 0 0 1 0\n"
79
+      "0 0 0 0 1 0\n"
80
+      "0 0 0 0 1 0\n"
81
+      "0 0 0 0 1 0\n"
82
+      "0 0 0 0 1 0\n"
83
+      "1 0 0 0 1 0\n"
84
+      "0 1 1 1 0 0\n"
85
+      "0 0 0 0 0 0\n"
86
+      "0 0 0 0 0 0\n",
87
+      6, 10,
88
+      DATA ( 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff,
89
+	     0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff,
90
+	     0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff,
91
+	     0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff,
92
+	     0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff,
93
+	     0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff,
94
+	     0x000000, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff,
95
+	     0xffffff, 0x000000, 0x000000, 0x000000, 0xffffff, 0xffffff,
96
+	     0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
97
+	     0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff ) );
98
+
99
+/** PGM ASCII example (from Wikipedia) */
100
+PNM ( pgm_ascii,
101
+      "P2\n"
102
+      "# Shows the word \"FEEP\" (example from Netpbm man page on PGM)\n"
103
+      "24 7\n"
104
+      "15\n"
105
+      "0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0\n"
106
+      "0  3  3  3  3  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15 15 15 15  0\n"
107
+      "0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0 15  0\n"
108
+      "0  3  3  3  0  0  0  7  7  7  0  0  0 11 11 11  0  0  0 15 15 15 15  0\n"
109
+      "0  3  0  0  0  0  0  7  0  0  0  0  0 11  0  0  0  0  0 15  0  0  0  0\n"
110
+      "0  3  0  0  0  0  0  7  7  7  7  0  0 11 11 11 11  0  0 15  0  0  0  0\n"
111
+      "0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0\n"
112
+      , 24, 7,
113
+      DATA ( 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
114
+	     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
115
+	     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
116
+	     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
117
+	     0x000000, 0x333333, 0x333333, 0x333333, 0x333333, 0x000000,
118
+	     0x000000, 0x777777, 0x777777, 0x777777, 0x777777, 0x000000,
119
+	     0x000000, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0x000000,
120
+	     0x000000, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000,
121
+	     0x000000, 0x333333, 0x000000, 0x000000, 0x000000, 0x000000,
122
+	     0x000000, 0x777777, 0x000000, 0x000000, 0x000000, 0x000000,
123
+	     0x000000, 0xbbbbbb, 0x000000, 0x000000, 0x000000, 0x000000,
124
+	     0x000000, 0xffffff, 0x000000, 0x000000, 0xffffff, 0x000000,
125
+	     0x000000, 0x333333, 0x333333, 0x333333, 0x000000, 0x000000,
126
+	     0x000000, 0x777777, 0x777777, 0x777777, 0x000000, 0x000000,
127
+	     0x000000, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0x000000, 0x000000,
128
+	     0x000000, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000,
129
+	     0x000000, 0x333333, 0x000000, 0x000000, 0x000000, 0x000000,
130
+	     0x000000, 0x777777, 0x000000, 0x000000, 0x000000, 0x000000,
131
+	     0x000000, 0xbbbbbb, 0x000000, 0x000000, 0x000000, 0x000000,
132
+	     0x000000, 0xffffff, 0x000000, 0x000000, 0x000000, 0x000000,
133
+	     0x000000, 0x333333, 0x000000, 0x000000, 0x000000, 0x000000,
134
+	     0x000000, 0x777777, 0x777777, 0x777777, 0x777777, 0x000000,
135
+	     0x000000, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0x000000,
136
+	     0x000000, 0xffffff, 0x000000, 0x000000, 0x000000, 0x000000,
137
+	     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
138
+	     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
139
+	     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
140
+	     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000 ) );
141
+
142
+/** PPM ASCII example (from Wikipedia) */
143
+PNM ( ppm_ascii,
144
+      "P3\n"
145
+      "# The P3 means colors are in ASCII, then 3 columns and 2 rows,\n"
146
+      "# then 255 for max color, then RGB triplets\n"
147
+      "3 2\n"
148
+      "255\n"
149
+      "255   0   0     0 255   0     0   0 255\n"
150
+      "255 255   0   255 255 255     0   0   0\n",
151
+      3, 2,
152
+      DATA ( 0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xffffff, 0x000000 ) );
153
+
154
+/** PBM ASCII with no space between pixel values */
155
+PNM ( pbm_ascii_no_space,
156
+      "P1\n"
157
+      "3 3\n"
158
+      "001\n"
159
+      "010\n"
160
+      "111\n",
161
+      3, 3,
162
+      DATA ( 0xffffff, 0xffffff, 0x000000, 0xffffff, 0x000000, 0xffffff,
163
+	     0x000000, 0x000000, 0x000000 ) );
164
+
165
+/** PBM binary example (converted from Wikipedia) */
166
+PNM ( pbm_binary,
167
+      DATA ( 0x50, 0x34, 0x0a, 0x23, 0x20, 0x43, 0x52, 0x45, 0x41, 0x54, 0x4f,
168
+	     0x52, 0x3a, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x20, 0x50, 0x4e, 0x4d,
169
+	     0x20, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x20, 0x56, 0x65, 0x72,
170
+	     0x73, 0x69, 0x6f, 0x6e, 0x20, 0x31, 0x2e, 0x31, 0x0a, 0x36, 0x20,
171
+	     0x31, 0x30, 0x0a, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x88, 0x70,
172
+	     0x00, 0x00 ),
173
+      6, 10,
174
+      DATA ( 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff,
175
+	     0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff,
176
+	     0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff,
177
+	     0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff,
178
+	     0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff,
179
+	     0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff,
180
+	     0x000000, 0xffffff, 0xffffff, 0xffffff, 0x000000, 0xffffff,
181
+	     0xffffff, 0x000000, 0x000000, 0x000000, 0xffffff, 0xffffff,
182
+	     0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff,
183
+	     0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0xffffff ) );
184
+
185
+/** PGM binary example (converted from Wikipedia) */
186
+PNM ( pgm_binary,
187
+      DATA ( 0x50, 0x35, 0x0a, 0x32, 0x34, 0x20, 0x37, 0x0a, 0x31, 0x35, 0x0a,
188
+	     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
189
+	     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190
+	     0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x07, 0x07,
191
+	     0x07, 0x07, 0x00, 0x00, 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x00, 0x0f,
192
+	     0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
193
+	     0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x00,
194
+	     0x00, 0x0f, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x03, 0x03, 0x03, 0x00,
195
+	     0x00, 0x00, 0x07, 0x07, 0x07, 0x00, 0x00, 0x00, 0x0b, 0x0b, 0x0b,
196
+	     0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x03, 0x00,
197
+	     0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
198
+	     0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00,
199
+	     0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, 0x00,
200
+	     0x00, 0x0b, 0x0b, 0x0b, 0x0b, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
201
+	     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
202
+	     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
203
+	     0x00, 0x00, 0x00 ),
204
+      24, 7,
205
+      DATA ( 0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
206
+	     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
207
+	     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
208
+	     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
209
+	     0x000000, 0x333333, 0x333333, 0x333333, 0x333333, 0x000000,
210
+	     0x000000, 0x777777, 0x777777, 0x777777, 0x777777, 0x000000,
211
+	     0x000000, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0x000000,
212
+	     0x000000, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000,
213
+	     0x000000, 0x333333, 0x000000, 0x000000, 0x000000, 0x000000,
214
+	     0x000000, 0x777777, 0x000000, 0x000000, 0x000000, 0x000000,
215
+	     0x000000, 0xbbbbbb, 0x000000, 0x000000, 0x000000, 0x000000,
216
+	     0x000000, 0xffffff, 0x000000, 0x000000, 0xffffff, 0x000000,
217
+	     0x000000, 0x333333, 0x333333, 0x333333, 0x000000, 0x000000,
218
+	     0x000000, 0x777777, 0x777777, 0x777777, 0x000000, 0x000000,
219
+	     0x000000, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0x000000, 0x000000,
220
+	     0x000000, 0xffffff, 0xffffff, 0xffffff, 0xffffff, 0x000000,
221
+	     0x000000, 0x333333, 0x000000, 0x000000, 0x000000, 0x000000,
222
+	     0x000000, 0x777777, 0x000000, 0x000000, 0x000000, 0x000000,
223
+	     0x000000, 0xbbbbbb, 0x000000, 0x000000, 0x000000, 0x000000,
224
+	     0x000000, 0xffffff, 0x000000, 0x000000, 0x000000, 0x000000,
225
+	     0x000000, 0x333333, 0x000000, 0x000000, 0x000000, 0x000000,
226
+	     0x000000, 0x777777, 0x777777, 0x777777, 0x777777, 0x000000,
227
+	     0x000000, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0xbbbbbb, 0x000000,
228
+	     0x000000, 0xffffff, 0x000000, 0x000000, 0x000000, 0x000000,
229
+	     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
230
+	     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
231
+	     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000,
232
+	     0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000 ) );
233
+
234
+/** PPM binary example (converted from Wikipedia) */
235
+PNM ( ppm_binary,
236
+      DATA ( 0x50, 0x36, 0x0a, 0x33, 0x20, 0x32, 0x0a, 0x32, 0x35, 0x35, 0x0a,
237
+	     0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
238
+	     0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00 ),
239
+      3, 2,
240
+      DATA ( 0xff0000, 0x00ff00, 0x0000ff, 0xffff00, 0xffffff, 0x000000 ) );
241
+
242
+/**
243
+ * Report PNM test result
244
+ *
245
+ * @v test		PNM test
246
+ */
247
+#define pnm_ok( test ) do {						\
248
+	struct pixel_buffer *pixbuf;					\
249
+	uint8_t data[ (test)->len ];					\
250
+	int rc;								\
251
+									\
252
+	/* Sanity check */						\
253
+	assert ( ( (test)->width * (test)->height *			\
254
+		   sizeof ( (test)->data[0] ) ) == (test)->len );	\
255
+									\
256
+	/* Correct image data pointer */				\
257
+	(test)->image->data =						\
258
+		virt_to_user ( ( void * ) (test)->image->data );	\
259
+									\
260
+	/* Perform tests */						\
261
+	ok ( image_probe ( (test)->image ) == 0 );			\
262
+	ok ( (test)->image->type == &pnm_image_type );			\
263
+	ok ( ( rc = image_pixbuf ( (test)->image, &pixbuf ) ) == 0 );	\
264
+	if ( rc == 0 ) {						\
265
+		ok ( pixbuf->width == (test)->width );			\
266
+		ok ( pixbuf->height == (test)->height );		\
267
+		ok ( pixbuf->len == (test)->len );			\
268
+		copy_from_user ( data, pixbuf->data, 0,			\
269
+				 sizeof ( data ) );			\
270
+		ok ( memcmp ( data, (test)->data,			\
271
+			      sizeof ( data ) ) == 0 );			\
272
+		DBGC_HDA ( (test)->image, 0, data, sizeof ( data ) );	\
273
+		pixbuf_put ( pixbuf );					\
274
+	}								\
275
+	} while ( 0 )
276
+
277
+/**
278
+ * Perform PNM self-test
279
+ *
280
+ */
281
+static void pnm_test_exec ( void ) {
282
+
283
+	pnm_ok ( &pbm_ascii );
284
+	pnm_ok ( &pgm_ascii );
285
+	pnm_ok ( &ppm_ascii );
286
+	pnm_ok ( &pbm_ascii_no_space );
287
+	pnm_ok ( &pbm_binary );
288
+	pnm_ok ( &pgm_binary );
289
+	pnm_ok ( &ppm_binary );
290
+}
291
+
292
+/** PNM self-test */
293
+struct self_test pnm_test __self_test = {
294
+	.name = "pnm",
295
+	.exec = pnm_test_exec,
296
+};

+ 1
- 0
src/tests/tests.c View File

@@ -49,3 +49,4 @@ REQUIRE_OBJECT ( rsa_test );
49 49
 REQUIRE_OBJECT ( x509_test );
50 50
 REQUIRE_OBJECT ( ocsp_test );
51 51
 REQUIRE_OBJECT ( cms_test );
52
+REQUIRE_OBJECT ( pnm_test );

Loading…
Cancel
Save