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:
parent
84cef16f47
commit
dcf9d82a95
@ -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/metadata.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/pngdec.c
|
${CMAKE_CURRENT_SOURCE_DIR}/imageio/pngdec.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/pngdec.h
|
${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.c
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/tiffdec.h
|
${CMAKE_CURRENT_SOURCE_DIR}/imageio/tiffdec.h
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/imageio/webpdec.c
|
${CMAKE_CURRENT_SOURCE_DIR}/imageio/webpdec.c
|
||||||
|
@ -263,6 +263,7 @@ IMAGEIO_DEC_OBJS = \
|
|||||||
$(DIROBJ)\imageio\jpegdec.obj \
|
$(DIROBJ)\imageio\jpegdec.obj \
|
||||||
$(DIROBJ)\imageio\metadata.obj \
|
$(DIROBJ)\imageio\metadata.obj \
|
||||||
$(DIROBJ)\imageio\pngdec.obj \
|
$(DIROBJ)\imageio\pngdec.obj \
|
||||||
|
$(DIROBJ)\imageio\pnmdec.obj \
|
||||||
$(DIROBJ)\imageio\tiffdec.obj \
|
$(DIROBJ)\imageio\tiffdec.obj \
|
||||||
$(DIROBJ)\imageio\webpdec.obj \
|
$(DIROBJ)\imageio\webpdec.obj \
|
||||||
$(DIROBJ)\imageio\wicdec.obj \
|
$(DIROBJ)\imageio\wicdec.obj \
|
||||||
|
@ -288,6 +288,7 @@ model {
|
|||||||
include "jpegdec.c"
|
include "jpegdec.c"
|
||||||
include "metadata.c"
|
include "metadata.c"
|
||||||
include "pngdec.c"
|
include "pngdec.c"
|
||||||
|
include "pnmdec.c"
|
||||||
include "tiffdec.c"
|
include "tiffdec.c"
|
||||||
include "webpdec.c"
|
include "webpdec.c"
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ LOCAL_SRC_FILES := \
|
|||||||
jpegdec.c \
|
jpegdec.c \
|
||||||
metadata.c \
|
metadata.c \
|
||||||
pngdec.c \
|
pngdec.c \
|
||||||
|
pnmdec.c \
|
||||||
tiffdec.c \
|
tiffdec.c \
|
||||||
webpdec.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 += jpegdec.c jpegdec.h
|
||||||
libimagedec_la_SOURCES += metadata.c metadata.h
|
libimagedec_la_SOURCES += metadata.c metadata.h
|
||||||
libimagedec_la_SOURCES += pngdec.c pngdec.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 += tiffdec.c tiffdec.h
|
||||||
libimagedec_la_SOURCES += webpdec.c webpdec.h
|
libimagedec_la_SOURCES += webpdec.c webpdec.h
|
||||||
libimagedec_la_SOURCES += wicdec.c wicdec.h
|
libimagedec_la_SOURCES += wicdec.c wicdec.h
|
||||||
|
@ -29,6 +29,10 @@ WebPInputFileFormat WebPGuessImageType(const uint8_t* const data,
|
|||||||
format = WEBP_TIFF_FORMAT;
|
format = WEBP_TIFF_FORMAT;
|
||||||
} else if (magic1 == 0x52494646 && magic2 == 0x57454250) {
|
} else if (magic1 == 0x52494646 && magic2 == 0x57454250) {
|
||||||
format = WEBP_WEBP_FORMAT;
|
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;
|
return format;
|
||||||
@ -51,6 +55,7 @@ WebPImageReader WebPGetImageReader(WebPInputFileFormat format) {
|
|||||||
case WEBP_JPEG_FORMAT: return ReadJPEG;
|
case WEBP_JPEG_FORMAT: return ReadJPEG;
|
||||||
case WEBP_TIFF_FORMAT: return ReadTIFF;
|
case WEBP_TIFF_FORMAT: return ReadTIFF;
|
||||||
case WEBP_WEBP_FORMAT: return ReadWebP;
|
case WEBP_WEBP_FORMAT: return ReadWebP;
|
||||||
|
case WEBP_PNM_FORMAT: return ReadPNM;
|
||||||
default: return FailReader;
|
default: return FailReader;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "./metadata.h"
|
#include "./metadata.h"
|
||||||
#include "./jpegdec.h"
|
#include "./jpegdec.h"
|
||||||
#include "./pngdec.h"
|
#include "./pngdec.h"
|
||||||
|
#include "./pnmdec.h"
|
||||||
#include "./tiffdec.h"
|
#include "./tiffdec.h"
|
||||||
#include "./webpdec.h"
|
#include "./webpdec.h"
|
||||||
#include "./wicdec.h"
|
#include "./wicdec.h"
|
||||||
@ -36,6 +37,7 @@ typedef enum {
|
|||||||
WEBP_JPEG_FORMAT,
|
WEBP_JPEG_FORMAT,
|
||||||
WEBP_TIFF_FORMAT,
|
WEBP_TIFF_FORMAT,
|
||||||
WEBP_WEBP_FORMAT,
|
WEBP_WEBP_FORMAT,
|
||||||
|
WEBP_PNM_FORMAT,
|
||||||
WEBP_UNSUPPORTED_FORMAT
|
WEBP_UNSUPPORTED_FORMAT
|
||||||
} WebPInputFileFormat;
|
} 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/jpegdec.o \
|
||||||
imageio/metadata.o \
|
imageio/metadata.o \
|
||||||
imageio/pngdec.o \
|
imageio/pngdec.o \
|
||||||
|
imageio/pnmdec.o \
|
||||||
imageio/tiffdec.o \
|
imageio/tiffdec.o \
|
||||||
imageio/webpdec.o \
|
imageio/webpdec.o \
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user