亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? jpeg.cpp

?? 一個(gè)開源的嵌入式flash播放器的源代碼
?? CPP
字號(hào):
// jpeg.cpp	-- Thatcher Ulrich <tu@tulrich.com> 2002

// This source code has been donated to the Public Domain.  Do
// whatever you want with it.

// Wrapper for jpeg file operations.  The actual work is done by the
// IJG jpeg lib.


#include "base/utility.h"
#include "base/jpeg.h"
#include "base/tu_file.h"
#include <stdio.h>

#if TU_CONFIG_LINK_TO_JPEGLIB

extern "C" {
#include <jpeglib.h>
}


namespace jpeg
{
	// jpeglib data source constructors, for using tu_file* instead
	// of stdio for jpeg IO.
	void	setup_rw_source(jpeg_decompress_struct* cinfo, tu_file* instream);
	void	setup_rw_dest(jpeg_compress_struct* cinfo, tu_file* outstream);


	// Helper object for reading jpeg image data.  Basically a thin
	static const int	IO_BUF_SIZE = 4096;

	// A jpeglib source manager that reads from a tu_file.  Paraphrased
	// from IJG jpeglib jdatasrc.c.
	struct rw_source
	{
		struct jpeg_source_mgr	m_pub;		/* public fields */

		tu_file*	m_in_stream;		/* source stream */
		bool	m_start_of_file;		/* have we gotten any data yet? */
		JOCTET	m_buffer[IO_BUF_SIZE];	/* start of buffer */

		rw_source(tu_file* in)
			:
			m_in_stream(in),
			m_start_of_file(true)
		// Constructor.  The caller is responsible for closing the input stream
		// after it's done using us.
		{
			// fill in function pointers...
			m_pub.init_source = init_source;
			m_pub.fill_input_buffer = fill_input_buffer;
			m_pub.skip_input_data = skip_input_data;
			m_pub.resync_to_restart = jpeg_resync_to_restart;	// use default method
			m_pub.term_source = term_source;
			m_pub.bytes_in_buffer = 0;
			m_pub.next_input_byte = NULL;
		}

		static void init_source(j_decompress_ptr cinfo)
		{
			rw_source*	src = (rw_source*) cinfo->src;
			src->m_start_of_file = true;
		}

		static boolean	fill_input_buffer(j_decompress_ptr cinfo)
		// Read data into our input buffer.  Client calls this
		// when it needs more data from the file.
		{
			rw_source*	src = (rw_source*) cinfo->src;

			size_t	bytes_read = src->m_in_stream->read_bytes(src->m_buffer, IO_BUF_SIZE);

			if (bytes_read <= 0) {
				// Is the file completely empty?
				if (src->m_start_of_file) {
					// Treat this as a fatal error.
					throw "empty jpeg source stream.";
				}
				// warn("jpeg end-of-stream");

				// Insert a fake EOI marker.
				src->m_buffer[0] = (JOCTET) 0xFF;
				src->m_buffer[1] = (JOCTET) JPEG_EOI;
				bytes_read = 2;
			}

			// Hack to work around SWF bug: sometimes data
			// starts with FFD9FFD8, when it should be
			// FFD8FFD9!
			if (src->m_start_of_file && bytes_read >= 4)
			{
				if (src->m_buffer[0] == 0xFF
				    && src->m_buffer[1] == 0xD9 
				    && src->m_buffer[2] == 0xFF
				    && src->m_buffer[3] == 0xD8)
				{
					src->m_buffer[1] = 0xD8;
					src->m_buffer[3] = 0xD9;
				}
			}

			// Expose buffer state to clients.
			src->m_pub.next_input_byte = src->m_buffer;
			src->m_pub.bytes_in_buffer = bytes_read;
			src->m_start_of_file = false;

			return TRUE;
		}

		static void	skip_input_data(j_decompress_ptr cinfo, long num_bytes)
		// Called by client when it wants to advance past some
		// uninteresting data.
		{
			rw_source*	src = (rw_source*) cinfo->src;

			// According to jpeg docs, large skips are
			// infrequent.  So let's just do it the simple
			// way.
			if (num_bytes > 0) {
				while (num_bytes > (long) src->m_pub.bytes_in_buffer) {
					num_bytes -= (long) src->m_pub.bytes_in_buffer;
					fill_input_buffer(cinfo);
				}
				// Handle remainder.
				src->m_pub.next_input_byte += (size_t) num_bytes;
				src->m_pub.bytes_in_buffer -= (size_t) num_bytes;
			}
		}

		static void term_source(j_decompress_ptr cinfo)
		// Terminate the source.  Make sure we get deleted.
		{
			/*rw_source*	src = (rw_source*) cinfo->src;
			assert(src);

			// @@ it's kind of bogus to be deleting here
			// -- term_source happens at the end of
			// reading an image, but we're probably going
			// to want to init a source and use it to read
			// many images, without reallocating our
			// buffer.
			delete src;
			cinfo->src = NULL;*/
		}


		void	discard_partial_buffer()
		{
			// Discard existing bytes in our buffer.
			m_pub.bytes_in_buffer = 0;
			m_pub.next_input_byte = NULL;
		}
	};

	
	void	setup_rw_source(jpeg_decompress_struct* cinfo, tu_file* instream)
	// Set up the given decompress object to read from the given
	// stream.
	{
		// assert(cinfo->src == NULL);
		cinfo->src = (jpeg_source_mgr*) (new rw_source(instream));
	}


	// A jpeglib destination manager that writes to a tu_file.
	// Paraphrased from IJG jpeglib jdatadst.c.
	struct rw_dest
	{
		struct jpeg_destination_mgr	m_pub;	/* public fields */

		tu_file*	m_out_stream;		/* source stream */
		JOCTET	m_buffer[IO_BUF_SIZE];	/* start of buffer */

		rw_dest(tu_file* out)
			:
			m_out_stream(out)
		// Constructor.  The caller is responsible for closing
		// the output stream after it's done using us.
		{
			// fill in function pointers...
			m_pub.init_destination = init_destination;
			m_pub.empty_output_buffer = empty_output_buffer;
			m_pub.term_destination = term_destination;

			m_pub.next_output_byte = m_buffer;
			m_pub.free_in_buffer = IO_BUF_SIZE;
		}

		static void init_destination(j_compress_ptr cinfo)
		{
			rw_dest*	dest = (rw_dest*) cinfo->dest;
			assert(dest);

			dest->m_pub.next_output_byte = dest->m_buffer;
			dest->m_pub.free_in_buffer = IO_BUF_SIZE;
		}

		static boolean	empty_output_buffer(j_compress_ptr cinfo)
		// Write the output buffer into the stream.
		{
			rw_dest*	dest = (rw_dest*) cinfo->dest;
			assert(dest);

			if (dest->m_out_stream->write_bytes(dest->m_buffer, IO_BUF_SIZE) != IO_BUF_SIZE)
			{
				// Error.
				// @@ bah, exceptions suck.  TODO consider alternatives.
				throw "jpeg::rw_dest couldn't write data.";
			}

			dest->m_pub.next_output_byte = dest->m_buffer;
			dest->m_pub.free_in_buffer = IO_BUF_SIZE;

			return TRUE;
		}

		static void term_destination(j_compress_ptr cinfo)
		// Terminate the destination.  Flush any leftover
		// data, and make sure we get deleted.
		{
			rw_dest*	dest = (rw_dest*) cinfo->dest;
			assert(dest);

			// Write any remaining data.
			int	datacount = IO_BUF_SIZE - dest->m_pub.free_in_buffer;
			if (datacount > 0) {
				if (dest->m_out_stream->write_bytes(dest->m_buffer, datacount) != datacount)
				{
					// Error.
					throw "jpeg::rw_dest::term_destination couldn't write data.";
				}
			}

			// Clean ourselves up.
			delete dest;
			cinfo->dest = NULL;
		}
	};


	void	setup_rw_dest(j_compress_ptr cinfo, tu_file* outstream)
	// Set up the given compress object to write to the given
	// output stream.
	{
		cinfo->dest = (jpeg_destination_mgr*) (new rw_dest(outstream));
	}


	//
	// Error handler
	//


	void	jpeg_error_exit(j_common_ptr cinfo)
	// Called when jpeglib has a fatal error.
	{
		assert(0);
		(*cinfo->err->output_message) (cinfo);
		tu_error_exit(1, "internal error in jpeglib");
	}


	static void	setup_jpeg_err(jpeg_error_mgr* jerr)
	// Set up some error handlers for the jpeg lib.
	{
		// Set up defaults.
		jpeg_std_error(jerr);

		jerr->error_exit = jpeg_error_exit;
	}


	//
	// wrappers
	//


	struct input_impl : public input
	// Bascially this is a thin wrapper around jpeg_decompress
	// object.
	{
		// State needed for input.
		struct jpeg_decompress_struct	m_cinfo;
		struct jpeg_error_mgr	m_jerr;

		bool	m_compressor_opened;


		enum SWF_DEFINE_BITS_JPEG2 { SWF_JPEG2 };
		enum SWF_DEFINE_BITS_JPEG2_HEADER_ONLY { SWF_JPEG2_HEADER_ONLY };

		input_impl(tu_file* in)
			:
			m_compressor_opened(false)
		// Constructor.  Read the header data from in, and
		// prepare to read data.
		{
			setup_jpeg_err(&m_jerr);
			m_cinfo.err = &m_jerr;

			// Initialize decompression object.
			jpeg_create_decompress(&m_cinfo);

			setup_rw_source(&m_cinfo, in);

			start_image();
		}


		input_impl(SWF_DEFINE_BITS_JPEG2_HEADER_ONLY e, tu_file* in)
			:
			m_compressor_opened(false)
		// The SWF file format stores JPEG images with the
		// encoding tables separate from the image data.  This
		// constructor reads the encoding table only and keeps
		// them in this object.  You need to call
		// start_image() and finish_image() around any calls
		// to get_width/height/components and read_scanline.
		{
			setup_jpeg_err(&m_jerr);
			m_cinfo.err = &m_jerr;

			// Initialize decompression object.
			jpeg_create_decompress(&m_cinfo);

			setup_rw_source(&m_cinfo, in);

			// Read the encoding tables.
			jpeg_read_header(&m_cinfo, FALSE);

			// Don't start reading any image data!
			// App does that manually using start_image.
		}

		~input_impl()
		// Destructor.  Clean up our jpeg reader state.
		{
			finish_image();

			rw_source* src = (rw_source*) m_cinfo.src;
			delete src;
			m_cinfo.src = NULL;


			jpeg_destroy_decompress(&m_cinfo);
		}


		void	discard_partial_buffer()
		// Discard any data sitting in our input buffer.  Use
		// this before/after reading headers or partial image
		// data, to avoid screwing up future reads.
		{
			rw_source* src = (rw_source*) m_cinfo.src;

			// We only have to discard the input buffer after reading the tables.
			if (src)
			{
				src->discard_partial_buffer();
			}
		}


		void	start_image()
		// This is something you can do with "abbreviated"
		// streams; i.e. if you constructed this inputter
		// using (SWF_JPEG2_HEADER_ONLY) to just load the
		// tables, or if you called finish_image() and want to
		// load another image using the existing tables.
		{
			assert(m_compressor_opened == false);

			// Now, read the image header.
			jpeg_read_header(&m_cinfo, TRUE);
			jpeg_start_decompress(&m_cinfo);
			m_compressor_opened = true;
		}

		void	finish_image()
		{
			if (m_compressor_opened)
			{
				jpeg_finish_decompress(&m_cinfo);
				m_compressor_opened = false;
			}
		}

		int	get_height() const
		// Return the height of the image.  Take the data from our m_cinfo struct.
		{
			assert(m_compressor_opened);
			return m_cinfo.output_height;
		}

		int	get_width() const
		// Return the width of the image.  Take the data from our m_cinfo struct.
		{
			assert(m_compressor_opened);
			return m_cinfo.output_width;
		}

		int	get_components() const
		// Return number of components (i.e. == 3 for RGB
		// data).  The size of the data for a scanline is
		// get_width() * get_components().
		{
			assert(m_compressor_opened);
			return m_cinfo.output_components;
		}


		void	read_scanline(unsigned char* rgb_data)
		// Read a scanline's worth of image data into the
		// given buffer.  The amount of data read is
		// get_width() * get_components().
		{
			assert(m_compressor_opened);
			assert(m_cinfo.output_scanline < m_cinfo.output_height);
			int	lines_read = jpeg_read_scanlines(&m_cinfo, &rgb_data, 1);
			assert(lines_read == 1);
			lines_read = lines_read;	// avoid warning in NDEBUG
		}
	};


	/*static*/ input*	input::create(tu_file* in)
	// Create and return a jpeg-input object that will read from the
	// given input stream.
	{
		return new input_impl(in);
	}

	/*static*/ input*	input::create_swf_jpeg2_header_only(tu_file* in)
	// Read SWF JPEG2-style header.  App needs to call
	// start_image() before loading any image data.  Multiple
	// images can be loaded by bracketing within
	// start_image()/finish_image() pairs.
	{
		return new input_impl(input_impl::SWF_JPEG2_HEADER_ONLY, in);
	}


