本文介绍: 本来提取像素设置像素应该sse写的,但是折磨了chatgpt好几天 也没有写出来。所以这里仅用sse优化数据以及目标数据坐标计算这里实现打印文件缩放算法。即使是这样优化效果也很好。

前情提要
这里实现打印文件缩放算法 缩放打印文件(prt,prn)
核心功能如下

void CZoomPrtFile::zoomPrtFile(BYTE* pTargetData)
{
	float xRatio = static_cast<float>(m_perWidth - 1) / m_zoomWidth;
	float yRatio = static_cast<float>(m_perHeight - 1) / m_zoomHeight;

	int srcX=0, srcY=0;
	int nTargetLineSize = (m_zoomWidth * m_header.nImageColorDeep + 7) / 8;

	BYTE* pSourceLineData = new BYTE[m_header.nBytePerLine];
	for (size_t row = 0; row < m_zoomHeight; row++) 
	{
		srcY = static_cast<int>(yRatio * row);
		for (int ColorNum = 0; ColorNum < m_header.nImageColorNum; ColorNum++)
		{

			memset(pSourceLineData, 0, m_header.nBytePerLine);
			ReadLine(pSourceLineData, srcY * m_header.nImageColorNum + ColorNum, 0, m_header.nBytePerLine);

			for (size_t column = 0; column < m_zoomWidth; column++) 
			{
				srcX = static_cast<int>(xRatio * column);
				// 获取图像bit像素
				unsigned char srcValue = getPixel(pSourceLineData, srcX, m_header.nImageColorDeep);
				int y = (row * m_header.nImageColorNum + ColorNum) * nTargetLineSize + sizeof(m_header);
				// 设置目标图像的2bit像素
				setPixel(pTargetData+y,column, srcValue, m_header.nImageColorDeep);
			}
		}
	}

	delete[] pSourceLineData;
}

unsigned char CZoomPrtFile::getPixel(unsigned char* data, int x, int nImageColorDeep)
{
	//unsigned char存储 8/int nImageColorDeep 个 int nImageColorDeep bit像素 ,其中 nImageColorDeep :1,2,4,8 RIP image output bit per color
	int byteIndex = x * nImageColorDeep / 8; // 字节索引
	int bitIndex = (x * nImageColorDeep) % 8; // 位索引

	// 创建掩码
	unsigned char mask = (1 << nImageColorDeep) - 1;
	//std::lock_guard<std::mutex> locker(fileMutex);
	// 位运算提取像素

	unsigned char pixel;
	{ 
		std::lock_guard<std::mutex> locker(fileMutex); 
		pixel = data[byteIndex];
	}
	pixel = (pixel >> bitIndex) &amp; mask;

	return pixel;
}

unsigned char CZoomPrtFile::getPixel(unsigned char data, int x, int nImageColorDeep)
{
	//unsigned char存储 8/int nImageColorDeep 个 int nImageColorDeep bit像素 ,其中 nImageColorDeep :1,2,4,8 RIP image output bit per color
	int byteIndex = x * nImageColorDeep / 8; // 字节索引
	int bitIndex = (x * nImageColorDeep) % 8; // 位索引

	// 创建掩码
	unsigned char mask = (1 << nImageColorDeep) - 1;
	//std::lock_guard<std::mutex> locker(fileMutex);
	// 位运算提取像素
	unsigned char pixel = (data >> bitIndex) &amp; mask;

	return pixel;
}

使用sse 128

