void png_start(struct cached_image *cimg) { png_structp png_ptr; png_infop info_ptr; struct png_decoder *decoder; png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, img_my_png_error, img_my_png_warning); #ifdef DEBUG if (!png_ptr) internal("png_create_read_struct failed\n"); #endif /* #ifdef DEBUG */ info_ptr=png_create_info_struct(png_ptr); #ifdef DEBUG if (!info_ptr) internal ("png_create_info_struct failed\n"); #endif /* #ifdef DEBUG */ if (setjmp(png_ptr->jmpbuf)){ error: png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); img_end(cimg); return; } png_set_progressive_read_fn(png_ptr, NULL, png_info_callback, png_row_callback, png_end_callback); if (setjmp(png_ptr->jmpbuf)) goto error; decoder=mem_alloc(sizeof(*decoder)); decoder->png_ptr=png_ptr; decoder->info_ptr=info_ptr; cimg->decoder=decoder; }
void png_start(struct cached_image *cimg) { png_structp png_ptr; png_infop info_ptr; struct png_decoder *decoder; retry1: png_ptr=png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, img_my_png_error, img_my_png_warning); if (!png_ptr) { if (out_of_memory(0, NULL, 0)) goto retry1; fatal_exit("png_create_read_struct failed"); } retry2: info_ptr=png_create_info_struct(png_ptr); if (!info_ptr) { if (out_of_memory(0, NULL, 0)) goto retry2; fatal_exit("png_create_info_struct failed"); } if (setjmp(png_jmpbuf(png_ptr))){ error: png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); img_end(cimg); return; } png_set_progressive_read_fn(png_ptr, NULL, png_info_callback, &png_row_callback, png_end_callback); if (setjmp(png_jmpbuf(png_ptr))) goto error; decoder=mem_alloc(sizeof(*decoder)); decoder->png_ptr=png_ptr; decoder->info_ptr=info_ptr; cimg->decoder=decoder; }
void png_restart(struct cached_image *cimg, unsigned char *data, int length) { png_structp png_ptr; png_infop info_ptr; #ifdef DEBUG if (!cimg->decoder) internal("decoder NULL in png_restart\n"); #endif /* #ifdef DEBUG */ png_ptr=((struct png_decoder *)(cimg->decoder))->png_ptr; info_ptr=((struct png_decoder *)(cimg->decoder))->info_ptr; end_callback_hit=0; if (setjmp(png_ptr->jmpbuf)){ img_end(cimg); return; } png_process_data(png_ptr, info_ptr, data, length); if (end_callback_hit) img_end(cimg); }
void jpeg_start(struct cached_image *cimg) { struct jpg_decoder *jd; global_cinfo=mem_alloc(sizeof(*global_cinfo)); global_jerr=mem_alloc(sizeof(*global_jerr)); global_cinfo->err = jpeg_std_error(&(global_jerr->pub)); global_jerr->pub.error_exit=my_error_exit; global_jerr->pub.output_message=my_output_message; if (setjmp(global_jerr->setjmp_buffer)){ g19_2000: mem_free(global_cinfo); mem_free(global_jerr); img_end(cimg); return; } jpeg_create_decompress(global_cinfo); if (setjmp(global_jerr->setjmp_buffer)){ jpeg_destroy_decompress(global_cinfo); goto g19_2000; return; } jpeg_stdio_src(global_cinfo,stdin); global_cinfo->src->init_source=&nop; global_cinfo->src->fill_input_buffer=&my_fill_input_buffer; global_cinfo->src->skip_input_data=&my_skip_input_data; global_cinfo->src->resync_to_restart=&jpeg_resync_to_restart; global_cinfo->src->term_source=nop; global_cinfo->src->bytes_in_buffer=0; global_cinfo->src->next_input_byte=NULL; cimg->decoder=mem_alloc(sizeof(struct jpg_decoder)); jd=(struct jpg_decoder *)cimg->decoder; jd->cinfo=global_cinfo; jd->jerr=global_jerr; jd->state=0; jd->skip_bytes=0; jd->jdata=NULL; /* Scanlines can be left unititialized */ }
/* length is always !=NULL */ static int xbm_decode(struct cached_image *cimg, unsigned char *data, int length) { struct xbm_decoder *deco=(struct xbm_decoder *)cimg->decoder; /* okurky v decu ;-) */ int a; int must_return=0; restart_again: if (must_return&&!length)return 0; must_return=0; a=min(length,XBM_BUFFER_LEN-deco->buffer_pos); memcpy(deco->buffer+deco->buffer_pos,data,a); length-=a; deco->buffer_pos+=a; if (!deco->buffer_pos)return 0; /* z toho nic plodnyho nevznikne */ data+=a; if (!deco->in_data_block&&deco->partnum) { unsigned char *p; int a; int b,d; p=deco->buffer; a=deco->buffer_pos; *(deco->numdest)=xbm_read_num(&p,&a,&(deco->partnum),&d,&b); /* p i a ukazuje na 1. neciselnej znak (at uz za mezerama bylo cislo nebo nebylo) */ memmove(deco->buffer,p,a); deco->buffer_pos=a; if (deco->partnum) { must_return=1; /* zase konec bufferu */ goto restart_again; } } if (deco->width<0||deco->height<0) /* decoding header */ { unsigned char *p,*q; int *d; int a; int base, digits; p=my_memmem(deco->buffer,deco->buffer_pos,cast_uchar "width",5); q=my_memmem(deco->buffer,deco->buffer_pos,cast_uchar "height",6); if (!p&&!q) /* sezereme zacatek */ { int a=deco->buffer_pos>5?deco->buffer_pos:0; /* nesmime ukrast kus width/height */ memmove(deco->buffer,deco->buffer+deco->buffer_pos-a,deco->buffer_pos-a); /* sezereme to pred width/height */ deco->buffer_pos-=a; must_return=1; goto restart_again; } p=p&&q?min(p,q):max(p,q); /* bereme vetsi, protoze ten 2. je NULL */ memmove(deco->buffer,p,(deco->buffer_pos)+(deco->buffer)-p); /* sezereme to pred width/height */ deco->buffer_pos-=p-deco->buffer; /* deco->buffer zacina height/width */ if (deco->buffer[0]=='w') { p=deco->buffer+5; d=&(deco->width); } else { p=deco->buffer+6; d=&(deco->height); } a=deco->buffer_pos+deco->buffer-p; xbm_skip_space_tab(&p,&a); if (!a) { must_return=1; /* v bufferu je: width/height, whitespace, konec */ goto restart_again; } *d=xbm_read_num(&p,&a,&(deco->partnum),&digits, &base); if (deco->partnum)deco->numdest=d,must_return=1; /* p i a ukazuje na 1. neciselnej znak (at uz za mezerama bylo cislo nebo nebylo) */ memmove(deco->buffer,p,a); deco->buffer_pos=a; goto restart_again; } else /* decoding data */ { unsigned char *p; int a; int d=0,b=10; if (!deco->in_data_block) { p=memchr(deco->buffer,'{',deco->buffer_pos); if (!p) { deco->buffer_pos=0; /* sezerem celej blok a cekame na zavorku */ must_return=1; goto restart_again; } cimg->width=deco->width; cimg->height=deco->height; cimg->buffer_bytes_per_pixel=3; cimg->red_gamma=display_red_gamma; cimg->green_gamma=display_green_gamma; cimg->blue_gamma=display_blue_gamma; cimg->strip_optimized=0; if (header_dimensions_known(cimg)) { img_end(cimg); return 1; } deco->in_data_block=1; p++; memmove(deco->buffer,p,deco->buffer_pos+deco->buffer-p); /* sezereme to pred width/height */ deco->buffer_pos-=p-deco->buffer; deco->image_pos=0; deco->pixels=deco->width*deco->height; deco->line_pos=0; } p=deco->buffer; a=deco->buffer_pos; if (!deco->partnum) xbm_skip_whitespace(&p,&a); if (!a) { must_return=1; goto restart_again; } deco->actual_eight=xbm_read_num(&p,&a,&(deco->partnum),&d,&b); memmove(deco->buffer,p,a); deco->buffer_pos=a; if (deco->partnum)must_return=1; else put_eight(cimg,(b==16&&d>2)||(b==10&&deco->actual_eight>255)?16:8); if (deco->image_pos>=deco->pixels) { img_end(cimg); return 1; } goto restart_again; } }
void jpeg_restart(struct cached_image *cimg, unsigned char *data, int length) { struct jpg_decoder *deco; deco=(struct jpg_decoder *)(cimg->decoder); #ifdef DEBUG if (!deco) internal("NULL decoder in jpeg_restart"); #endif /* #ifdef DEBUG */ global_cinfo=((struct jpg_decoder *)(cimg->decoder))->cinfo; global_jerr=((struct jpg_decoder *)(cimg->decoder))->jerr; /* These global variables are here so that we don't have to pass lots * of structure pointers into each function. The jpeg decoder is never * running twice at the same time so it doesn't matter. */ /* If the decoder wants us to skip bytes it's not interested in */ if (deco->skip_bytes>=length){ /* If the decoder wants to skip as much as or more bytes than * the chunk that has just arrived */ deco->skip_bytes-=length; return; }else{ /* If the decoder wants to skip less bytes than the chunk * that has just arrived */ data+=deco->skip_bytes; length-=deco->skip_bytes; deco->skip_bytes=0; } /* Add the arrived data chunk into the decoder buffer. Sometimes the * chunks are so small the decoder can't move on on a single chunk * so it has to accumulate more chunks together. This is why the buffer * is there. */ if ((unsigned)global_cinfo->src->bytes_in_buffer + (unsigned)length > MAXINT) overalloc(); if ((unsigned)global_cinfo->src->bytes_in_buffer + (unsigned)length < (unsigned)length) overalloc(); if (deco->jdata){ /* If there is already some decoder buffer, we have to * allocate more space */ memmove(deco->jdata,global_cinfo->src->next_input_byte, global_cinfo->src->bytes_in_buffer); deco->jdata=mem_realloc( deco->jdata, global_cinfo->src->bytes_in_buffer+length); }else{ /* If there is no decoder buffer we'll have to allocate * space for a new buffer */ deco->jdata=mem_alloc(global_cinfo->src->bytes_in_buffer+length); } /* Copy the data iself into the decoder buffer */ memcpy(deco->jdata+global_cinfo->src->bytes_in_buffer ,data,length); /* Update the next input byte pointer for the decoder to continue at * the right position */ global_cinfo->src->next_input_byte=deco->jdata; /* ...:::...:..:.:::.:.::::.::.:.:.:.::..::::.::::.:...: */ /* Update the length of data in the decoder buffer */ global_cinfo->src->bytes_in_buffer+=length; if (setjmp(global_jerr->setjmp_buffer)) goto decoder_ended; switch(deco->state){ case 0: /* jpeg_read_header */ if (JPEG_SUSPENDED==jpeg_read_header(global_cinfo,TRUE)) break; global_cinfo->buffered_image=TRUE; deco->state=1; case 1: /* If the scaling is sufficiently brutal we can leave out * some DCT coefficients...: */ /* jpeg_start_decompress */ if (jpeg_start_decompress(global_cinfo)==FALSE) break; cimg->width=global_cinfo->output_width; cimg->height=global_cinfo->output_height; switch(cimg->buffer_bytes_per_pixel= global_cinfo->output_components) { case 1: /* We'll do the conversion ourselves * because libjpeg seems to be buggy */ cimg->buffer_bytes_per_pixel=3; break; case 3: /* RGB or YCrCb. We will ask libjpeg to * possibly convert from YCrCb to RGB. */ global_cinfo->out_color_space=JCS_RGB; break; case 4: /* CMYK or YCCK. We need to enable conversion * to CMYK and then convert CMYK data to RGBA * with dummy A ourselves. * We will ask libjpeg to possibly convert from * YCCK to CMYK. */ global_cinfo->out_color_space=JCS_CMYK; break; default: /* Let's make a decompression fatal error here */ if (!mesg_unsup_emitted){ fprintf(stderr, "Unsupported JPEG output components number: %d.\n", cimg->buffer_bytes_per_pixel); mesg_unsup_emitted=1; } longjmp(global_jerr->setjmp_buffer,2); /* longjmp() and siglongjmp() make programs hard to * understand and maintain. If possible an alternative * should be used. Hahaha :) ;-) */ /* Free will makes people hard to understand * and maintain. If possible an alternative should be * used. */ /* With our new LongJump(TM) your jumps will be longer * than with ordinary commercially available jumps. */ } cimg->red_gamma=sRGB_gamma; cimg->green_gamma=sRGB_gamma; cimg->blue_gamma=sRGB_gamma; /* This is defined in the JPEG standard somehow that sRGB * color space is used. */ cimg->strip_optimized=0; /* Strip optimization yet waits to be written. This will * allow huge jpegs to be processed without consuming * Links memory and consuming Xserver memory instead ;-) * However strip optimization is already written for PNG's. */ header_dimensions_known(cimg); new_scan: deco->state=2; case 2: /* jpeg_start_output */ if (FALSE==jpeg_start_output(global_cinfo,global_cinfo->input_scan_number)){ susp0: /* Suspended */ break; } deco->state=3; case 3: /* jpeg_read_scanlines */ /* color */ while (global_cinfo->output_scanline <global_cinfo->output_height){ int a, lines; for (a=0;a<16;a++){ deco->scanlines[a]=cimg->buffer +(global_cinfo ->output_scanline+a) *global_cinfo->output_width*cimg-> buffer_bytes_per_pixel; } if ((lines= jpeg_read_scanlines( global_cinfo,deco->scanlines,1))){ /* Some lines were written into cimg buffer */ cimg->rows_added=1; fix_data(deco, lines); }else{ /* No lines have been written into cimg * buffer */ /* We are suspended and we want more data */ goto susp0; /* Break the outer * switch statement */ } } deco->state=4; case 4: /* jpeg_finish_output */ if (FALSE==jpeg_finish_output(global_cinfo)) { /* Suspended */ break; } if (!jpeg_input_complete(global_cinfo)) { /* Some more scans awaited... */ goto new_scan; } deco->state=5; case 5: /* jpeg_finish_decompress */ if (FALSE==jpeg_finish_decompress(global_cinfo)) break; decoder_ended: img_end(cimg); } }