	// Default destructor.
	input::~input() {}


	struct output_impl : public output
	// Basically this is a thin wrapper around jpeg_compress
	// object.
	{
		// State needed for output.
		struct jpeg_compress_struct	m_cinfo;
		struct jpeg_error_mgr m_jerr;

		output_impl(tu_file* out, int width, int height, int quality)
		// Constructor.  Read the header data from in, and
		// prepare to read data.
		{
			m_cinfo.err = jpeg_std_error(&m_jerr);

			// Initialize decompression object.
			jpeg_create_compress(&m_cinfo);

			setup_rw_dest(&m_cinfo, out);
			m_cinfo.image_width = width;
			m_cinfo.image_height = height;
			m_cinfo.input_components = 3;
			m_cinfo.in_color_space = JCS_RGB;
			jpeg_set_defaults(&m_cinfo);
			jpeg_set_quality(&m_cinfo, quality, TRUE);

			jpeg_start_compress(&m_cinfo, TRUE);
		}


		~output_impl()
		// Destructor.  Clean up our jpeg reader state.
		{
			jpeg_finish_compress(&m_cinfo);
/*
			rw_dest* src = (rw_source*) m_cinfo.dest;
			delete dest;
			m_cinfo.dest = NULL;
*/
			jpeg_destroy_compress(&m_cinfo);
		}


		void	write_scanline(unsigned char* rgb_data)
		// Write out a single scanline.
		{
			jpeg_write_scanlines(&m_cinfo, &rgb_data, 1);
		}
	};


	/*static*/ output*	output::create(tu_file* in, int width, int height, int quality)
	// Create and return a jpeg-input object that will read from the
	// given input stream.
	{
		return new output_impl(in, width, height, quality);
	}


	// Default constructor.
	output::~output() {}
}


#else // not TU_CONFIG_LINK_TO_JPEGLIB


namespace jpeg
{
	/*static*/ input* input::create(tu_file* in)
	{
		return NULL;
	}

	/*static*/ input* input::create_swf_jpeg2_header_only(tu_file* in)
	{
		return NULL;
	}

	/*static*/ output* output::create(tu_file* out, int width, int height, int quality)
	{
		return NULL;
	}

}


#endif // not TU_CONFIG_LINK_TO_JPEGLIB


