jpeg.c
Upload User: zlh9724
Upload Date: 2007-01-04
Package Size: 1991k
Code Size: 7k
Category:

Browser Client

Development Platform:

Unix_Linux

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include "jpeglib.h"
  4. #include "jerror.h"
  5. #include "jinclude.h"
  6. #include <setjmp.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <fcntl.h>
  10. #include <limits.h>     /* definition of OPEN_MAX */
  11. #include <X11/Intrinsic.h>
  12. #include "HTUtils.h" /* WWW general purpose macros */
  13. #include "tcp.h"
  14. #include "HTList.h"
  15. #include "HTAccess.h"
  16. #include "www.h"
  17. #ifdef JPEG
  18. JSAMPLE *image_buffer; /* Points to large array of R,G,B-order data */
  19. int image_height; /* Number of rows in image */
  20. int image_width; /* Number of columns in image */
  21. #define MAX_BUFFER 10000
  22. #define MAX_ROWS   10
  23. typedef struct {
  24.    unsigned char *buffer;
  25.    int filled;
  26.    } buffer_struct;
  27. typedef struct {
  28.   struct jpeg_source_mgr pub; /* public fields */
  29.   buffer_struct *buffer;
  30.   int state;
  31.   JOCTET terminal[2];
  32. } my_source_mgr;
  33. typedef my_source_mgr * my_src_ptr;
  34. #define IMAGE_COLOUR_SPACE_UNKNOWN 0
  35. #define IMAGE_COLOUR_SPACE_GREYSCALE 1
  36. #define IMAGE_COLOUR_SPACE_RGB 2
  37. static void my_input_manager  (j_decompress_ptr cinfo, buffer_struct *buffer);
  38. GLOBAL int image_transform_jpeg (
  39. void *buffer_data, 
  40. int buffer_size,
  41. int declare_data_frame (void *userdata, image_data *data),
  42. int put_scanline_someplace (void *userdata, image_data *data),
  43. void *userdata
  44. );
  45. extern int ImageOutputInit (void *output,
  46. image_data *data);
  47. extern int ImageOutputScanlines (void *output, 
  48. image_data *data);
  49. unsigned char *LoadJPEGImage(Image *image, Block *bp, unsigned int depth) {
  50.     output_image_data _output_data, *output_data;
  51.     output_data = &_output_data;
  52.     output_data->depth = depth;
  53.     image_transform_jpeg (
  54. (void*)bp->buffer, bp->size, 
  55. ImageOutputInit,
  56. ImageOutputScanlines, 
  57. output_data);
  58.     image->width = output_data->width;
  59.     image->height = output_data->height;
  60.     return output_data->data;
  61. }
  62. #ifdef STANDALONE_TEST
  63. extern int put_scanline_someplace (void *userdata, image_data *data);
  64. extern int declare_data_frame (void *userdata, image_data *data);
  65. extern int main (int argc, char *argv[], char *envp[]) {
  66.    char  *filename = argv[1];
  67.    int  file;
  68.    int status;
  69.    unsigned char buffer [MAX_BUFFER];
  70.    void  *userdata;
  71.    printf ("Process file %sn", filename);
  72.    file = open (filename, O_RDONLY, 0);
  73.    status = read (file, buffer, MAX_BUFFER);
  74.    close (file);
  75.    printf ("file read %dn", status);
  76.    image_transform_jpeg (
  77. (void*)buffer, status, 
  78. declare_data_frame,
  79. put_scanline_someplace, 
  80. userdata);
  81.    printf ("finished :-)n");
  82.    }
  83. extern int declare_data_frame (void *userdata, image_data *data) {
  84.    printf ("The picture size is %d, %d components %dn", 
  85. data->height, data->width, data->components);
  86.    }
  87. extern int put_scanline_someplace (void *userdata, image_data *data) {
  88.    int count;
  89.    int total=0;
  90.    unsigned char *buffer = data->buffer;
  91.    for (count=0; count<(data->components*data->width*data->rows); count++) {
  92.         total = total + buffer[count];
  93. }
  94.    printf ("[%d=%d]", data->rows, total);
  95.    return (1);
  96.    }
  97. #endif
  98. struct my_error_mgr {
  99.   struct jpeg_error_mgr pub; /* "public" fields */
  100.   jmp_buf setjmp_buffer; /* for return to caller */
  101. };
  102. typedef struct my_error_mgr * my_error_ptr;
  103. METHODDEF void my_error_exit (j_common_ptr cinfo) {
  104.   my_error_ptr myerr = (my_error_ptr) cinfo->err;
  105.   longjmp(myerr->setjmp_buffer, 1);
  106. }
  107. GLOBAL int image_transform_jpeg (
  108. void *buffer_data, 
  109. int buffer_size,
  110. int declare_data_frame (void *userdata, image_data *data),
  111. int put_scanline_someplace (void *userdata, image_data *data),
  112. void *userdata
  113. ) {
  114.   struct jpeg_decompress_struct cinfo;
  115.   struct my_error_mgr jerr;
  116.   JSAMPARRAY buffer; /* Output row buffer */
  117.   int row_stride; /* physical row width in output buffer */
  118.   int rows;
  119.   image_data _idata, *idata;
  120.   buffer_struct _buffer_in, *buffer_in;
  121.   buffer_in = &_buffer_in;
  122.   idata = &_idata;
  123.   buffer_in->buffer = buffer_data;
  124.   buffer_in->filled = buffer_size;
  125.   cinfo.err = jpeg_std_error(&jerr.pub);
  126.   jerr.pub.error_exit = my_error_exit;
  127.   if (setjmp(jerr.setjmp_buffer)) {
  128.     jpeg_destroy_decompress(&cinfo);
  129.     return 0;
  130.   }
  131.     jpeg_create_decompress(&cinfo);
  132.     my_input_manager (&cinfo, buffer_in);
  133.     jpeg_read_header(&cinfo, TRUE);
  134.     jpeg_start_decompress(&cinfo);
  135.     idata->width = cinfo.output_width;
  136.     idata->height = cinfo.output_height;
  137.     idata->components = cinfo.output_components;
  138.     if (cinfo.out_color_space == JCS_GRAYSCALE) {
  139. idata->colour_space = IMAGE_COLOUR_SPACE_GREYSCALE;
  140. }
  141.     else if (cinfo.out_color_space == JCS_RGB) {
  142. idata->colour_space = IMAGE_COLOUR_SPACE_RGB;
  143. }
  144.     else {
  145. idata->colour_space = IMAGE_COLOUR_SPACE_UNKNOWN;
  146. }
  147.     idata->row_interlace = 1;
  148.     declare_data_frame (userdata, idata);
  149.     row_stride = cinfo.output_width * cinfo.output_components;
  150.     buffer = (*cinfo.mem->alloc_sarray)
  151. ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, MAX_ROWS);
  152.     idata->buffer = (unsigned char*) buffer [0];
  153.     while (cinfo.output_scanline < cinfo.output_height) {
  154.         rows = jpeg_read_scanlines(&cinfo, buffer, MAX_ROWS);
  155. idata->rows = rows;
  156.         put_scanline_someplace(userdata, idata);
  157.         }
  158.     jpeg_finish_decompress(&cinfo);
  159.     jpeg_destroy_decompress(&cinfo);
  160.     return 1;
  161.     }
  162. METHODDEF void init_source (j_decompress_ptr cinfo) {
  163.     my_src_ptr src = (my_src_ptr) cinfo->src;
  164.     src->state = 0;
  165.     }
  166. METHODDEF boolean fill_input_buffer (j_decompress_ptr cinfo) {
  167.   my_src_ptr src = (my_src_ptr) cinfo->src;
  168.   /* janet 21/07/95: not used:  size_t nbytes; */
  169.   /* Since we have given all we have got already we simply fake an end of
  170. file */
  171.   WARNMS(cinfo, JWRN_JPEG_EOF);
  172.   src->pub.next_input_byte = src->terminal;
  173.   src->pub.bytes_in_buffer = 2;
  174.   src->terminal[0] = (JOCTET) 0xFF;
  175.   src->terminal[0] = (JOCTET) JPEG_EOI;
  176.   return TRUE;
  177. }
  178. METHODDEF void skip_input_data (j_decompress_ptr cinfo, long num_bytes) {
  179.     my_src_ptr src = (my_src_ptr) cinfo->src;
  180.     src->pub.next_input_byte = src->pub.next_input_byte + num_bytes;
  181. }
  182. METHODDEF void term_source (j_decompress_ptr cinfo) {
  183.     }
  184. static void my_input_manager (j_decompress_ptr cinfo, buffer_struct *buffer) {
  185.   my_src_ptr src;
  186.   if (cinfo->src == NULL) { /* first time for this JPEG object? */
  187.     cinfo->src = (struct jpeg_source_mgr *)
  188.       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
  189.   SIZEOF(my_source_mgr));
  190.   }
  191.   src = (my_src_ptr) cinfo->src;
  192.   src->pub.init_source  = init_source;
  193.   src->pub.fill_input_buffer  = fill_input_buffer;
  194.   src->pub.skip_input_data  = skip_input_data;
  195.   src->pub.resync_to_restart  = jpeg_resync_to_restart; 
  196.   src->pub.term_source  = term_source;
  197.   src->pub.bytes_in_buffer  = buffer->filled;
  198.   src->pub.next_input_byte  = buffer->buffer;
  199.   src->buffer = buffer;
  200. }
  201. #endif /* JPEG */