home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
MM1
/
GRAPHICS
/
jpegshow_3.0.lzh
/
JPEGSHOW
/
jpegshow.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-27
|
9KB
|
363 lines
#include <stdio.h>
#include <modes.h>
#include <signal.h>
#ifdef __UWLIBS__
typedef long size_t;
#endif
#include "jpeglib.h"
#include <setjmp.h>
#include "getargs.h"
#define TABSIZE (sizeof(Argtab)/sizeof(ARG))
#define SCREEN_WIDTH 384
#define SCREEN_HEIGHT 480
#define SCREEN_TYPE 9
#define X_MAX 45
#define Y_MAX 56
struct progress_mgr {
struct jpeg_progress_mgr pub; /* fields known to JPEG library */
int completed_extra_passes; /* extra passes completed */
int total_extra_passes; /* total extra */
/* last printed percentage stored here to avoid multiple printouts */
int percent_done;
};
struct progress_mgr progress;
typedef struct progress_mgr * progress_ptr;
int actwin, signum, pauselen = -1;
int iflag, xflag, yflag, scale = 1, sflag, vflag, wflag, gflag, mflag, dflag, rflag;
int xoffset, yoffset, gotsig;
extern errno;
extern int h_pos, v_pos;
unsigned char *scraddr, *sptr;
int row_stride; /* physical row width in output buffer */
JSAMPARRAY buffer; /* Output row buffer */
struct jpeg_decompress_struct cinfo;
struct my_error_mgr {
struct jpeg_error_mgr pub; /* "public" fields */
jmp_buf setjmp_buffer; /* for return to caller */
};
ARG Argtab[] =
{{'i', BOOLEAN, &iflag, "display header info only"},
{'d', INTEGER, &dflag, "debug level"},
{'g', BOOLEAN, &gflag, "grayscale output"},
{'m', BOOLEAN, &mflag, "mouse scrolling"},
{'p', INTEGER, &pauselen, "pause in secs (0 = no pause, -1= wait for user"},
{'r', BOOLEAN, &rflag, "report progress (only with -m)"},
{'s', INTEGER, &scale, "scale factor, must be 1, 2, 4 or 8"},
{'v', BOOLEAN, &vflag, "verbose"},
{'x', INTEGER, &xflag, "x offset in percent"},
{'y', INTEGER, &yflag, "y offset in percent"},
{'1', BOOLEAN, &sflag, "single pass (fast)"}};
typedef struct my_error_mgr *my_error_ptr;
unsigned char palette[3][256];
gotsignl(int signum)
{
gotsig = signum;
if (signum != SIGQUIT && signum != SIGINT)
return;
jpeg_destroy_decompress(&cinfo);
Select(0);
exit(signum);
}
int wait4user(int argc, char **argv)
{
char c;
if (pauselen > 0)
sleep(pauselen);
else if (pauselen < 0) {
if (mflag) {
_ss_sbar(actwin, h_pos, v_pos);
Bell(actwin);
return mmenu(actwin, argc, argv);
} else {
Bell(actwin);
do {
read(actwin, &c, 1);
} while (c != 13);
}
}
return 0;
}
METHODDEF void
progress_monitor (j_common_ptr cinfo)
{
progress_ptr prog = (progress_ptr) cinfo->progress;
int percent_done;
if ( prog->pub.completed_passes == 0 )
percent_done = (int) (prog->pub.pass_counter*X_MAX/prog->pub.pass_limit);
else
percent_done = (int) (prog->pub.pass_counter*Y_MAX/prog->pub.pass_limit);
if (percent_done != prog->percent_done) {
prog->percent_done = percent_done;
if ( prog->pub.completed_passes == 0 )
_ss_sbar(actwin, percent_done, v_pos);
else
_ss_sbar(actwin, h_pos, percent_done);
}
}
METHODDEF void my_error_exit(j_common_ptr cinfo)
{
my_error_ptr myerr = (my_error_ptr) cinfo->err;
(*cinfo->err->output_message) (cinfo);
longjmp(myerr->setjmp_buffer, 1);
}
GLOBAL int read_JPEG_file(char *filename)
{
struct my_error_mgr jerr;
FILE *infile; /* source file */
int i;
if ((infile = fopen(filename, "r")) == NULL) {
fprintf(stderr, "can't open %s\n", filename);
return 0;
}
if (mflag)
_ss_tbar(actwin, filename);
cinfo.err = jpeg_std_error(&jerr.pub);
jerr.pub.error_exit = my_error_exit;
if (setjmp(jerr.setjmp_buffer)) {
jpeg_destroy_decompress(&cinfo);
Select(0);
fclose(infile);
return 0;
}
jpeg_create_decompress(&cinfo);
if ( rflag && mflag )
cinfo.progress = &progress.pub;
jpeg_stdio_src(&cinfo, infile);
(void) jpeg_read_header(&cinfo, TRUE);
cinfo.quantize_colors = TRUE;
cinfo.scale_num = 1;
cinfo.scale_denom = scale;
cinfo.err->trace_level = dflag;
jpeg_calc_output_dimensions(&cinfo);
row_stride = cinfo.output_width;
if (mflag)
buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) & cinfo, JPOOL_PERMANENT, row_stride, cinfo.output_height);
else
buffer = (*cinfo.mem->alloc_sarray)
((j_common_ptr) & cinfo, JPOOL_PERMANENT, row_stride, 1);
if (sflag)
cinfo.two_pass_quantize = FALSE;
if (gflag)
cinfo.out_color_space = JCS_GRAYSCALE;
if (mflag)
cinfo.desired_number_of_colors = 254;
jpeg_start_decompress(&cinfo);
if (iflag || vflag) {
fprintf(stderr, "output width x height = %d x %d\n",
cinfo.output_width, cinfo.output_height);
fprintf(stderr, "actual number of colors = %d\n",
cinfo.actual_number_of_colors);
}
if (iflag) {
jpeg_destroy_decompress(&cinfo);
return 0;
}
xoffset = xflag * cinfo.output_width / 100;
yoffset = yflag * cinfo.output_height / 100;
if ( cinfo.out_color_space == JCS_GRAYSCALE )
for (i = 0; i < cinfo.desired_number_of_colors; i++)
Palette(actwin, i,
cinfo.colormap[0][i], cinfo.colormap[0][i], cinfo.colormap[0][i]);
else
for (i = 0; i < cinfo.desired_number_of_colors; i++)
Palette(actwin, i,
cinfo.colormap[0][i], cinfo.colormap[1][i], cinfo.colormap[2][i]);
while (cinfo.output_scanline < cinfo.output_height) {
if (mflag) {
(void) jpeg_read_scanlines(&cinfo, &buffer[cinfo.output_scanline], 1);
put_scanline_m(buffer[cinfo.output_scanline - 1], row_stride,
cinfo.output_scanline);
} else {
(void) jpeg_read_scanlines(&cinfo, &buffer[0], 1);
put_scanline(buffer[0], row_stride);
}
}
(void) jpeg_finish_decompress(&cinfo);
fclose(infile);
return 1;
}
main(int argc, char **argv)
{
int res, i;
argc = getargs(argc, argv, Argtab, TABSIZE);
if ( argc < 2 )
exit(0);
if (scale != 1 && scale != 2 && scale != 4 && scale != 8) {
fprintf(stderr, "scale = %d, must be 1, 2, 4 or 8 - ignored\n", scale);
scale = 1;
}
if (xflag < 0 || xflag >= 100) {
fprintf(stderr, "x offset = %d, must be 0 - 100 %% - ignored\n", xflag);
xflag = 0;
}
if (yflag < 0 || yflag >= 100) {
fprintf(stderr, "x offset = %d, must be 0 - 100 %% - ignored\n", yflag);
yflag = 0;
}
if (!iflag) {
actwin = open("/w", S_IWRITE | S_IREAD);
if (actwin == EOF)
exit(_errmsg(errno, "cannot open '/w'\n"));
if (DWSet(actwin, SCREEN_TYPE, 0, 0, SCREEN_WIDTH / 8, SCREEN_HEIGHT / 8,
0, 0, 0) == EOF)
exit(_errmsg(errno, "cannot DWSet\n"));
CurOff(actwin);
ScaleSw(actwin, 0);
scraddr = (unsigned char *) _gs_scadd(actwin);
if (scraddr == NULL)
exit(_errmsg(errno, "cannot _gs_scadd\n"));
if (mflag) {
scraddr += 16 * SCREEN_WIDTH + 8;
openwin(actwin);
}
Select(actwin);
} else
sflag = 1;
intercept(gotsignl);
for ( i = 1; i < argc; i++ ) {
sptr = scraddr;
if (!iflag)
Clear(actwin);
h_pos = v_pos = 0;
_ss_sbar(actwin, h_pos, v_pos);
if ( rflag && mflag ) {
progress.pub.progress_monitor = progress_monitor;
progress.completed_extra_passes = 0;
progress.total_extra_passes = 0;
progress.percent_done = -1;
}
if (read_JPEG_file(argv[i]) == 0)
continue;
res = wait4user(argc, argv);
jpeg_destroy_decompress(&cinfo);
if ( res == -1 && i > 1 )
i -= 2;
if ( res > 0 )
i = res - 1;
}
Select(0);
}
put_scanline(unsigned char *a, int r_s)
{
register int count;
register unsigned char *dest, *src, *next;
r_s -= xoffset;
if (cinfo.output_scanline < yoffset ||
cinfo.output_scanline - yoffset > SCREEN_HEIGHT / 2 || r_s < 0)
return;
count = (r_s < SCREEN_WIDTH) ? r_s : SCREEN_WIDTH;
dest = sptr;
next = dest + SCREEN_WIDTH;
src = a + xoffset;
while (count--)
*dest++ = *next++ = *src++;
sptr += SCREEN_WIDTH * 2;
}
put_scanline_m(unsigned char *a, int r_s, int n)
{
register int count;
register unsigned char *dest, *src, *next;
r_s -= xoffset;
if (n < yoffset || n - yoffset > (SCREEN_HEIGHT - 24) / 2 || r_s < 0)
return;
count = (r_s < SCREEN_WIDTH - 16) ? r_s : SCREEN_WIDTH - 16;
dest = sptr;
next = dest + SCREEN_WIDTH;
src = a + xoffset;
while (count--)
*dest++ = *next++ = *src++;
sptr += SCREEN_WIDTH * 2;
}
int repaint(int x, int y)
{
register int i;
if ( cinfo.output_width < SCREEN_WIDTH - 16 && x > 0 )
return 0;
if ( cinfo.output_height < SCREEN_HEIGHT / 2 - 12 && y > 0 )
return 0;
xoffset = x * (cinfo.output_width - SCREEN_WIDTH + 16) / X_MAX;
yoffset = y * (cinfo.output_height - SCREEN_HEIGHT / 2 + 12) / Y_MAX;
sptr = scraddr;
Clear(actwin);
for ( i = 0; i < cinfo.output_height; i++ )
put_scanline_m(buffer[i], row_stride, i);
return 1;
}