📄 jpg2.c
字号:
{ j->sampling[i].h_samp_factor /= min_h_samp_factor; j->sampling[i].v_samp_factor /= min_v_samp_factor; } j->max_h_samp_factor /= min_h_samp_factor; j->max_v_samp_factor /= min_v_samp_factor; ASSERT(j->component_array[0] != NULL ); ASSERT(j->component_array[1] != NULL ); ASSERT(j->component_array[2] != NULL ); j->cinfo.raw_data_out = TRUE; /* work out what the yuv setting is */ j->yuv_mode = get_yuv_mode(j); }#if FLAVOUR_YUV else if (j->cinfo.jpeg_color_space == JCS_YCbCr ) { j->cinfo.out_color_space = JCS_YCbCr; }#endif /* FLAVOUR_YUV */#endif /* LAYERS_FB_32BITS */ else { j->cinfo.out_color_space = JCS_RGB; if (!deepsprite) { j->cinfo.desired_number_of_colors = 256; j->cinfo.quantize_colors = TRUE; } } { webimage2_rc rc; rc = webimage2__jpeg_info( j, &j->cinfo ); if ( rc != webimage2_OK ) { jpeg_destroy_decompress( &j->cinfo ); return rc; } } /* warning, casting function pointer to void* not guaranteed by ANSI */ dest_mgr = j->sink = jinit_write_sprite( &j->cinfo, j->w->handle, (void *) &j->w->putdst, (void *) &j->w->seekdst, (void *) &j->w->getdst, (j->w->flags & webimage_JPEG32) == 0, (j->cinfo.raw_data_out != 0), j->rotate); if ( jpeg_has_multiple_scans( &j->cinfo ) ) { j->state = jpegstate_PROGRESSIVE; goto progressive; } j->state = jpegstate_STARTIMAGE; /* drop through */ case jpegstate_STARTIMAGE: if ( !jpeg_start_decompress( &j->cinfo ) ) return webimage2_OK; /* Suspension point */ j->cinfo.dither_mode = JDITHER_FS; (*dest_mgr->start_output)( &j->cinfo, dest_mgr ); j->state = jpegstate_IMAGE; /* drop through */ case jpegstate_IMAGE:#if LAYERS_FB_32BITS if ( (j->w->flags & webimage_JPEGYUV422) != 0 ) { while ( j->cinfo.output_scanline < j->cinfo.output_height ) { int num_scanlines = jpeg_read_raw_data ( &j->cinfo, j->component_array, j->cinfo.max_v_samp_factor * j->cinfo.min_DCT_scaled_size); if ( !num_scanlines ) return webimage2_OK; /* Suspension point */ if (j->cinfo.output_scanline > j->cinfo.output_height ) { int fudge = j->cinfo.output_scanline - j->cinfo.output_height; num_scanlines -= fudge; j->cinfo.output_scanline -= fudge; } process_raw_data ( j, num_scanlines ); call_changed_function( j, num_scanlines ); } } else#endif { unsigned int offset = 0; while ( j->cinfo.output_scanline < j->cinfo.output_height ) { int num_scanlines = jpeg_read_scanlines( &j->cinfo, dest_mgr->buffer + offset, dest_mgr->buffer_height-offset ); if ( !num_scanlines && !offset) return webimage2_OK; /* Suspension point */ offset += num_scanlines; if (offset == dest_mgr->buffer_height || !num_scanlines || j->cinfo.output_scanline >= j->cinfo.output_height) { (*dest_mgr->put_pixel_rows)( &j->cinfo, dest_mgr, offset ); call_changed_function( j, offset ); offset = 0; } if (!num_scanlines) return webimage2_OK; /* Suspension point */ } } (*dest_mgr->finish_output)( &j->cinfo, dest_mgr ); j->state = jpegstate_FINISHING; /* drop through */ case jpegstate_FINISHING: finishing: if ( !jpeg_finish_decompress( &j->cinfo ) ) return webimage2_OK; /* Suspension point */ jpeg_destroy_decompress( &j->cinfo ); j->state = jpegstate_FINISHED; return webimage2_OK; /* States for progressive JPEGs start here */ case jpegstate_PROGRESSIVE: progressive: j->prog.oldscan = -1; j->prog.nextscan = TRUE; j->prog.final_pass = FALSE; j->cinfo.buffered_image = TRUE; if ( !jpeg_start_decompress( &j->cinfo ) ) return webimage2_OK; /* Suspension point */ (*dest_mgr->start_output)( &j->cinfo, dest_mgr ); j->state = jpegstate_PROGRESSIVE_STARTSCAN; /* drop through */ case jpegstate_PROGRESSIVE_STARTSCAN: progressive_startscan: { int rc; do { rc = jpeg_consume_input( &j->cinfo ); if ( rc == JPEG_SUSPENDED ) return webimage2_OK; /* Suspension point */ } while ( rc != JPEG_REACHED_EOI && rc != JPEG_ROW_COMPLETED ); } if ( !j->prog.final_pass && jpeg_input_complete( &j->cinfo ) ) { j->prog.final_pass = TRUE; j->cinfo.dither_mode = JDITHER_FS; j->prog.nextscan = TRUE; } if ( j->cinfo.input_scan_number != j->prog.oldscan && j->prog.nextscan ) { goto progressive_finishingscan; } j->state = jpegstate_PROGRESSIVE_IMAGE; /* drop through */ case jpegstate_PROGRESSIVE_IMAGE: progressive_image:#if LAYERS_FB_32BITS if ((j->w->flags & webimage_JPEGYUV422) != 0 ) { while ( j->cinfo.output_scanline < j->cinfo.output_height ) { int num_scanlines = jpeg_read_raw_data ( &j->cinfo, j->component_array, j->cinfo.max_v_samp_factor * j->cinfo.min_DCT_scaled_size); if ( !num_scanlines ) return webimage2_OK; /* Suspension point */ if (j->cinfo.output_scanline > j->cinfo.output_height ) { int fudge = j->cinfo.output_scanline - j->cinfo.output_height; num_scanlines -= fudge; j->cinfo.output_scanline -= fudge; } process_raw_data ( j, num_scanlines ); call_changed_function( j, num_scanlines ); } } else#endif { unsigned int offset = 0; while ( j->cinfo.output_scanline < j->cinfo.output_height ) { int num_scanlines = jpeg_read_scanlines( &j->cinfo, dest_mgr->buffer + offset, dest_mgr->buffer_height-offset ); if ( !num_scanlines && !offset) return webimage2_OK; /* Suspension point */ offset += num_scanlines; if (offset == dest_mgr->buffer_height || !num_scanlines || j->cinfo.output_scanline >= j->cinfo.output_height) { (*dest_mgr->put_pixel_rows)( &j->cinfo, dest_mgr, offset ); call_changed_function( j, offset ); offset = 0; } if (!num_scanlines) return webimage2_OK; /* Suspension point */ } } j->prog.nextscan = TRUE; if ( !j->prog.final_pass ) goto progressive_startscan; jpeg_finish_output( &j->cinfo ); goto finishing; case jpegstate_PROGRESSIVE_FINISHINGSCAN: progressive_finishingscan: if ( j->prog.oldscan != -1 ) if ( !jpeg_finish_output( &j->cinfo ) ) return webimage2_OK; /* Suspension point */ j->state = jpegstate_PROGRESSIVE_STARTINGSCAN; /* drop through */ case jpegstate_PROGRESSIVE_STARTINGSCAN: if ( !jpeg_start_output( &j->cinfo, j->cinfo.input_scan_number ) ) return webimage2_OK; /* Suspension point */ /* Seek to start of output sprite */ j->w->seekdst( j->image_offset, j->w->handle ); j->prog.oldscan = j->cinfo.input_scan_number; j->state = jpegstate_PROGRESSIVE_IMAGE; goto progressive_image; default: break; } return webimage2_OK;}/* not interested in the details of the progress just want a regular * callback */static void progress_monitor (j_common_ptr cinfo){ layers_hourglass_tick(); NOT_USED(cinfo);}static webimage2_rc webimage2__jpeg_feed( void *handle, void *buf, size_t *pnBytes, BOOL eof ){ webimage2_jpeg j; struct webimage2_error_mgr emgr; int skip; int nBytes = *pnBytes; webimage2_rc rc; j = (webimage2_jpeg) handle; TASSERT( j->magic == WEBIMAGE2_JPEGMAGIC ); skip = j->skipping; if ( skip >= nBytes ) { WIDBG(("wi%p: webimage2__jpeg_feed, skipping ENTIRE new buffer (%d bytes)\n", j->w, nBytes )); j->skipping -= nBytes; return webimage2_OK; } j->skipping = 0; /* Set up error handler */ j->cinfo.err = jpeg_std_error( &emgr.base ); j->cinfo.err->error_exit = webimage2__jpeg_error; j->cinfo.err->output_message = webimage2__jpeg_message; /* setup progress monitor */ j->progress.progress_monitor = progress_monitor; j->cinfo.progress = &j->progress; j->buf = ((char*)buf) + skip; j->nBytes = nBytes - skip; j->new_buffer = TRUE; j->eof = eof; if ( setjmp( emgr.jmpbuf ) ) { /* Error return */ jpeg_destroy_decompress( &j->cinfo ); j->state = jpegstate_ERROR; WIDBG(("wi%p: JPEG feeder returning error\n", j->w ));#if DEBUG { char buffer[JMSG_LENGTH_MAX]; (*j->cinfo.err->format_message)((j_common_ptr)&j->cinfo, buffer); WIDBG(("wi%p: error is '%s'\n", j->w, buffer )); }#endif return webimage2_ERROR; } rc = webimage2__jpeg_state_machine( j ); *pnBytes = nBytes - j->nBytes; return rc;} /*==================* * Finalisation * *==================*/static void webimage2__jpeg_destroy( void** pHandle ){ if ( pHandle && *pHandle ) { webimage2_jpeg j = (webimage2_jpeg)*pHandle; *pHandle = NULL; TASSERT( j->magic == WEBIMAGE2_JPEGMAGIC ); jpeg_destroy_decompress( &j->cinfo ); mm_free( j ); }} /*=================* * Constructor * *=================*/static const webimage2_decoder jpeg_decoder = { webimage2__jpeg_init, webimage2__jpeg_feed, webimage2__jpeg_destroy};const webimage2_decoder *webimage2_jpeg_recognise( void *buf, size_t nBytes ){ unsigned char *cbuf = (unsigned char*) buf; /* Detect a JPEG file */ if (cbuf[0] == 0xff && cbuf[1] == 0xd8 && cbuf[2] == 0xff) return &jpeg_decoder; NOT_USED(nBytes); /* No, not a JPEG */ return NULL;}/* eof */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -