mirror of
https://github.com/NishiOwO/arena.git
synced 2025-04-21 16:54:42 +00:00
279 lines
6.7 KiB
C
279 lines
6.7 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "jpeglib.h"
|
|
#include "jerror.h"
|
|
#include "jinclude.h"
|
|
#include <setjmp.h>
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <limits.h> /* definition of OPEN_MAX */
|
|
|
|
|
|
#include <X11/Intrinsic.h>
|
|
|
|
#include "HTUtils.h" /* WWW general purpose macros */
|
|
#include "tcp.h"
|
|
#include "HTList.h"
|
|
#include "HTAccess.h"
|
|
|
|
#include "www.h"
|
|
|
|
#ifdef JPEG
|
|
|
|
JSAMPLE *image_buffer; /* Points to large array of R,G,B-order data */
|
|
int image_height; /* Number of rows in image */
|
|
int image_width; /* Number of columns in image */
|
|
|
|
#define MAX_BUFFER 10000
|
|
#define MAX_ROWS 10
|
|
|
|
typedef struct {
|
|
unsigned char *buffer;
|
|
int filled;
|
|
} buffer_struct;
|
|
|
|
typedef struct {
|
|
struct jpeg_source_mgr pub; /* public fields */
|
|
|
|
buffer_struct *buffer;
|
|
int state;
|
|
JOCTET terminal[2];
|
|
} my_source_mgr;
|
|
|
|
typedef my_source_mgr * my_src_ptr;
|
|
|
|
#define IMAGE_COLOUR_SPACE_UNKNOWN 0
|
|
#define IMAGE_COLOUR_SPACE_GREYSCALE 1
|
|
#define IMAGE_COLOUR_SPACE_RGB 2
|
|
|
|
|
|
|
|
|
|
static void my_input_manager (j_decompress_ptr cinfo, buffer_struct *buffer);
|
|
GLOBAL int image_transform_jpeg (
|
|
void *buffer_data,
|
|
int buffer_size,
|
|
int declare_data_frame (void *userdata, image_data *data),
|
|
int put_scanline_someplace (void *userdata, image_data *data),
|
|
void *userdata
|
|
);
|
|
|
|
extern int ImageOutputInit (void *output,
|
|
image_data *data);
|
|
extern int ImageOutputScanlines (void *output,
|
|
image_data *data);
|
|
|
|
unsigned char *LoadJPEGImage(Image *image, Block *bp, unsigned int depth) {
|
|
output_image_data _output_data, *output_data;
|
|
|
|
output_data = &_output_data;
|
|
|
|
output_data->depth = depth;
|
|
image_transform_jpeg (
|
|
(void*)bp->buffer, bp->size,
|
|
ImageOutputInit,
|
|
ImageOutputScanlines,
|
|
output_data);
|
|
|
|
image->width = output_data->width;
|
|
image->height = output_data->height;
|
|
|
|
return output_data->data;
|
|
}
|
|
|
|
|
|
#ifdef STANDALONE_TEST
|
|
|
|
extern int put_scanline_someplace (void *userdata, image_data *data);
|
|
extern int declare_data_frame (void *userdata, image_data *data);
|
|
|
|
extern int main (int argc, char *argv[], char *envp[]) {
|
|
char *filename = argv[1];
|
|
int file;
|
|
int status;
|
|
unsigned char buffer [MAX_BUFFER];
|
|
void *userdata;
|
|
|
|
printf ("Process file %s\n", filename);
|
|
|
|
file = open (filename, O_RDONLY, 0);
|
|
status = read (file, buffer, MAX_BUFFER);
|
|
close (file);
|
|
|
|
printf ("file read %d\n", status);
|
|
|
|
image_transform_jpeg (
|
|
(void*)buffer, status,
|
|
declare_data_frame,
|
|
put_scanline_someplace,
|
|
userdata);
|
|
|
|
printf ("finished :-)\n");
|
|
}
|
|
|
|
extern int declare_data_frame (void *userdata, image_data *data) {
|
|
printf ("The picture size is %d, %d components %d\n",
|
|
data->height, data->width, data->components);
|
|
}
|
|
extern int put_scanline_someplace (void *userdata, image_data *data) {
|
|
int count;
|
|
int total=0;
|
|
unsigned char *buffer = data->buffer;
|
|
|
|
for (count=0; count<(data->components*data->width*data->rows); count++) {
|
|
total = total + buffer[count];
|
|
}
|
|
printf ("[%d=%d]", data->rows, total);
|
|
|
|
return (1);
|
|
}
|
|
#endif
|
|
|
|
|
|
struct my_error_mgr {
|
|
struct jpeg_error_mgr pub; /* "public" fields */
|
|
|
|
jmp_buf setjmp_buffer; /* for return to caller */
|
|
};
|
|
|
|
typedef struct my_error_mgr * my_error_ptr;
|
|
|
|
METHODDEF void my_error_exit (j_common_ptr cinfo) {
|
|
my_error_ptr myerr = (my_error_ptr) cinfo->err;
|
|
|
|
longjmp(myerr->setjmp_buffer, 1);
|
|
}
|
|
|
|
|
|
GLOBAL int image_transform_jpeg (
|
|
void *buffer_data,
|
|
int buffer_size,
|
|
int declare_data_frame (void *userdata, image_data *data),
|
|
int put_scanline_someplace (void *userdata, image_data *data),
|
|
void *userdata
|
|
) {
|
|
|
|
struct jpeg_decompress_struct cinfo;
|
|
struct my_error_mgr jerr;
|
|
JSAMPARRAY buffer; /* Output row buffer */
|
|
int row_stride; /* physical row width in output buffer */
|
|
int rows;
|
|
|
|
image_data _idata, *idata;
|
|
|
|
buffer_struct _buffer_in, *buffer_in;
|
|
|
|
buffer_in = &_buffer_in;
|
|
idata = &_idata;
|
|
|
|
buffer_in->buffer = buffer_data;
|
|
buffer_in->filled = buffer_size;
|
|
|
|
cinfo.err = jpeg_std_error(&jerr.pub);
|
|
jerr.pub.error_exit = my_error_exit;
|
|
if (setjmp(jerr.setjmp_buffer)) {
|
|
jpeg_destroy_decompress(&cinfo);
|
|
return 0;
|
|
}
|
|
|
|
jpeg_create_decompress(&cinfo);
|
|
my_input_manager (&cinfo, buffer_in);
|
|
|
|
jpeg_read_header(&cinfo, TRUE);
|
|
jpeg_start_decompress(&cinfo);
|
|
|
|
idata->width = cinfo.output_width;
|
|
idata->height = cinfo.output_height;
|
|
idata->components = cinfo.output_components;
|
|
|
|
if (cinfo.out_color_space == JCS_GRAYSCALE) {
|
|
idata->colour_space = IMAGE_COLOUR_SPACE_GREYSCALE;
|
|
}
|
|
else if (cinfo.out_color_space == JCS_RGB) {
|
|
idata->colour_space = IMAGE_COLOUR_SPACE_RGB;
|
|
}
|
|
else {
|
|
idata->colour_space = IMAGE_COLOUR_SPACE_UNKNOWN;
|
|
}
|
|
idata->row_interlace = 1;
|
|
|
|
declare_data_frame (userdata, idata);
|
|
|
|
|
|
row_stride = cinfo.output_width * cinfo.output_components;
|
|
buffer = (*cinfo.mem->alloc_sarray)
|
|
((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, MAX_ROWS);
|
|
|
|
idata->buffer = (unsigned char*) buffer [0];
|
|
|
|
while (cinfo.output_scanline < cinfo.output_height) {
|
|
rows = jpeg_read_scanlines(&cinfo, buffer, MAX_ROWS);
|
|
idata->rows = rows;
|
|
put_scanline_someplace(userdata, idata);
|
|
}
|
|
|
|
jpeg_finish_decompress(&cinfo);
|
|
jpeg_destroy_decompress(&cinfo);
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
METHODDEF void init_source (j_decompress_ptr cinfo) {
|
|
my_src_ptr src = (my_src_ptr) cinfo->src;
|
|
src->state = 0;
|
|
}
|
|
|
|
METHODDEF boolean fill_input_buffer (j_decompress_ptr cinfo) {
|
|
my_src_ptr src = (my_src_ptr) cinfo->src;
|
|
/* janet 21/07/95: not used: size_t nbytes; */
|
|
|
|
/* Since we have given all we have got already we simply fake an end of
|
|
file */
|
|
WARNMS(cinfo, JWRN_JPEG_EOF);
|
|
src->pub.next_input_byte = src->terminal;
|
|
src->pub.bytes_in_buffer = 2;
|
|
src->terminal[0] = (JOCTET) 0xFF;
|
|
src->terminal[0] = (JOCTET) JPEG_EOI;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
METHODDEF void skip_input_data (j_decompress_ptr cinfo, long num_bytes) {
|
|
my_src_ptr src = (my_src_ptr) cinfo->src;
|
|
|
|
src->pub.next_input_byte = src->pub.next_input_byte + num_bytes;
|
|
}
|
|
|
|
|
|
METHODDEF void term_source (j_decompress_ptr cinfo) {
|
|
}
|
|
|
|
|
|
static void my_input_manager (j_decompress_ptr cinfo, buffer_struct *buffer) {
|
|
my_src_ptr src;
|
|
|
|
if (cinfo->src == NULL) { /* first time for this JPEG object? */
|
|
cinfo->src = (struct jpeg_source_mgr *)
|
|
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
|
SIZEOF(my_source_mgr));
|
|
}
|
|
|
|
src = (my_src_ptr) cinfo->src;
|
|
src->pub.init_source = init_source;
|
|
src->pub.fill_input_buffer = fill_input_buffer;
|
|
src->pub.skip_input_data = skip_input_data;
|
|
src->pub.resync_to_restart = jpeg_resync_to_restart;
|
|
src->pub.term_source = term_source;
|
|
|
|
src->pub.bytes_in_buffer = buffer->filled;
|
|
src->pub.next_input_byte = buffer->buffer;
|
|
|
|
src->buffer = buffer;
|
|
}
|
|
|
|
|
|
#endif /* JPEG */
|