// Local Variables:
// mode: C++
// c-basic-offset: 8 
// tab-width: 8
// indent-tabs-mode: t
// End:

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美成人伊人久久综合网| 91精品婷婷国产综合久久竹菊| 国产亚洲精品福利| 成人免费观看男女羞羞视频| 国产精品久久午夜| 色94色欧美sute亚洲线路二| 亚洲va在线va天堂| 日韩欧美一区二区在线视频| 激情欧美日韩一区二区| 日本一区二区三区电影| 91偷拍与自偷拍精品| 亚洲与欧洲av电影| 日韩一区二区免费在线观看| 国产一区二区导航在线播放| 中文字幕亚洲一区二区va在线| 色婷婷亚洲综合| 日欧美一区二区| 国产欧美日韩在线| 欧美吻胸吃奶大尺度电影 | 成人午夜看片网址| 国产人伦精品一区二区| 91猫先生在线| 日韩电影在线免费| 久久久电影一区二区三区| 99re8在线精品视频免费播放| 亚洲福利一区二区三区| 久久午夜羞羞影院免费观看| 99天天综合性| 全部av―极品视觉盛宴亚洲| 中文一区二区完整视频在线观看| 欧美性感一区二区三区| 国产精品影视天天线| 一区二区三区蜜桃网| 欧美精品第1页| 久久精品国产99国产精品| 中文字幕在线观看不卡| 日韩欧美国产1| 国产精品一区二区黑丝| 亚洲777理论| 欧美国产成人精品| 日韩视频一区在线观看| av不卡在线播放| 国产精品一级片| 首页综合国产亚洲丝袜| 亚洲欧美另类久久久精品2019| 欧美成人性战久久| 欧美日韩国产123区| av在线不卡观看免费观看| 蓝色福利精品导航| 五月天激情综合| 夜夜爽夜夜爽精品视频| 国产精品二三区| 久久精品欧美一区二区三区麻豆| 欧美午夜精品久久久久久孕妇| 99久久综合精品| 国产精品69毛片高清亚洲| 日韩av一二三| 亚洲国产中文字幕| 伊人色综合久久天天人手人婷| 欧美激情综合五月色丁香| 亚洲精品在线一区二区| 欧美一区二区网站| 欧美日韩国产影片| 在线观看视频欧美| 色综合天天综合色综合av| 99精品视频一区| 成人网在线免费视频| 国产成人在线视频网址| 国产一区二区日韩精品| 久久 天天综合| 国产在线看一区| 久久99久久久久久久久久久| 蜜桃久久久久久久| 秋霞午夜鲁丝一区二区老狼| 免费成人av资源网| 久久精品国产精品青草| 久久99精品国产麻豆不卡| 久久精品国产999大香线蕉| 激情av综合网| 国产成人精品午夜视频免费| 成人开心网精品视频| 成人精品免费看| 99久久er热在这里只有精品66| 91在线无精精品入口| 色素色在线综合| 欧美日韩在线不卡| 日韩欧美国产麻豆| 精品国产一区二区三区久久影院 | 国产精品久久久久久久久久久免费看| 久久久国际精品| 国产精品毛片久久久久久| 国产精品成人免费在线| 一区二区日韩av| 日精品一区二区| 国产精品18久久久久| 国产成人精品综合在线观看 | 国产福利电影一区二区三区| 成人性色生活片免费看爆迷你毛片| 成人av免费在线播放| 欧美日韩在线精品一区二区三区激情 | 亚洲图片欧美激情| 亚洲成人高清在线| 国产一区二区三区四| av中文字幕不卡| 4438x成人网最大色成网站| 久久久无码精品亚洲日韩按摩| 亚洲丝袜另类动漫二区| 日韩高清在线不卡| 国产凹凸在线观看一区二区| 色88888久久久久久影院野外| 911精品产国品一二三产区| 久久久亚洲高清| 亚洲国产精品人人做人人爽| 国产一区二区三区在线看麻豆| 色婷婷狠狠综合| 26uuu另类欧美| 亚洲综合网站在线观看| 国产一区欧美一区| 欧美伊人久久久久久久久影院| 日韩欧美精品三级| 亚洲品质自拍视频| 久久精品国产**网站演员| 色综合网色综合| www国产精品av| 五月天一区二区| www.亚洲精品| 欧美精品一区男女天堂| 亚洲在线视频一区| 成人av电影在线| 精品欧美黑人一区二区三区| 一级日本不卡的影视| 国产成人精品三级| 欧美大度的电影原声| 亚洲一本大道在线| 91在线精品一区二区| 精品精品国产高清一毛片一天堂| 夜夜揉揉日日人人青青一国产精品| 国产精品99久久久| 日韩亚洲欧美高清| 午夜一区二区三区视频| 91在线porny国产在线看| 久久免费视频色| 久久精品理论片| 欧美电影在线免费观看| 亚洲精品菠萝久久久久久久| 国产v综合v亚洲欧| 国产午夜精品一区二区三区四区 | 亚洲综合色区另类av| 99久久久久久99| 国产精品天天看| 国产高清视频一区| 久久久久久久久久看片| 老司机精品视频线观看86| 欧美人xxxx| 日韩精品国产欧美| 欧美精品一二三| 天堂久久一区二区三区| 欧美婷婷六月丁香综合色| 一区二区成人在线| 欧美图片一区二区三区| 亚洲二区视频在线| 欧美日韩精品二区第二页| 亚洲国产综合色| 欧美日韩精品欧美日韩精品一| 夜夜精品视频一区二区| 欧美中文字幕一区二区三区亚洲| 一区二区在线电影| 欧美亚洲图片小说| 亚洲国产精品久久一线不卡| 在线播放亚洲一区| 日韩国产在线观看一区| 欧美一级欧美三级在线观看| 青青草97国产精品免费观看| 日韩免费电影网站| 久久国产精品区| 国产免费观看久久| 91影院在线免费观看| 亚洲一二三四区不卡| 欧美男生操女生| 久久精品国产久精国产爱| 国产亚洲欧洲一区高清在线观看| 国产乱码一区二区三区| 国产精品美女视频| 欧洲精品一区二区| 青娱乐精品视频| 久久奇米777| 色偷偷一区二区三区| 亚洲成av人片一区二区三区| 欧美一区二区三区视频免费| 国内精品嫩模私拍在线| 中文字幕永久在线不卡| 在线免费亚洲电影| 男人的天堂久久精品| 国产欧美日韩亚州综合| 在线精品视频小说1| 麻豆精品一区二区av白丝在线| 国产欧美日韩在线视频| 欧美日韩一区二区三区四区五区| 亚洲午夜在线观看视频在线| 国产一区二区网址|