📄 loader_jpeg.cpp
字号:
// filling buffer with the new data memcpy(jsrc.buffer + jsrc.valid_buffer_len, buffer, consumed); jsrc.valid_buffer_len += consumed; if(jsrc.skip_input_bytes) {#ifdef BUFFER_DEBUG qDebug("doing skipping"); qDebug("valid_buffer_len %d", jsrc.valid_buffer_len); qDebug("skip_input_bytes %d", jsrc.skip_input_bytes);#endif int skipbytes = kMin((size_t) jsrc.valid_buffer_len, jsrc.skip_input_bytes); if(skipbytes < jsrc.valid_buffer_len) memmove(jsrc.buffer, jsrc.buffer+skipbytes, jsrc.valid_buffer_len - skipbytes); jsrc.valid_buffer_len -= skipbytes; jsrc.skip_input_bytes -= skipbytes; // still more bytes to skip if(jsrc.skip_input_bytes) { if(consumed <= 0) qDebug("ERROR!!!"); return consumed; } } cinfo.src->next_input_byte = (JOCTET *) jsrc.buffer; cinfo.src->bytes_in_buffer = (size_t) jsrc.valid_buffer_len;#ifdef BUFFER_DEBUG qDebug("buffer contains %d bytes", jsrc.valid_buffer_len);#endif if(state == Init) { if(jpeg_read_header(&cinfo, true) != JPEG_SUSPENDED) { // do some simple memory requirements limitations // as long as we use that stupid Qt stuff int s = cinfo.image_width * cinfo.image_height; if ( s > 16384 * 12388 ) cinfo.scale_denom = 8; else if ( s > 8192 * 6144 ) cinfo.scale_denom = 4; else if ( s > 4096 * 3072 ) cinfo.scale_denom = 2; if ( consumer ) consumer->setSize(cinfo.image_width/cinfo.scale_denom, cinfo.image_height/cinfo.scale_denom); state = startDecompress; } } if(state == startDecompress) { jsrc.do_progressive = jpeg_has_multiple_scans( &cinfo );#ifdef JPEG_DEBUG qDebug( "**** DOPROGRESSIVE: %d", jsrc.do_progressive );#endif if ( jsrc.do_progressive ) cinfo.buffered_image = true; else cinfo.buffered_image = false; // setup image sizes jpeg_calc_output_dimensions( &cinfo ); if ( cinfo.jpeg_color_space == JCS_YCbCr ) cinfo.out_color_space = JCS_RGB; cinfo.do_fancy_upsampling = true; cinfo.do_block_smoothing = false; cinfo.quantize_colors = false; // false: IO suspension if(jpeg_start_decompress(&cinfo)) { if ( cinfo.output_components == 3 || cinfo.output_components == 4) { image.create( cinfo.output_width, cinfo.output_height, 32 ); } else if ( cinfo.output_components == 1 ) { image.create( cinfo.output_width, cinfo.output_height, 8, 256 ); for (int i=0; i<256; i++) image.setColor(i, qRgb(i,i,i)); }#ifdef JPEG_DEBUG qDebug("will create a picture %d/%d in size", cinfo.output_width, cinfo.output_height);#endif#ifdef JPEG_DEBUG qDebug("ok, going to decompressStarted");#endif jsrc.decoder_timestamp.start(); state = jsrc.do_progressive ? decompressStarted : doOutputScan; } }again: if(state == decompressStarted) { state = (!jsrc.final_pass && jsrc.decoder_timestamp.elapsed() < max_consumingtime) ? consumeInput : prepareOutputScan; } if(state == consumeInput) { int retval; do { retval = jpeg_consume_input(&cinfo); } while (retval != JPEG_SUSPENDED && retval != JPEG_REACHED_EOI && (retval != JPEG_REACHED_SOS || jsrc.decoder_timestamp.elapsed() < max_consumingtime)); if(jsrc.decoder_timestamp.elapsed() >= max_consumingtime || jsrc.final_pass || retval == JPEG_REACHED_EOI || retval == JPEG_REACHED_SOS) state = prepareOutputScan; } if(state == prepareOutputScan) { if ( jpeg_start_output(&cinfo, cinfo.input_scan_number) ) state = doOutputScan; } if(state == doOutputScan) { if(image.isNull() || jsrc.decoding_done) {#ifdef JPEG_DEBUG qDebug("complete in doOutputscan, eating..");#endif return consumed; } uchar** lines = image.jumpTable(); int oldoutput_scanline = cinfo.output_scanline; while(cinfo.output_scanline < cinfo.output_height && jpeg_read_scanlines(&cinfo, lines+cinfo.output_scanline, cinfo.output_height)) ; // here happens all the magic of decoding int completed_scanlines = cinfo.output_scanline - oldoutput_scanline;#ifdef JPEG_DEBUG qDebug("completed now %d scanlines", completed_scanlines);#endif if ( cinfo.output_components == 3 ) { // Expand 24->32 bpp. for (int j=oldoutput_scanline; j<oldoutput_scanline+completed_scanlines; j++) { uchar *in = image.scanLine(j) + cinfo.output_width * 3; QRgb *out = (QRgb*)image.scanLine(j); for (uint i=cinfo.output_width; i--; ) { in-=3; out[i] = qRgb(in[0], in[1], in[2]); } } } if(consumer && completed_scanlines) { QRect r(0, oldoutput_scanline, cinfo.output_width, completed_scanlines);#ifdef JPEG_DEBUG qDebug("changing %d/%d %d/%d", r.x(), r.y(), r.width(), r.height());#endif jsrc.change_rect |= r; if ( jsrc.decoder_timestamp.elapsed() >= max_consumingtime ) { if( !jsrc.old_change_rect.isEmpty()) { consumer->changed(jsrc.old_change_rect); jsrc.old_change_rect = QRect(); } consumer->changed(jsrc.change_rect); jsrc.change_rect = QRect(); jsrc.decoder_timestamp.restart(); } } if(cinfo.output_scanline >= cinfo.output_height) { if ( jsrc.do_progressive ) { jpeg_finish_output(&cinfo); jsrc.final_pass = jpeg_input_complete(&cinfo); jsrc.decoding_done = jsrc.final_pass && cinfo.input_scan_number == cinfo.output_scan_number; if ( !jsrc.decoding_done ) { jsrc.old_change_rect |= jsrc.change_rect; jsrc.change_rect = QRect(); } } else jsrc.decoding_done = true;#ifdef JPEG_DEBUG qDebug("one pass is completed, final_pass = %d, dec_done: %d, complete: %d", jsrc.final_pass, jsrc.decoding_done, jpeg_input_complete(&cinfo));#endif if(!jsrc.decoding_done) {#ifdef JPEG_DEBUG qDebug("starting another one, input_scan_number is %d/%d", cinfo.input_scan_number, cinfo.output_scan_number);#endif jsrc.decoder_timestamp.restart(); state = decompressStarted; // don't return until necessary! goto again; } } if(state == doOutputScan && jsrc.decoding_done) {#ifdef JPEG_DEBUG qDebug("input is complete, cleaning up, returning..");#endif if ( consumer && !jsrc.change_rect.isEmpty() ) consumer->changed( jsrc.change_rect ); if(consumer) consumer->end(); jsrc.ateof = true; (void) jpeg_finish_decompress(&cinfo); (void) jpeg_destroy_decompress(&cinfo); state = readDone; return 0; } }#ifdef BUFFER_DEBUG qDebug("valid_buffer_len is now %d", jsrc.valid_buffer_len); qDebug("bytes_in_buffer is now %d", jsrc.bytes_in_buffer); qDebug("consumed %d bytes", consumed);#endif if(jsrc.bytes_in_buffer && jsrc.buffer != jsrc.next_input_byte) memmove(jsrc.buffer, jsrc.next_input_byte, jsrc.bytes_in_buffer); jsrc.valid_buffer_len = jsrc.bytes_in_buffer; return consumed;}// -----------------------------------------------------------------------------// This is the factory that teaches Qt about progressive JPEG'sQImageFormat* khtml::KJPEGFormatType::decoderFor(const unsigned char* buffer, int length){ if(length < 3) return 0; if(buffer[0] == 0377 && buffer[1] == 0330 && buffer[2] == 0377) return new KJPEGFormat; return 0;}const char* khtml::KJPEGFormatType::formatName() const{ return "JPEG";}#else#ifdef __GNUC__#warning You don't seem to have libJPEG. jpeg support in khtml won't work#endif#endif // HAVE_LIBJPEG// -----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -