📄 mif_cod.c
字号:
/*
* Copyright (c) 2001-2002 Michael David Adams.
* All rights reserved.
*/
/* __START_OF_JASPER_LICENSE__
*
* JasPer License Version 2.0
*
* Copyright (c) 2001-2006 Michael David Adams
* Copyright (c) 1999-2000 Image Power, Inc.
* Copyright (c) 1999-2000 The University of British Columbia
*
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person (the
* "User") obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the
* following conditions:
*
* 1. The above copyright notices and this permission notice (which
* includes the disclaimer below) shall be included in all copies or
* substantial portions of the Software.
*
* 2. The name of a copyright holder shall not be used to endorse or
* promote products derived from the Software without specific prior
* written permission.
*
* THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
* LICENSE. NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
* THIS DISCLAIMER. THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
* "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
* INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. NO ASSURANCES ARE
* PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
* THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
* EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
* BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
* PROPERTY RIGHTS OR OTHERWISE. AS A CONDITION TO EXERCISING THE RIGHTS
* GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
* ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY. THE SOFTWARE
* IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
* SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
* AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
* SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
* THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
* PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
* RISK ACTIVITIES"). THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
* EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
*
* __END_OF_JASPER_LICENSE__
*/
/******************************************************************************\
* Includes.
\******************************************************************************/
#include <assert.h>
#include "jasper/jas_tvp.h"
#include "jasper/jas_stream.h"
#include "jasper/jas_image.h"
#include "jasper/jas_string.h"
#include "jasper/jas_malloc.h"
#include "mif_cod.h"
/******************************************************************************\
* Local types.
\******************************************************************************/
typedef enum {
MIF_END = 0,
MIF_CMPT
} mif_tagid2_t;
typedef enum {
MIF_TLX = 0,
MIF_TLY,
MIF_WIDTH,
MIF_HEIGHT,
MIF_HSAMP,
MIF_VSAMP,
MIF_PREC,
MIF_SGND,
MIF_DATA
} mif_tagid_t;
/******************************************************************************\
* Local functions.
\******************************************************************************/
static mif_hdr_t *mif_hdr_create(int maxcmpts);
static void mif_hdr_destroy(mif_hdr_t *hdr);
static int mif_hdr_growcmpts(mif_hdr_t *hdr, int maxcmpts);
static mif_hdr_t *mif_hdr_get(jas_stream_t *in);
static int mif_process_cmpt(mif_hdr_t *hdr, char *buf);
static int mif_hdr_put(mif_hdr_t *hdr, jas_stream_t *out);
static int mif_hdr_addcmpt(mif_hdr_t *hdr, int cmptno, mif_cmpt_t *cmpt);
static mif_cmpt_t *mif_cmpt_create(void);
static void mif_cmpt_destroy(mif_cmpt_t *cmpt);
static char *mif_getline(jas_stream_t *jas_stream, char *buf, int bufsize);
static int mif_getc(jas_stream_t *in);
static mif_hdr_t *mif_makehdrfromimage(jas_image_t *image);
/******************************************************************************\
* Local data.
\******************************************************************************/
jas_taginfo_t mif_tags2[] = {
{MIF_CMPT, "component"},
{MIF_END, "end"},
{-1, 0}
};
jas_taginfo_t mif_tags[] = {
{MIF_TLX, "tlx"},
{MIF_TLY, "tly"},
{MIF_WIDTH, "width"},
{MIF_HEIGHT, "height"},
{MIF_HSAMP, "sampperx"},
{MIF_VSAMP, "samppery"},
{MIF_PREC, "prec"},
{MIF_SGND, "sgnd"},
{MIF_DATA, "data"},
{-1, 0}
};
/******************************************************************************\
* Code for load operation.
\******************************************************************************/
/* Load an image from a stream in the MIF format. */
jas_image_t *mif_decode(jas_stream_t *in, char *optstr)
{
mif_hdr_t *hdr;
jas_image_t *image;
jas_image_t *tmpimage;
jas_stream_t *tmpstream;
int cmptno;
mif_cmpt_t *cmpt;
jas_image_cmptparm_t cmptparm;
jas_seq2d_t *data;
int_fast32_t x;
int_fast32_t y;
int bias;
/* Avoid warnings about unused parameters. */
optstr = 0;
hdr = 0;
image = 0;
tmpimage = 0;
tmpstream = 0;
data = 0;
if (!(hdr = mif_hdr_get(in))) {
goto error;
}
if (!(image = jas_image_create0())) {
goto error;
}
for (cmptno = 0; cmptno < hdr->numcmpts; ++cmptno) {
cmpt = hdr->cmpts[cmptno];
tmpstream = cmpt->data ? jas_stream_fopen(cmpt->data, "rb") : in;
if (!tmpstream) {
goto error;
}
if (!(tmpimage = jas_image_decode(tmpstream, -1, 0))) {
goto error;
}
if (tmpstream != in) {
jas_stream_close(tmpstream);
tmpstream = 0;
}
if (!cmpt->width) {
cmpt->width = jas_image_cmptwidth(tmpimage, 0);
}
if (!cmpt->height) {
cmpt->height = jas_image_cmptwidth(tmpimage, 0);
}
if (!cmpt->prec) {
cmpt->prec = jas_image_cmptprec(tmpimage, 0);
}
if (cmpt->sgnd < 0) {
cmpt->sgnd = jas_image_cmptsgnd(tmpimage, 0);
}
cmptparm.tlx = cmpt->tlx;
cmptparm.tly = cmpt->tly;
cmptparm.hstep = cmpt->sampperx;
cmptparm.vstep = cmpt->samppery;
cmptparm.width = cmpt->width;
cmptparm.height = cmpt->height;
cmptparm.prec = cmpt->prec;
cmptparm.sgnd = cmpt->sgnd;
if (jas_image_addcmpt(image, jas_image_numcmpts(image), &cmptparm)) {
goto error;
}
if (!(data = jas_seq2d_create(0, 0, cmpt->width, cmpt->height))) {
goto error;
}
if (jas_image_readcmpt(tmpimage, 0, 0, 0, cmpt->width, cmpt->height,
data)) {
goto error;
}
if (cmpt->sgnd) {
bias = 1 << (cmpt->prec - 1);
for (y = 0; y < cmpt->height; ++y) {
for (x = 0; x < cmpt->width; ++x) {
*jas_seq2d_getref(data, x, y) -= bias;
}
}
}
if (jas_image_writecmpt(image, jas_image_numcmpts(image) - 1, 0, 0,
cmpt->width, cmpt->height, data)) {
goto error;
}
jas_seq2d_destroy(data);
data = 0;
jas_image_destroy(tmpimage);
tmpimage = 0;
}
mif_hdr_destroy(hdr);
hdr = 0;
return image;
error:
if (image) {
jas_image_destroy(image);
}
if (hdr) {
mif_hdr_destroy(hdr);
}
if (tmpstream && tmpstream != in) {
jas_stream_close(tmpstream);
}
if (tmpimage) {
jas_image_destroy(tmpimage);
}
if (data) {
jas_seq2d_destroy(data);
}
return 0;
}
/******************************************************************************\
* Code for save operation.
\******************************************************************************/
/* Save an image to a stream in the the MIF format. */
int mif_encode(jas_image_t *image, jas_stream_t *out, char *optstr)
{
mif_hdr_t *hdr;
jas_image_t *tmpimage;
int fmt;
int cmptno;
mif_cmpt_t *cmpt;
jas_image_cmptparm_t cmptparm;
jas_seq2d_t *data;
int_fast32_t x;
int_fast32_t y;
int bias;
hdr = 0;
tmpimage = 0;
data = 0;
if (optstr && *optstr != '\0') {
jas_eprintf("warning: ignoring unsupported options\n");
}
if ((fmt = jas_image_strtofmt("pnm")) < 0) {
jas_eprintf("error: PNM support required\n");
goto error;
}
if (!(hdr = mif_makehdrfromimage(image))) {
goto error;
}
if (mif_hdr_put(hdr, out)) {
goto error;
}
/* Output component data. */
for (cmptno = 0; cmptno < hdr->numcmpts; ++cmptno) {
cmpt = hdr->cmpts[cmptno];
if (!cmpt->data) {
if (!(tmpimage = jas_image_create0())) {
goto error;
}
cmptparm.tlx = 0;
cmptparm.tly = 0;
cmptparm.hstep = cmpt->sampperx;
cmptparm.vstep = cmpt->samppery;
cmptparm.width = cmpt->width;
cmptparm.height = cmpt->height;
cmptparm.prec = cmpt->prec;
cmptparm.sgnd = false;
if (jas_image_addcmpt(tmpimage, jas_image_numcmpts(tmpimage), &cmptparm)) {
goto error;
}
if (!(data = jas_seq2d_create(0, 0, cmpt->width, cmpt->height))) {
goto error;
}
if (jas_image_readcmpt(image, cmptno, 0, 0, cmpt->width, cmpt->height,
data)) {
goto error;
}
if (cmpt->sgnd) {
bias = 1 << (cmpt->prec - 1);
for (y = 0; y < cmpt->height; ++y) {
for (x = 0; x < cmpt->width; ++x) {
*jas_seq2d_getref(data, x, y) += bias;
}
}
}
if (jas_image_writecmpt(tmpimage, 0, 0, 0, cmpt->width, cmpt->height,
data)) {
goto error;
}
jas_seq2d_destroy(data);
data = 0;
if (jas_image_encode(tmpimage, out, fmt, 0)) {
goto error;
}
jas_image_destroy(tmpimage);
tmpimage = 0;
}
}
mif_hdr_destroy(hdr);
return 0;
error:
if (hdr) {
mif_hdr_destroy(hdr);
}
if (tmpimage) {
jas_image_destroy(tmpimage);
}
if (data) {
jas_seq2d_destroy(data);
}
return -1;
}
/******************************************************************************\
* Code for validate operation.
\******************************************************************************/
int mif_validate(jas_stream_t *in)
{
uchar buf[MIF_MAGICLEN];
uint_fast32_t magic;
int i;
int n;
assert(JAS_STREAM_MAXPUTBACK >= MIF_MAGICLEN);
/* Read the validation data (i.e., the data used for detecting
the format). */
if ((n = jas_stream_read(in, buf, MIF_MAGICLEN)) < 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -