📄 img_jpeg.c
字号:
/******************************************************************************* * * img_jpeg.c * * Original code from dillo http://dillo.sourceforge.net * * Hacked by Garett Spencley for Cheetah Web Browser * * Copyright (C) 1997 Raph Levien <raph@acm.org> * Copyright (C) 1999 James McCollough <jamesm@gtwn.net> * Copyright (C) 2000 Jorge Arellano Cid <jcid@users.sourceforge.net> * Copyright (C) 2001 Garett Spencley <gspen@home.com> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * *******************************************************************************/#include <stdio.h>#include <gtk/gtk.h>#include <string.h>#include "img_jpeg.h"#include "debug.h"METHODDEF(void) Jpeg_errorexit(j_common_ptr cinfo);/* this is the routine called by libjpeg when it detects an error. */METHODDEF(void) Jpeg_errorexit(j_common_ptr cinfo){ /* display message and return to setjmp buffer */ my_error_ptr myerr = (my_error_ptr) cinfo->err; (*cinfo->err->output_message) (cinfo); longjmp(myerr->setjmp_buffer, 1);}/* * MIME handler for "image/jpeg" type * (Sets Jpeg_callback or a_Dicache_callback as the cache-client) */DwWidget *a_Jpeg_image(const char *Type, ImageData *image, void **Data){ if (!image) image = Image_new(0, 0, NULL, DW_PAINT_DEFAULT_BGND); *Data = image; return DW_WIDGET(image);}/* * Finish the decoding process */void Jpeg_close(JpegImage *jpeg){ if(jpeg->state != JPEG_DONE) jpeg_destroy_decompress(&(jpeg->cinfo)); g_free(jpeg);}static void init_source(j_decompress_ptr cinfo){}static void term_source(j_decompress_ptr cinfo){}static boolean fill_input_buffer(j_decompress_ptr cinfo){ JpegImage *jpeg = ((my_source_mgr *) cinfo->src)->jpeg; debug_print("fill_input_buffer"); if (jpeg->Skip) { jpeg->Start_Ofs = jpeg->NewStart + jpeg->Skip - 1; jpeg->Skip = 0; } else { jpeg->Start_Ofs = (gulong) jpeg->cinfo.src->next_input_byte - (gulong) jpeg->Data; } return FALSE;}static void skip_input_data(j_decompress_ptr cinfo, glong num_bytes){ JpegImage *jpeg; if(num_bytes < 1) return; jpeg = ((my_source_mgr *) cinfo->src)->jpeg; debug_print("skip_input_data: Start_Ofs = %d, num_bytes = %d, %d bytes in buffer", jpeg->Start_Ofs, num_bytes, cinfo->src->bytes_in_buffer); cinfo->src->next_input_byte += num_bytes; if (num_bytes < (glong) cinfo->src->bytes_in_buffer) { cinfo->src->bytes_in_buffer -= num_bytes; } else { jpeg->Skip += num_bytes - cinfo->src->bytes_in_buffer + 1; cinfo->src->bytes_in_buffer = 0; }}JpegImage *Jpeg_new(ImageData *Image){ my_source_mgr *src; JpegImage *jpeg = g_malloc(sizeof(*jpeg)); jpeg->Image = Image; jpeg->state = JPEG_INIT; jpeg->Start_Ofs = 0; jpeg->Skip = 0; /* decompression step 1 (see libjpeg.doc) */ jpeg->cinfo.err = jpeg_std_error(&(jpeg->jerr.pub)); jpeg->jerr.pub.error_exit = Jpeg_errorexit; jpeg_create_decompress(&(jpeg->cinfo)); /* decompression step 2 (see libjpeg.doc) */ jpeg->cinfo.src = &jpeg->Src.pub; src = &jpeg->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.term_source = term_source; src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ src->pub.next_input_byte = NULL; /* until buffer loaded */ src->jpeg = jpeg; /* decompression steps continue in write method */ return jpeg;}/* * Receive and process new chunks of JPEG image data */void Jpeg_write(JpegImage *jpeg, void *Buf, guint BufSize){ ImageType type = IMG_TYPE_RGB; guchar *linebuf; JSAMPLE *array[1]; gint num_read; debug_print("Jpeg_write: (0x%lx) Bytes in buff: %ld Ofs: %d\n", jpeg, BufSize, jpeg->Start_Ofs); /* See if we are supposed to skip ahead. */ if (BufSize <= jpeg->Start_Ofs) return; /* Concatenate with the partial input, if any. */ jpeg->cinfo.src->next_input_byte = (guchar *) Buf + jpeg->Start_Ofs; jpeg->cinfo.src->bytes_in_buffer = BufSize - jpeg->Start_Ofs; jpeg->NewStart = BufSize; jpeg->Data = Buf; if (setjmp(jpeg->jerr.setjmp_buffer)) { /* If we get here, the JPEG code has signaled an error. */ jpeg->state = JPEG_ERROR; } /* Process the bytes in the input buffer. */ if (jpeg->state == JPEG_INIT) { /* decompression step 3 (see libjpeg.doc) */ if (jpeg_read_header(&(jpeg->cinfo), TRUE) != JPEG_SUSPENDED) { type = IMG_TYPE_GRAY; if (jpeg->cinfo.num_components == 1) type = IMG_TYPE_GRAY; else if (jpeg->cinfo.num_components == 3) type = IMG_TYPE_RGB; else g_print("jpeg: can't handle %d component images\n", jpeg->cinfo.num_components); /* decompression step 4 (see libjpeg.doc) */ jpeg->state = JPEG_STARTING; } } if (jpeg->state == JPEG_STARTING) { /* decompression step 5 (see libjpeg.doc) */ if (jpeg_start_decompress(&(jpeg->cinfo))) { jpeg->y = 0; jpeg->state = JPEG_READING; } } if (jpeg->state == JPEG_READING) { guchar *buf; size_t size; linebuf = g_malloc(jpeg->cinfo.image_width * jpeg->cinfo.num_components); array[0] = linebuf; size = jpeg->cinfo.image_height * jpeg->cinfo.image_width * 3; buf = g_malloc(size); Image_set_parms(jpeg->Image, buf, jpeg->cinfo.image_width, jpeg->cinfo.image_height, type); while (jpeg->y < jpeg->cinfo.image_height) { num_read = jpeg_read_scanlines(&(jpeg->cinfo), array, 1); if (num_read == 0) break; Image_write(jpeg->Image, linebuf, jpeg->y, TRUE); jpeg->y++; } if (jpeg->y == jpeg->cinfo.image_height) { debug_print("Jpeg: height achieved."); jpeg_destroy_decompress(&(jpeg->cinfo)); jpeg->state = JPEG_DONE; } g_free(linebuf); } if (jpeg->state == JPEG_ERROR) { jpeg_destroy_decompress(&(jpeg->cinfo)); jpeg->state = JPEG_DONE; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -