存档

‘Computer’ 分类的存档

CxImage库Resample函数插值优化

2011年9月14日 没有评论

最近用了下图像操作库cximage。这库不错,免费开源。修改下bcb,vc都能用。

唯一的主要毛病可能就算是优化不给力了。

使用中,对其resample函数的插值算法尤其头痛,随便一个pdg图像,200%缩放,花费10-20s是常事。因此不得不硬着头皮对其进行优化。

优化中能想起来的使用过 定点替换浮点,循环展开,区域缓存,查表等等。

优化后效果还不错。
bicubic 24bit图像能实现2178×2976 2倍放大耗时 1.8s左右
bicubic 1bit 图像能实现2178×2976 2倍放大耗时 2.6s左右

bilinear 24bit图像能实现2178×2976 2倍放大耗时 0.78s左右
bilinear 1bit 图像能实现2178×2976 2倍放大耗时 1.31s左右

以上测试数据基于T6400 CPU,优化基于cximage 7.02.

当然肯定还有优化空间,例如源码进一步优化以及mmx,sse优化等等,不过暂时本人是没啥辙了,能力有限,只能到这个地步。

这里贴出改过之后的ximatran.cpp
PS:KernelBSpline函数也改成了定点版本,所以这个函数需要自己去改下,不在ximatran.cpp里
修改后的ximatran.cpp

分类: Computer 标签: , ,

CxImage bicubic插值算法优化

2011年9月6日 没有评论

CxImage是个好东西,开源,支持图片种类多,操作花样多,如果非要说缺点的话,那估计只有1个,效率低下,尤其某些图形处理算法效率更低,无任何优化。

这里说到的是CxImage的bicubic插值算法的优化。

Bicubic插值,对与目标图形的某个点,需要其源图像对应点周围的16个点参与计算,因此计算量很大,并且还是浮点运算。

就优化而言,有多种途径,浮点转定点,浮点数转整数,sse等。这里说到的优化方法是浮点转定点,浮点数转整数。

基本思想是,用整数近视替代浮点数,精度是1/256,即将任一浮点数向精度1/256的整数倍靠近,之后计算bicubic函数的权重数据,存到表格里。bicubic插值时查表即可。
CxImage的原bicubic插值函数片段是

//		float f_x, f_y, a, b, rr, gg, bb, r1, r2;
//		int32_t   i_x, i_y, xx, yy;
//		RGBQUAD rgb;
//		uint8_t* iDst;
//		for(int32_t y=0; y<newy; y++){
//			info.nProgress = (int32_t)(100*y/newy);
//			if (info.nEscape) break;
//			f_y = (float) y * yScale - 0.5f;
//			i_y = (int32_t) floor(f_y);
//			a   = f_y - (float)floor(f_y);
//			for(int32_t x=0; x<newx; x++){
//				f_x = (float) x * xScale - 0.5f;
//				i_x = (int32_t) floor(f_x);
//				b   = f_x - (float)floor(f_x);
//
//				rr = gg = bb = 0.0f;
//				for(int32_t m=-1; m<3; m++) {
//					r1 = KernelBSpline((float) m - a);
//					yy = i_y+m;
//					if (yy<0) yy=0;
//					if (yy>=head.biHeight) yy = head.biHeight-1;
//					for(int32_t n=-1; n<3; n++) {
//						r2 = r1 * KernelBSpline(b - (float)n);
//						xx = i_x+n;
//						if (xx<0) xx=0;
//						if (xx>=head.biWidth) xx=head.biWidth-1;
//
//						if (head.biClrUsed){
//							rgb = GetPixelColor(xx,yy);
//						} else {
//							iDst  = info.pImage + yy*info.dwEffWidth + xx*3;
//							rgb.rgbBlue = *iDst++;
//							rgb.rgbGreen= *iDst++;
//							rgb.rgbRed  = *iDst;
//						}
//
//						rr += rgb.rgbRed * r2;
//						gg += rgb.rgbGreen * r2;
//						bb += rgb.rgbBlue * r2;
//					}
//				}
//
//				if (head.biClrUsed)
//					newImage.SetPixelColor(x,y,RGB(rr,gg,bb));
//				else {
//					iDst = newImage.info.pImage + y*newImage.info.dwEffWidth + x*3;
//					*iDst++ = (uint8_t)bb;
//					*iDst++ = (uint8_t)gg;
//					*iDst   = (uint8_t)rr;
//				}
//
//			}
//		}
//		break;

以下是经过初步优化的代码,其中s_BicubicTblX,s_BicubicTblY是两个预先计算好的权重表

		//float f_x, f_y, a, b, rr, gg, bb, r1, r2;
		int32_t   i_x, i_y, xx, yy, a, b, r_x, r_y;
		int32_t r1,r2;
		int32_t rr,gg,bb;
		uint8_t r_r,g_g,b_b;
		RGBQUAD rgb;
		uint8_t* iDst;
		uint8_t* iSrc;
 
		r_x = (int32_t)((float)(head.biWidth << 8)/((float)newx)+0.5);
		r_y = (int32_t)((float)(head.biHeight << 8)/((float)newy)+0.5);
 
 
		for(int32_t y=0; y<newy; y++){
			info.nProgress = (int32_t)(100*y/newy);
			if (info.nEscape) break;
 
 
			i_y = (y*r_y) >> 8;
			a   = (uint8_t)(y*r_y);
			for(int32_t x=0; x<newx; x++){
				i_x = (x*r_x) >> 8;
				b   = (uint8_t)(x*r_x);
 
				rr = gg = bb = 0;
				for(int32_t m=0; m<4; m++) {
 
					r1 = s_BicubicTblY[m][a];
					yy = i_y+m;
					if (yy<0) yy=0;
					if (yy>=head.biHeight) yy = head.biHeight-1;
 
					for(int32_t n=0; n<4; n++) {
						r2 = s_BicubicTblX[n][b];
						xx = i_x+n;
						if (xx<0) xx=0;
						if (xx>=head.biWidth) xx=head.biWidth-1;
 
						if (head.biClrUsed){
							rgb = GetPixelColor(xx,yy);
						} else {
							iSrc  = info.pImage + yy*info.dwEffWidth + xx*3;
							//memcpy(&rgb,iSrc,3);
							rgb.rgbBlue = *iSrc++;
							rgb.rgbGreen= *iSrc++;
							rgb.rgbRed  = *iSrc;
						}
 
						rr += rgb.rgbRed * r1 * r2;
						gg += rgb.rgbGreen * r1 * r2;
						bb += rgb.rgbBlue * r1 * r2;
					}
				}
				bb = ((bb<=0)-1) & bb;
				gg = ((gg<=0)-1) & gg;
				rr = ((rr<=0)-1) & rr;
 
 
				if (head.biClrUsed)
					newImage.SetPixelColor(x,y,RGB(rr,gg,bb));
				else {
					iDst = newImage.info.pImage + y*newImage.info.dwEffWidth + x*3;
					b_b = ((bb & 0xFFFF0000) >= 0xFF0000) ? (0xFF) : ((uint8_t)(bb>>16));
					g_g = ((gg & 0xFFFF0000) >= 0xFF0000) ? (0xFF) : ((uint8_t)(gg>>16));
					r_r = ((rr & 0xFFFF0000) >= 0xFF0000) ? (0xFF) : ((uint8_t)(rr>>16));
					*iDst++ = (uint8_t)b_b;
					*iDst++ = (uint8_t)g_g;
					*iDst   = (uint8_t)r_r;
				}
 
			}
		}
		break;

优化后,速度提升大约1倍左右,对SSE不熟,不知是否还有利用SSE优化的空间

分类: Computer 标签: ,

EndNoteRenamer2 sourcecode

2011年5月25日 没有评论

最开始写这个插件主要目的是为了满足自己在使用EndNote过程中的不便,目前为止已经满足了我的需求,也就没啥可升级的了。正好也没啥空闲时间继续折腾这个了。这里放出源代码。大家随意参考使用,如分发源码希望注明原始作者。

下载链接: 点我下载

EndNoteRenamer2 plugin for endnote windows version
—————————————————————————-
E-Mail: coolspace#qq.com

http://blog.kingse.og

—————————————————————————-

————————————————————————
IMPORTANT NOTE:
This software is provided ‘as-is’, without any expressed or implied warranty.
Permission is granted to anyone to use this source for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this source must not be misrepresented, you must not
claim that you wrote the original source.
2. Altered source versions must be plainly marked as such, and must not
be misrepresented as being the original source.
3. This notice may not be removed or altered from any source
distribution.

————————————————————————
THANKS:
thanks to authors of WTL, tinyxml,deelx and so on.

分类: Computer, Study 标签: ,

EndNoteRenamer ver 2.0 released

2011年2月9日 没有评论

好久没写过新日志了。。。。惭愧
以新版本的EndNoteRenamer来代替日志吧。

下载链接

ChangeLog:

相比1.5,做了以下调整
1、核心更新,重命名规则由之前的单一设置,统一为选取EndNote的output style方式,利用此方式,可以很方便的扩充想要支持的记录类型,例如book,journal article等。

2、校验output style 输出字串的长度,满足windows平台上 文件名全名 <= 256的限制,如果输出长度超过此值,则该记录不会更改。(解决之前版本在fat32分区上容易出现的文件消失现象)

3、Other small improvements.

注:
1、由于从此版本开始,命名规则改由output style提供,因此需要注意output style的选取,output style选取不当,会照成无法重命名,最好自己新建style。附件中我提供了一个自己的实例,大家可以在这基础进行更改,得到合适自己的style。另外由于EndNote的bug,style必须放在endnote安装目录的styles文件夹中。

2、如使用过上一版本,那么需要删除plugins目录下的Endnoterenamer.dll和EndNoteRenamer.ini。以防和新版本冲突。

3、推荐初次使用前,备份数据库(直接copy记录和相应的文件夹),然后设置规则后,用插件进行重命名尝试,如无其他问题,再进行使用,毕竟数据才是第一位的。

 
4、关于bug反馈,最好说明系统版本,endnote版本,数据库所在盘文件系统格式,同时如有 出错数据库的备份(就是出错数据库的原始记录,而非出错以后的记录)更好。

压缩包中自带的style的具体命名规则如下图

分类: Computer, Study 标签: ,

EndNote插件EndNoteRenamer发布~~[原创]

2010年11月21日 没有评论

EndNote是个好东西。尤其是FindFullText

但是FindFullText默认下回来的文件的命名规则实在是难看,基本上脱离了endnote,没有任何文献管理的便利可言。

同时,你是否相对现有记录的全文进行批量重命名?

本插件EndNoteRenamer满足以上的需求。

插件版本:v1.5
插件作者:coolspace
插件功能:根据规则批量重命名全文,包括pdf文件名及文件路径
插件授权:Free
下载地址:http://files.kingse.org/EndNoteRenamer.rar
免责申明:插件未做大规模测试,注意备份
致谢:插件基于WTL,TinyXML,RDK构建,UPX压缩,对WTL,TinyXML,RDK,UPX的贡献者致以崇高的敬意
未来规划:。。。待定,看兴趣
使用说明:
1、将插件dll放入endnote的plugins文件夹,启动endnote,会看到tools菜单下会多出两个endnoterenamer的菜单项。进入config,设定命名规则,命名规则是全文pdf的文件名部分(不包括扩展名),文件夹名自动设置为文件名+一串数字

2、选中需要重命名的记录,点击rename菜单项进行重命名。

如有bug,欢迎反馈。

分类: Computer, Study 标签: ,

在dll中嵌入WTL窗体

2010年11月18日 没有评论

WTL全称Windows Template Library,是基于模板的window界面库,架构在ATL只上,由于其基于模板,没有MFC那么多继承以及相互引用,因此静态链接出来的exe十分短小精悍。WTL自带app wizard,但是这个app wizard仅支持生成exe型的应用程序,而不支持生成嵌入WTL窗体的dll。

经过摸索,并查阅wtl新闻组上的相关资料,最终有了下面的在dll中嵌入wtl窗口的例子。例子很简单只导出了一个函数ShowDlg,调用这个函数会生成一个模态的对话框。

源码如下:

DLL中嵌入WTL窗体简单示例

分类: Computer 标签: , ,

[原创]delphi dcu逆向编译漫谈

2010年9月4日 没有评论

提起这个话题,主要是从前不久自己的一次实际dcu逆向编译经历而来的。

题记:f-in-box控件是个delphi下进行flash播放的优秀控件,其能从内存中载入ocx,从内存中载入flash等优秀特性。但是很可惜,网上只能找到3.1.2版本的full source版本。之后版本一直到最新版3.5.3之间都只有破解版存在。full source版本苦等不来,后来看f-in-box控件源码结构也比较简单,只有一个pas文件。正好我们都知道dcu中含有不少pas中的原始结构和类型信息,因此尝试在3.1.2源码的基础上对3.5.3进行逆向编译。至于为何在3.1.2的基础上,不在3.1.2的基础上行不行?这个我可以说的是,即使没有3.1.2,也是可行的,3.1.2的存在只是为中间逆向省去了很多麻烦而已。

下面,就对我在逆向f-in-box dcu的过程中的经验做下总结。 阅读全文…

分类: Computer 标签: , ,

内存中载入DLL并执行(C代码,兼容vc,bcb)

2010年8月10日 1 条评论

系统载入dll的整体过程可以分为以下几个步骤:

1、将dll文件内容载入内存,并按照对齐粒度进行对齐并设置对应的各个内存区间的权限属性;

2、如果dll有重定位表,则进行重定位操作;

3、填充dll的导入表;

4、用ATTACH参数调用dll的入口函数进行初始化,之后返回imagebase即可。

因此了解了系统载入dll的整体流程,也就可以自己实现将dll载入内存并执行,这种方法对于加密等有一定意义。

但由于自己载入内存后,系统api GetProcAddress函数失效,因此在自己实现loadlibrary函数的同时必须自己实现此函数。

下面附上参考网上现有代码原理后写的代码。

进过少量测试,暂未发现bug,如发现bug,欢迎提出。

DLLLoader.h文件内容如下

//---------------------------------------------------------------------------
 
#ifndef DLLLoaderH
#define DLLLoaderH
 
#ifdef __cplusplus
extern "C" {
#endif
 
#include <stdio .h>
#include <windows .h>
//---------------------------------------------------------------------------
 
//public functions
 
DWORD LoadDllFromMemory(LPVOID lpBuffer,__int64 BufferSize);
DWORD FreeDllFromMemory(LPVOID lpBaseAddress);
FARPROC GetDllProcAddress(LPVOID imagebase,char * FuncName);
 
// private functions
 
DWORD AlignDllToMemory(LPVOID lpBuffer,PIMAGE_DOS_HEADER &dosHeader,PIMAGE_NT_HEADERS &ntHeader,__int64 BufferSize);   //从内存载入到对齐内存
DWORD GetAlignedSize(DWORD Origin,DWORD Alignment);                                                                    //计算对齐后的位置
DWORD GetImageSize(PIMAGE_NT_HEADERS ntHeader,PIMAGE_SECTION_HEADER sectionHeaders);                                   //计算总imagesize
DWORD Relocation(PIMAGE_NT_HEADERS ntHeader,LPVOID NewBase);                                                           //修正重定位
DWORD FillImportTable(LPVOID imagebase,PIMAGE_NT_HEADERS ntHeader);                                                    //填充IAT
 
 
//entrypoint function type
typedef UINT (CALLBACK * LPENTRYPOINT) (HANDLE hInstance, DWORD Reason, LPVOID Reserved);
 
 
#ifdef __cplusplus
}
#endif
 
#endif
</windows></stdio>

阅读全文…

分类: Computer 标签: ,