mirror of
				https://github.com/webmproject/libwebp.git
				synced 2025-10-31 18:35:41 +01:00 
			
		
		
		
	imageio: add limited PNM support for reading
see: http://netpbm.sourceforge.net/ Only reads P5 and P6 pnm files for now. Change-Id: I2332a623f803df67455047f570f1cff9f464480a
This commit is contained in:
		| @@ -124,6 +124,8 @@ if(WEBP_BUILD_CWEBP OR WEBP_BUILD_DWEBP OR | ||||
|     ${CMAKE_CURRENT_SOURCE_DIR}/imageio/metadata.h | ||||
|     ${CMAKE_CURRENT_SOURCE_DIR}/imageio/pngdec.c | ||||
|     ${CMAKE_CURRENT_SOURCE_DIR}/imageio/pngdec.h | ||||
|     ${CMAKE_CURRENT_SOURCE_DIR}/imageio/pnmdec.c | ||||
|     ${CMAKE_CURRENT_SOURCE_DIR}/imageio/pnmdec.h | ||||
|     ${CMAKE_CURRENT_SOURCE_DIR}/imageio/tiffdec.c | ||||
|     ${CMAKE_CURRENT_SOURCE_DIR}/imageio/tiffdec.h | ||||
|     ${CMAKE_CURRENT_SOURCE_DIR}/imageio/webpdec.c | ||||
|   | ||||
| @@ -263,6 +263,7 @@ IMAGEIO_DEC_OBJS = \ | ||||
|     $(DIROBJ)\imageio\jpegdec.obj \ | ||||
|     $(DIROBJ)\imageio\metadata.obj \ | ||||
|     $(DIROBJ)\imageio\pngdec.obj \ | ||||
|     $(DIROBJ)\imageio\pnmdec.obj \ | ||||
|     $(DIROBJ)\imageio\tiffdec.obj \ | ||||
|     $(DIROBJ)\imageio\webpdec.obj \ | ||||
|     $(DIROBJ)\imageio\wicdec.obj \ | ||||
|   | ||||
| @@ -288,6 +288,7 @@ model { | ||||
|             include "jpegdec.c" | ||||
|             include "metadata.c" | ||||
|             include "pngdec.c" | ||||
|             include "pnmdec.c" | ||||
|             include "tiffdec.c" | ||||
|             include "webpdec.c" | ||||
|           } | ||||
|   | ||||
| @@ -25,6 +25,7 @@ LOCAL_SRC_FILES := \ | ||||
|     jpegdec.c \ | ||||
|     metadata.c \ | ||||
|     pngdec.c \ | ||||
|     pnmdec.c \ | ||||
|     tiffdec.c \ | ||||
|     webpdec.c \ | ||||
|  | ||||
|   | ||||
| @@ -11,6 +11,7 @@ libimagedec_la_SOURCES  = image_dec.c image_dec.h | ||||
| libimagedec_la_SOURCES += jpegdec.c jpegdec.h | ||||
| libimagedec_la_SOURCES += metadata.c metadata.h | ||||
| libimagedec_la_SOURCES += pngdec.c pngdec.h | ||||
| libimagedec_la_SOURCES += pnmdec.c pnmdec.h | ||||
| libimagedec_la_SOURCES += tiffdec.c tiffdec.h | ||||
| libimagedec_la_SOURCES += webpdec.c webpdec.h | ||||
| libimagedec_la_SOURCES += wicdec.c wicdec.h | ||||
|   | ||||
| @@ -29,6 +29,10 @@ WebPInputFileFormat WebPGuessImageType(const uint8_t* const data, | ||||
|       format = WEBP_TIFF_FORMAT; | ||||
|     } else if (magic1 == 0x52494646 && magic2 == 0x57454250) { | ||||
|       format = WEBP_WEBP_FORMAT; | ||||
|     } else if (((magic1 >> 24) & 0xff) == 'P') { | ||||
|       const int type = (magic1 >> 16) & 0xff; | ||||
|       // we only support 'P5' and 'P6' for now. | ||||
|       if (type >= '5' && type <= '6') format = WEBP_PNM_FORMAT; | ||||
|     } | ||||
|   } | ||||
|   return format; | ||||
| @@ -51,6 +55,7 @@ WebPImageReader WebPGetImageReader(WebPInputFileFormat format) { | ||||
|     case WEBP_JPEG_FORMAT: return ReadJPEG; | ||||
|     case WEBP_TIFF_FORMAT: return ReadTIFF; | ||||
|     case WEBP_WEBP_FORMAT: return ReadWebP; | ||||
|     case WEBP_PNM_FORMAT: return ReadPNM; | ||||
|     default: return FailReader; | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -23,6 +23,7 @@ | ||||
| #include "./metadata.h" | ||||
| #include "./jpegdec.h" | ||||
| #include "./pngdec.h" | ||||
| #include "./pnmdec.h" | ||||
| #include "./tiffdec.h" | ||||
| #include "./webpdec.h" | ||||
| #include "./wicdec.h" | ||||
| @@ -36,6 +37,7 @@ typedef enum { | ||||
|   WEBP_JPEG_FORMAT, | ||||
|   WEBP_TIFF_FORMAT, | ||||
|   WEBP_WEBP_FORMAT, | ||||
|   WEBP_PNM_FORMAT, | ||||
|   WEBP_UNSUPPORTED_FORMAT | ||||
| } WebPInputFileFormat; | ||||
|  | ||||
|   | ||||
							
								
								
									
										142
									
								
								imageio/pnmdec.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								imageio/pnmdec.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,142 @@ | ||||
| // Copyright 2017 Google Inc. All Rights Reserved. | ||||
| // | ||||
| // Use of this source code is governed by a BSD-style license | ||||
| // that can be found in the COPYING file in the root of the source | ||||
| // tree. An additional intellectual property rights grant can be found | ||||
| // in the file PATENTS. All contributing project authors may | ||||
| // be found in the AUTHORS file in the root of the source tree. | ||||
| // ----------------------------------------------------------------------------- | ||||
| // | ||||
| // (limited) PNM decoder | ||||
|  | ||||
| #include "./pnmdec.h" | ||||
|  | ||||
| #include <assert.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "webp/encode.h" | ||||
| #include "./imageio_util.h" | ||||
|  | ||||
| // ----------------------------------------------------------------------------- | ||||
| // PNM decoding | ||||
|  | ||||
| #define MAX_LINE_SIZE 1024 | ||||
| static const size_t kMinPNMHeaderSize = 3; | ||||
|  | ||||
| static size_t ReadLine(const uint8_t* const data, size_t off, size_t data_size, | ||||
|                        char out[MAX_LINE_SIZE + 1], size_t* const out_size) { | ||||
|   size_t i = 0; | ||||
|   *out_size = 0; | ||||
|  redo: | ||||
|   for (i = 0; i < MAX_LINE_SIZE && off < data_size; ++i) { | ||||
|     out[i] = data[off++]; | ||||
|     if (out[i] == '\n') break; | ||||
|   } | ||||
|   if (off < data_size) { | ||||
|     if (i == 0) goto redo;         // empty line | ||||
|     if (out[0] == '#') goto redo;  // skip comment | ||||
|   } | ||||
|   out[i] = 0;   // safety sentinel | ||||
|   *out_size = i; | ||||
|   return off; | ||||
| } | ||||
|  | ||||
| static size_t ReadHeader(const uint8_t* const data, size_t data_size, | ||||
|                          int* const width, int* const height, | ||||
|                          int* const type, int* const max_value) { | ||||
|   size_t off = 0; | ||||
|   char out[MAX_LINE_SIZE + 1]; | ||||
|   size_t out_size; | ||||
|   if (width == NULL || height == NULL || type == NULL || max_value == NULL) { | ||||
|     return 0; | ||||
|   } | ||||
|   *width = 0; | ||||
|   *height = 0; | ||||
|   *type = -1; | ||||
|   *max_value = 0; | ||||
|   if (data == NULL || data_size < kMinPNMHeaderSize) return 0; | ||||
|   off = ReadLine(data, off, data_size, out, &out_size); | ||||
|   if (off == 0 || sscanf(out, "P%d", type) != 1) return 0; | ||||
|   off = ReadLine(data, off, data_size, out, &out_size); | ||||
|   if (off == 0 || sscanf(out, "%d %d", width, height) != 2) return 0; | ||||
|   off = ReadLine(data, off, data_size, out, &out_size); | ||||
|   if (off == 0 || sscanf(out, "%d", max_value) != 1) return 0; | ||||
|   return off; | ||||
| } | ||||
|  | ||||
| int ReadPNM(const uint8_t* const data, size_t data_size, | ||||
|             WebPPicture* const pic, int keep_alpha, | ||||
|             struct Metadata* const metadata) { | ||||
|   int ok = 0; | ||||
|   int width, height, type, max_value; | ||||
|   int i, j; | ||||
|   uint64_t stride; | ||||
|   uint8_t* rgb = NULL, *tmp_rgb; | ||||
|   size_t offset; | ||||
|  | ||||
|   offset = ReadHeader(data, data_size, &width, &height, | ||||
|                       &type, &max_value); | ||||
|   if (offset == 0) goto End; | ||||
|   if (type != 5 && type != 6) { | ||||
|     fprintf(stderr, "Unsupported P%d PNM format.\n", type); | ||||
|     goto End; | ||||
|   } | ||||
|  | ||||
|   // Some basic validations. | ||||
|   if (pic == NULL) goto End; | ||||
|   if (width <= 0 || height <= 0 || | ||||
|       width > WEBP_MAX_DIMENSION || height > WEBP_MAX_DIMENSION) { | ||||
|     fprintf(stderr, "Invalid %dx%d dimension for PNM\n", width, height); | ||||
|     goto End; | ||||
|   } | ||||
|  | ||||
|   stride = 3LL * width; | ||||
|   if (stride != (size_t)stride || | ||||
|       !ImgIoUtilCheckSizeArgumentsOverflow(stride, height)) { | ||||
|     goto End; | ||||
|   } | ||||
|   if ((type == 5 && offset + 1LL * width * height > data_size) || | ||||
|       (type == 6 && offset + 3LL * width * height > data_size)) { | ||||
|     fprintf(stderr, "Truncated PNM file (P%d).\n", type); | ||||
|     goto End; | ||||
|   } | ||||
|  | ||||
|   rgb = (uint8_t*)malloc((size_t)stride * height); | ||||
|   if (rgb == NULL) goto End; | ||||
|  | ||||
|   // Convert input | ||||
|   tmp_rgb = rgb; | ||||
|   for (j = 0; j < height; ++j) { | ||||
|     if (type == 5) { | ||||
|       assert(offset + width <= data_size); | ||||
|       for (i = 0; i < width; ++i) { | ||||
|         const uint8_t v = data[offset + i]; | ||||
|         tmp_rgb[3 * i + 0] = tmp_rgb[3 * i + 1] = tmp_rgb[3 * i + 2] = v; | ||||
|       } | ||||
|       offset += width; | ||||
|     } else if (type == 6) { | ||||
|       assert(offset + 3LL * width <= data_size); | ||||
|       memcpy(tmp_rgb, data + offset, 3 * width * sizeof(*data)); | ||||
|       offset += 3 * width; | ||||
|     } | ||||
|     tmp_rgb += stride; | ||||
|   } | ||||
|  | ||||
|   // WebP conversion. | ||||
|   pic->width = width; | ||||
|   pic->height = height; | ||||
|   ok = WebPPictureImportRGB(pic, rgb, (int)stride); | ||||
|   if (!ok) goto End; | ||||
|  | ||||
|   ok = 1; | ||||
|  End: | ||||
|   free((void*)rgb); | ||||
|  | ||||
|   (void)metadata; | ||||
|   (void)keep_alpha; | ||||
|   return ok; | ||||
| } | ||||
|  | ||||
| // ----------------------------------------------------------------------------- | ||||
							
								
								
									
										37
									
								
								imageio/pnmdec.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								imageio/pnmdec.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| // Copyright 2017 Google Inc. All Rights Reserved. | ||||
| // | ||||
| // Use of this source code is governed by a BSD-style license | ||||
| // that can be found in the COPYING file in the root of the source | ||||
| // tree. An additional intellectual property rights grant can be found | ||||
| // in the file PATENTS. All contributing project authors may | ||||
| // be found in the AUTHORS file in the root of the source tree. | ||||
| // ----------------------------------------------------------------------------- | ||||
| // | ||||
| // partial PNM format decoder (ppm/pgm) | ||||
|  | ||||
| #ifndef WEBP_IMAGEIO_PNMDEC_H_ | ||||
| #define WEBP_IMAGEIO_PNMDEC_H_ | ||||
|  | ||||
| #include "webp/types.h" | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| extern "C" { | ||||
| #endif | ||||
|  | ||||
| struct Metadata; | ||||
| struct WebPPicture; | ||||
|  | ||||
| // Reads a PNM file from 'data', returning the decoded output in 'pic'. | ||||
| // The output is RGB or YUV depending on pic->use_argb value. | ||||
| // Returns true on success. | ||||
| // 'metadata' has no effect, but is kept for coherence with other signatures | ||||
| // for image readers. | ||||
| int ReadPNM(const uint8_t* const data, size_t data_size, | ||||
|             struct WebPPicture* const pic, int keep_alpha, | ||||
|             struct Metadata* const metadata); | ||||
|  | ||||
| #ifdef __cplusplus | ||||
| }    // extern "C" | ||||
| #endif | ||||
|  | ||||
| #endif  // WEBP_IMAGEIO_PNMDEC_H_ | ||||
| @@ -223,6 +223,7 @@ EX_FORMAT_DEC_OBJS = \ | ||||
|     imageio/jpegdec.o \ | ||||
|     imageio/metadata.o \ | ||||
|     imageio/pngdec.o \ | ||||
|     imageio/pnmdec.o \ | ||||
|     imageio/tiffdec.o \ | ||||
|     imageio/webpdec.o \ | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user