void CZoomPrtFile::zoomPrtFileSSE128(BYTE* pTargetData)
{
	const float xRatio = static_cast<float>(m_perWidth - 1) / m_zoomWidth;
	const float yRatio = static_cast<float>(m_perHeight - 1) / m_zoomHeight;

	__m128 xmmRatio = _mm_set1_ps(xRatio);
	__m128 ymmRatio = _mm_set1_ps(yRatio);
	__m128i colorDeep = _mm_set1_epi32(m_header.nImageColorDeep);

	__m128i bitMask = _mm_set1_epi8(0x07);
	unsigned char mask = (1 << m_header.nImageColorNum) - 1;
	__m128i mmMask = _mm_set1_epi32(mask); 
	
	BYTE* pSourceLineData = new BYTE[m_header.nBytePerLine];
	int nTargetLineSize = (m_zoomWidth * m_header.nImageColorDeep + 7) / 8;

	for (int row = 0; row < m_zoomHeight; row++)
	{
		int srcY = static_cast<int>(yRatio * row);

		for (int ColorNum = 0; ColorNum < m_header.nImageColorNum; ColorNum++)
		{
			memset(pSourceLineData, 0, m_header.nBytePerLine);
			ReadLine(pSourceLineData, srcY * m_header.nImageColorNum + ColorNum, 0, m_header.nBytePerLine);

			for (int column = 0; column < m_zoomWidth; column+=4)
			{
				// 加载128位值。返回值代表寄存器变量中的相同值,地址p不需要16字节对齐
				__m128i xmmColumn = _mm_setr_epi32(column, column + 1, column + 2, column + 3);
				// 列索引转换浮点数
				__m128 xmmColumnF = _mm_cvtepi32_ps(xmmColumn);
				// 乘以缩放比例  转换整数
				__m128i xmmSrcXInt = _mm_cvttps_epi32(_mm_mul_ps(xmmColumnF, xmmRatio));


				//原图
				 xmmSrcXInt = _mm_mullo_epi32(xmmSrcXInt, colorDeep);
				// 方法1:右移三位实现除以8
				__m128i xmmSrcXByteIndex = _mm_srli_epi32(xmmSrcXInt, 3);// 字节索引
				__m128i xmmSrcXBitIndex = _mm_and_si128(xmmSrcXInt, bitMask);// 位索引
				//目标
				__m128i xmmDesX = _mm_mullo_epi32(xmmColumn, colorDeep);//位索引 
				__m128i xmmDesXByteIndex = _mm_srli_epi32(xmmDesX, 3);// 字节索引
				__m128i xmmDesXBitIndex = _mm_and_si128(xmmDesX, bitMask);// 位索引

				//源数据
				alignas(16) int srcXByteIndex[4];//
				_mm_store_si128((__m128i*)srcXByteIndex, xmmSrcXByteIndex);
				alignas(16) int srcXBitIndex[4];//
				_mm_store_si128((__m128i*)srcXBitIndex, xmmSrcXBitIndex);

				unsigned char pixel[4]{ 
					(pSourceLineData[srcXByteIndex[0]] >> srcXBitIndex[0])&amp; mask,
					(pSourceLineData[srcXByteIndex[1]] >> srcXBitIndex[1])&amp; mask,
					(pSourceLineData[srcXByteIndex[2]] >> srcXBitIndex[2])&amp; mask,
					(pSourceLineData[srcXByteIndex[3]] >> srcXBitIndex[3])&amp; mask
				};
				//目标数据
				int y = (row * m_header.nImageColorNum + ColorNum) * nTargetLineSize + sizeof(m_header);
				BYTE* desDataPointer = pTargetData + y;

				alignas(16) int DesXByteIndex[4];
				_mm_store_si128((__m128i*)DesXByteIndex, xmmDesXByteIndex);
				alignas(16) int DesXBitIndex[4];//
				_mm_store_si128((__m128i*)DesXBitIndex, xmmDesXBitIndex);

				desDataPointer[DesXByteIndex[0]] = (desDataPointer[DesXByteIndex[0]] &amp; ~(mask << DesXBitIndex[0])) |
					((pixel[0] /*&amp; mask*/ ) << DesXBitIndex[0]);
				desDataPointer[DesXByteIndex[1]] = (desDataPointer[DesXByteIndex[1]] &amp; ~(mask << DesXBitIndex[1])) |
					((pixel[1] /*&amp; mask*/) << DesXBitIndex[1]);
				desDataPointer[DesXByteIndex[2]] = (desDataPointer[DesXByteIndex[2]] &amp; ~(mask << DesXBitIndex[2])) |
					((pixel[2] /*&amp; mask*/) << DesXBitIndex[2]);
				desDataPointer[DesXByteIndex[3]] = (desDataPointer[DesXByteIndex[3]] & ~(mask << DesXBitIndex[3])) |
					((pixel[3] /*& mask*/) << DesXBitIndex[3]);
			}
		}
	}

}

本来提取像素和设置像素都应该sse写的,但是折磨了chatgpt好几天 也没有写出来。
所以这里仅用sse优化数据以及目标数据坐标的计算
即使是这样优化效果也很好
在这里插入图片描述

原文地址:https://blog.csdn.net/fuyouzhiyi/article/details/134445033

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_45590.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注