添加app界面工程
This commit is contained in:
parent
d464356b28
commit
0ceea227a3
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,146 @@
|
|||
#ifndef __HGIMGVIEW_H__
|
||||
#define __HGIMGVIEW_H__
|
||||
|
||||
#include "base/HGDef.h"
|
||||
#include "base/HGBaseErr.h"
|
||||
#include "base/HGImage.h"
|
||||
#include <QWidget>
|
||||
|
||||
class HGImgView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
HGImgView(QWidget* parent = nullptr);
|
||||
virtual ~HGImgView();
|
||||
|
||||
HGResult setScrollSize(int size);
|
||||
HGResult setMinScrollSliderSize(int size);
|
||||
HGResult setHScrollLeftImage(const QImage *normalImage, const QImage *hotImage, const QImage *pushImage);
|
||||
HGResult setHScrollRightImage(const QImage *normalImage, const QImage *hotImage, const QImage *pushImage);
|
||||
HGResult setVScrollTopImage(const QImage *normalImage, const QImage *hotImage, const QImage *pushImage);
|
||||
HGResult setVScrollBottomImage(const QImage *normalImage, const QImage *hotImage, const QImage *pushImage);
|
||||
HGResult setHScrollImage(const QImage *image, const HGRect *stretch);
|
||||
HGResult setHScrollSliderImage(const QImage *normalImage, const HGRect *normalStretch, const QImage *hotImage, const HGRect *hotStretch,
|
||||
const QImage *pushImage, const HGRect *pushStretch);
|
||||
HGResult setVScrollImage(const QImage *image, const HGRect *stretch);
|
||||
HGResult setVScrollSliderImage(const QImage *normalImage, const HGRect *normalStretch, const QImage *hotImage, const HGRect *hotStretch,
|
||||
const QImage *pushImage, const HGRect *pushStretch);
|
||||
HGResult setNullScrollImage(const QImage *image);
|
||||
|
||||
HGResult enableScroll(bool enable);
|
||||
HGResult addImage(HGImage image);
|
||||
HGResult clearImage();
|
||||
HGResult getImage(HGImage *image);
|
||||
|
||||
HGResult rotateLeft();
|
||||
HGResult rotateRight();
|
||||
HGResult rotate180();
|
||||
|
||||
HGResult zoomIn(const HGPoint *pCenter);
|
||||
HGResult zoomOut(const HGPoint *pCenter);
|
||||
HGResult realSize();
|
||||
HGResult fitWndSize();
|
||||
HGResult fitWndWidth();
|
||||
|
||||
HGResult showColorInfo(bool show);
|
||||
|
||||
signals:
|
||||
void escape();
|
||||
void doubleClicked();
|
||||
void mousePos(int x, int y);
|
||||
void scaleChanged(double scale);
|
||||
void drop(const QObject *source, const QStringList &fileNames);
|
||||
|
||||
private:
|
||||
|
||||
enum MouseStatus
|
||||
{
|
||||
MouseStatus_Null = 0,
|
||||
MouseStatus_HScroll,
|
||||
MouseStatus_HScrollSlider,
|
||||
MouseStatus_HScrollLeft,
|
||||
MouseStatus_HScrollRight,
|
||||
MouseStatus_VScroll,
|
||||
MouseStatus_VScrollSlider,
|
||||
MouseStatus_VScrollTop,
|
||||
MouseStatus_VScrollBottom,
|
||||
MouseStatus_NullScroll
|
||||
};
|
||||
|
||||
protected:
|
||||
virtual void mousePressEvent(QMouseEvent *e);
|
||||
virtual void mouseMoveEvent(QMouseEvent* e);
|
||||
virtual void mouseReleaseEvent(QMouseEvent *e);
|
||||
virtual void enterEvent(QEvent *e);
|
||||
virtual void leaveEvent(QEvent *e);
|
||||
virtual void paintEvent(QPaintEvent* e);
|
||||
virtual void wheelEvent(QWheelEvent* e);
|
||||
virtual void resizeEvent(QResizeEvent* e);
|
||||
virtual void keyPressEvent(QKeyEvent *e);
|
||||
virtual void dragEnterEvent(QDragEnterEvent *e);
|
||||
virtual void dragMoveEvent(QDragMoveEvent *e);
|
||||
virtual void dragLeaveEvent(QDragLeaveEvent *e);
|
||||
virtual void dropEvent(QDropEvent *e);
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent* e);
|
||||
|
||||
private:
|
||||
static void GetMinShowImageRect(const HGRect *pWnd, int nImgWidth, int nImgHeight, bool &bShowImage, HGRectF &rcShowImage);
|
||||
static void ResizeShowImageRect(bool &bShowImage, HGRectF &rcShowImage, float fNewWidth, float fNewHeight, const HGPoint *pCenter);
|
||||
static void recalcShowRect(int wndWidth, int wndHeight, int scrollSize, bool hScroll, bool vScroll, bool showImage, HGRectF &imageRect);
|
||||
static void DrawImage(QPainter &painter, const QRect &destRect, const QImage *image, const QRect &stretchRect);
|
||||
|
||||
QImage* createQImage();
|
||||
void DrawScroll(QPainter &painter);
|
||||
void reset();
|
||||
void updateMoveStatusAndCursor();
|
||||
MouseStatus getMouseStatus(const QPoint &pt);
|
||||
|
||||
QRect getHScrollLeftPos();
|
||||
QRect getHScrollRightPos();
|
||||
QRect getHScrollPos();
|
||||
QRect getHScrollSliderPos();
|
||||
QRect getVScrollTopPos();
|
||||
QRect getVScrollBottomPos();
|
||||
QRect getVScrollPos();
|
||||
QRect getVScrollSliderPos();
|
||||
QRect getNullScrollPos();
|
||||
|
||||
void Show();
|
||||
|
||||
private:
|
||||
int m_scrollSize;
|
||||
int m_minScrollSliderSize;
|
||||
QImage *m_hScrollLeftImage[3];
|
||||
QImage *m_hScrollRightImage[3];
|
||||
QImage *m_vScrollTopImage[3];
|
||||
QImage *m_vScrollBottomImage[3];
|
||||
QImage *m_hScrollImage;
|
||||
QRect m_hScrollImageStretch;
|
||||
QImage *m_hScrollSliderImage[3];
|
||||
QRect m_hScrollSliderImageStretch[3];
|
||||
QImage *m_vScrollImage;
|
||||
QRect m_vScrollImageStretch;
|
||||
QImage *m_vScrollSliderImage[3];
|
||||
QRect m_vScrollSliderImageStretch[3];
|
||||
QImage *m_nullScrollImage;
|
||||
|
||||
bool m_enableScroll;
|
||||
bool m_mouseOn;
|
||||
bool m_hScroll;
|
||||
bool m_vScroll;
|
||||
HGImage m_image;
|
||||
QImage *m_qImage;
|
||||
bool m_showImage;
|
||||
HGRectF m_showRect;
|
||||
MouseStatus m_mouseMoveStatus;
|
||||
MouseStatus m_mousePressStatus;
|
||||
int m_mousePressBeginX;
|
||||
int m_mousePressBeginY;
|
||||
bool m_showColorInfo;
|
||||
int m_operate;
|
||||
int m_beginX;
|
||||
int m_beginY;
|
||||
bool m_draging;
|
||||
};
|
||||
|
||||
#endif /* __HGIMGVIEW_HPP__ */
|
|
@ -0,0 +1,94 @@
|
|||
QT += core gui
|
||||
|
||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any Qt feature that has been marked deprecated (the exact warnings
|
||||
# depend on your compiler). Please consult the documentation of the
|
||||
# deprecated API in order to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
|
||||
# You can also make your code fail to compile if it uses deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
TARGET = ProductionTool
|
||||
|
||||
RC_ICONS = image_rsc/logo/logo.ico
|
||||
|
||||
win32 {
|
||||
DEFINES += _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
contains(QT_ARCH, i386) {
|
||||
LIBS += -L../sdk/lib/x86/Release -lHGBase -lHGImgFmt -lHGImgProc -lsane
|
||||
LIBS += -L../../db/Debug -lHGPdtToolDb
|
||||
CONFIG(release, debug|release) {
|
||||
DESTDIR = ../release/x86/
|
||||
}
|
||||
CONFIG(debug, debug|release) {
|
||||
|
||||
}
|
||||
}
|
||||
contains(QT_ARCH, x86_64){
|
||||
LIBS += -L../sdk/lib/x64/Release -lHGBase -lHGImgFmt -lHGImgProc -lsane
|
||||
LIBS += -L../../db/Debug -lHGPdtToolDb
|
||||
CONFIG(release, debug|release) {
|
||||
DESTDIR = ../release/x64/
|
||||
}
|
||||
CONFIG(debug, debug|release) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
INCLUDEPATH += $$PWD/../utility/
|
||||
INCLUDEPATH += $$PWD/../modules/
|
||||
INCLUDEPATH += $$PWD/../sdk/include/
|
||||
INCLUDEPATH += $$PWD/../../db/HGPdtToolDb/
|
||||
|
||||
SOURCES += \
|
||||
HGImgView.cpp \
|
||||
HGUIGlobal.cpp \
|
||||
analysisjson.cpp \
|
||||
dialog_accountmanage.cpp \
|
||||
dialog_changepwd.cpp \
|
||||
dialog_login.cpp \
|
||||
dialog_rootfuntion.cpp \
|
||||
form_maininterface.cpp \
|
||||
form_texttips.cpp \
|
||||
main.cpp \
|
||||
mainwindow.cpp
|
||||
|
||||
HEADERS += \
|
||||
HGImgView.h \
|
||||
HGUIGlobal.h \
|
||||
analysisjson.h \
|
||||
dialog_accountmanage.h \
|
||||
dialog_changepwd.h \
|
||||
dialog_login.h \
|
||||
dialog_rootfuntion.h \
|
||||
form_maininterface.h \
|
||||
form_texttips.h \
|
||||
mainwindow.h
|
||||
|
||||
FORMS += \
|
||||
dialog_accountmanage.ui \
|
||||
dialog_changepwd.ui \
|
||||
dialog_login.ui \
|
||||
dialog_rootfuntion.ui \
|
||||
form_maininterface.ui \
|
||||
form_texttips.ui \
|
||||
mainwindow.ui
|
||||
|
||||
RESOURCES += \
|
||||
ProductionTool_resource.qrc
|
||||
|
||||
TRANSLATIONS += \
|
||||
ProductionTool_zh_CN.ts \
|
||||
|
||||
DISTFILES += \
|
||||
ProductionTool_zh_CN.qm \ \
|
||||
ProductionTool_zh_CN.ts
|
|
@ -0,0 +1,20 @@
|
|||
#include "HGUIGlobal.h"
|
||||
#include "base/HGDef.h"
|
||||
#include "base/HGInc.h"
|
||||
#include "base/HGUtility.h"
|
||||
|
||||
QString getStdFileName(const QString &fileName)
|
||||
{
|
||||
char result[512] = {0};
|
||||
HGBase_StandardiseFileName(fileName.toStdString().c_str(), result, 512);
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string getStdString(const QString &str)
|
||||
{
|
||||
#ifdef HG_CMP_MSC
|
||||
return str.toLocal8Bit().data();
|
||||
#else
|
||||
return str.toStdString();
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#ifndef __HGUIGLOBAL_H__
|
||||
#define __HGUIGLOBAL_H__
|
||||
|
||||
#include <QString>
|
||||
|
||||
QString getStdFileName(const QString &fileName);
|
||||
|
||||
std::string getStdString(const QString &str);
|
||||
|
||||
#endif /* __HGUIGLOBAL_H__ */
|
|
@ -0,0 +1,11 @@
|
|||
<RCC>
|
||||
<qresource prefix="/image">
|
||||
<file>image_rsc/icon/close.ico</file>
|
||||
<file>image_rsc/icon/minum.ico</file>
|
||||
<file>image_rsc/icon/setting.ico</file>
|
||||
<file>image_rsc/logo/logo.ico</file>
|
||||
</qresource>
|
||||
<qresource prefix="/translation">
|
||||
<file>ProductionTool_zh_CN.qm</file>
|
||||
</qresource>
|
||||
</RCC>
|
Binary file not shown.
|
@ -0,0 +1,405 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE TS>
|
||||
<TS version="2.1" language="zh_CN">
|
||||
<context>
|
||||
<name>Dialog_accountManage</name>
|
||||
<message>
|
||||
<location filename="dialog_accountmanage.ui" line="14"/>
|
||||
<source>Dialog</source>
|
||||
<translation>账户管理</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_accountmanage.ui" line="22"/>
|
||||
<source>Account List:</source>
|
||||
<translation>账户列表:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_accountmanage.ui" line="62"/>
|
||||
<source>NEW</source>
|
||||
<translation>新建账户</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_accountmanage.ui" line="69"/>
|
||||
<source>Destroy</source>
|
||||
<translation>销毁账户</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_accountmanage.ui" line="76"/>
|
||||
<source>Set Password</source>
|
||||
<translation>重置密码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_accountmanage.cpp" line="47"/>
|
||||
<location filename="dialog_accountmanage.cpp" line="71"/>
|
||||
<location filename="dialog_accountmanage.cpp" line="92"/>
|
||||
<location filename="dialog_accountmanage.cpp" line="96"/>
|
||||
<source>tips</source>
|
||||
<translation>提示</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_accountmanage.cpp" line="47"/>
|
||||
<source>create user failed: </source>
|
||||
<translation>创建账户失败: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_accountmanage.cpp" line="56"/>
|
||||
<source>Question</source>
|
||||
<translation>询问</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_accountmanage.cpp" line="57"/>
|
||||
<source>Are you sure to destroy: </source>
|
||||
<translation>请确认是否删除账户: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_accountmanage.cpp" line="59"/>
|
||||
<source>yes</source>
|
||||
<translation>确定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_accountmanage.cpp" line="60"/>
|
||||
<source>no</source>
|
||||
<translation>取消</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_accountmanage.cpp" line="71"/>
|
||||
<source>destroy user failed: </source>
|
||||
<translation>销毁账户失败: </translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_accountmanage.cpp" line="92"/>
|
||||
<source>change password succeed</source>
|
||||
<translation>修改密码成功</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_accountmanage.cpp" line="96"/>
|
||||
<source>change password failed: </source>
|
||||
<translation>修改密码失败: </translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Dialog_changePwd</name>
|
||||
<message>
|
||||
<location filename="dialog_changepwd.ui" line="14"/>
|
||||
<source>Dialog</source>
|
||||
<translation>修改密码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_changepwd.ui" line="35"/>
|
||||
<source>old password:</source>
|
||||
<translation>旧密码:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_changepwd.ui" line="75"/>
|
||||
<source>new password:</source>
|
||||
<translation>新密码:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_changepwd.ui" line="115"/>
|
||||
<source>confirm new password:</source>
|
||||
<translation>确认密码:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_changepwd.ui" line="155"/>
|
||||
<source>OK</source>
|
||||
<translation>确定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_changepwd.ui" line="162"/>
|
||||
<source>Cancel</source>
|
||||
<translation>取消</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_changepwd.cpp" line="33"/>
|
||||
<location filename="dialog_changepwd.cpp" line="40"/>
|
||||
<source>tips</source>
|
||||
<translation>提示</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_changepwd.cpp" line="33"/>
|
||||
<source>The passwords entered twice are inconsistent</source>
|
||||
<translation>两次输入的密码不一致</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_changepwd.cpp" line="40"/>
|
||||
<source>Change passwords failed: </source>
|
||||
<translation>修改密码失败: </translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Dialog_logIn</name>
|
||||
<message>
|
||||
<location filename="dialog_login.ui" line="14"/>
|
||||
<source>Dialog</source>
|
||||
<translation>登录</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_login.ui" line="95"/>
|
||||
<source>TextLabel</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_login.ui" line="154"/>
|
||||
<source>account:</source>
|
||||
<translation>账户:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_login.ui" line="194"/>
|
||||
<source>password:</source>
|
||||
<translation>密码:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_login.ui" line="234"/>
|
||||
<source>host:</source>
|
||||
<translation>IP地址:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_login.ui" line="274"/>
|
||||
<source>port:</source>
|
||||
<translation>端口号:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_login.ui" line="314"/>
|
||||
<source>LOG IN</source>
|
||||
<translation>登录</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_login.ui" line="324"/>
|
||||
<source>EXIT</source>
|
||||
<translation>退出</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_login.cpp" line="15"/>
|
||||
<source>Set host and port</source>
|
||||
<translation>设置IP与端口</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_login.cpp" line="16"/>
|
||||
<source>Minimize</source>
|
||||
<translation>最小化</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_login.cpp" line="17"/>
|
||||
<source>Close</source>
|
||||
<translation>关闭</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_login.cpp" line="20"/>
|
||||
<source>LogIn</source>
|
||||
<translation>登录</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_login.cpp" line="84"/>
|
||||
<source>tips</source>
|
||||
<translation>提示</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_login.cpp" line="84"/>
|
||||
<source>Login failed: </source>
|
||||
<translation>登录失败: </translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Dialog_rootFuntion</name>
|
||||
<message>
|
||||
<location filename="dialog_rootfuntion.ui" line="14"/>
|
||||
<source>Dialog</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_rootfuntion.ui" line="35"/>
|
||||
<source>Account:</source>
|
||||
<translation>账户:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_rootfuntion.ui" line="75"/>
|
||||
<source>password:</source>
|
||||
<translation>密码:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_rootfuntion.ui" line="115"/>
|
||||
<source>OK</source>
|
||||
<translation>确定</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_rootfuntion.ui" line="122"/>
|
||||
<source>Cancel</source>
|
||||
<translation>取消</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_rootfuntion.cpp" line="12"/>
|
||||
<source>Create account</source>
|
||||
<translation>创建账户</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_rootfuntion.cpp" line="18"/>
|
||||
<source>Reset password</source>
|
||||
<translation>重置密码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="dialog_rootfuntion.cpp" line="19"/>
|
||||
<source>new password:</source>
|
||||
<translation>新密码:</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Form_mainInterface</name>
|
||||
<message>
|
||||
<location filename="form_maininterface.ui" line="14"/>
|
||||
<source>Form</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="form_maininterface.ui" line="22"/>
|
||||
<source>SN:</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="form_maininterface.ui" line="73"/>
|
||||
<source>Privious Step</source>
|
||||
<translation>上一步</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="form_maininterface.ui" line="80"/>
|
||||
<source>PASS</source>
|
||||
<translation>通过</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="form_maininterface.ui" line="87"/>
|
||||
<source>FAIL</source>
|
||||
<translation>失败</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="form_maininterface.ui" line="94"/>
|
||||
<source>STOP</source>
|
||||
<translation>终止</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="form_maininterface.ui" line="101"/>
|
||||
<source>Next Step</source>
|
||||
<translation>下一步</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="form_maininterface.cpp" line="39"/>
|
||||
<source>1.Dial switch verification</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="form_maininterface.cpp" line="40"/>
|
||||
<source>2.Check the function of ship type switch</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="form_maininterface.cpp" line="41"/>
|
||||
<source>3.Testing</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>Form_textTips</name>
|
||||
<message>
|
||||
<location filename="form_texttips.ui" line="14"/>
|
||||
<source>Form</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="form_texttips.cpp" line="12"/>
|
||||
<location filename="form_texttips.cpp" line="25"/>
|
||||
<source>Please complete the calibration of ship type switch</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="form_texttips.cpp" line="28"/>
|
||||
<source>Please power on the device and observe the startup status</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="form_texttips.cpp" line="31"/>
|
||||
<source>Testing........</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>MainWindow</name>
|
||||
<message>
|
||||
<location filename="mainwindow.ui" line="14"/>
|
||||
<source>MainWindow</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.ui" line="28"/>
|
||||
<source>menu_device</source>
|
||||
<translation>设备</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.ui" line="35"/>
|
||||
<source>menu_user</source>
|
||||
<translation>用户</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.ui" line="50"/>
|
||||
<source>act_newDevice</source>
|
||||
<translation>新建项目</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.ui" line="55"/>
|
||||
<source>act_manage</source>
|
||||
<translation>账户管理</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.ui" line="60"/>
|
||||
<source>act_changePwd</source>
|
||||
<translation>修改密码</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.ui" line="65"/>
|
||||
<source>act_export</source>
|
||||
<translation>导出</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.ui" line="70"/>
|
||||
<source>act_logOut</source>
|
||||
<translation>登出</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.ui" line="75"/>
|
||||
<source>act_close</source>
|
||||
<translation>关闭</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.cpp" line="87"/>
|
||||
<source>tips</source>
|
||||
<translation>提示</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.cpp" line="87"/>
|
||||
<source>cannot create more table</source>
|
||||
<translation>不能创建更多项目</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.cpp" line="134"/>
|
||||
<source>Illegal user</source>
|
||||
<translation>非法的用户</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.cpp" line="138"/>
|
||||
<source>Wrong password</source>
|
||||
<translation>密码错误</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.cpp" line="142"/>
|
||||
<source>Database error</source>
|
||||
<translation>数据库错误</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.cpp" line="146"/>
|
||||
<source>connect error</source>
|
||||
<translation>连接错误</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="mainwindow.cpp" line="150"/>
|
||||
<source>Failed</source>
|
||||
<translation>错误</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
|
@ -0,0 +1,98 @@
|
|||
#include "analysisjson.h"
|
||||
#include <QFile>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonArray>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
|
||||
AnalysisJson::AnalysisJson(QString path)
|
||||
{
|
||||
if(QFile::exists(path)){
|
||||
QFile file(path);
|
||||
if(file.open(QIODevice::OpenModeFlag::ReadOnly))
|
||||
{
|
||||
m_json = QJsonDocument::fromJson(file.readAll());
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<AnalysisJson::json_node> AnalysisJson::GetNode()
|
||||
{
|
||||
std::vector<AnalysisJson::json_node> nodes;
|
||||
if(!m_json.isObject())
|
||||
return nodes;
|
||||
auto obj = m_json.object();
|
||||
for(auto key : obj.keys())
|
||||
{
|
||||
if(key != "global")
|
||||
nodes.push_back(json_node{obj[key].toObject()["title"].toString(),
|
||||
obj[key].toObject()["name"].toString(),
|
||||
obj[key].toObject()["man"].toBool(),
|
||||
obj[key].toObject()["err-level"].toInt()});
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
AnalysisJson::json_global AnalysisJson::GetGlobal()
|
||||
{
|
||||
if(!m_json.isObject())
|
||||
return json_global();
|
||||
auto obj = m_json.object()["global"].toObject();
|
||||
return json_global{obj["vid-org"].toInt(),
|
||||
obj["pid-org"].toInt(),
|
||||
obj["vid-to"].toInt(),
|
||||
obj["pid-to"].toInt()};
|
||||
|
||||
}
|
||||
|
||||
bool AnalysisJson::savejson(QString path, std::vector<AnalysisJson::json_node> json)
|
||||
{
|
||||
|
||||
QFileInfo info(path);
|
||||
if(!info.isFile())
|
||||
return false;
|
||||
if(!info.dir().exists())
|
||||
QDir().mkdir(info.dir().path());
|
||||
QJsonDocument doc;
|
||||
QJsonObject obj;
|
||||
int index =1;
|
||||
for(auto json_ : json)
|
||||
{
|
||||
QJsonObject tmp_obj;
|
||||
tmp_obj["title"] = json_.title;
|
||||
tmp_obj["name"] = json_.name;
|
||||
tmp_obj["man"] = json_.is_man;
|
||||
tmp_obj["err_level"] = json_.err_level;
|
||||
obj[QString::number(index++)] = tmp_obj;
|
||||
}
|
||||
doc.setObject(obj);
|
||||
QFile file(path);
|
||||
if(file.open(QIODevice::OpenModeFlag::WriteOnly))
|
||||
{
|
||||
file.write(doc.toJson());
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AnalysisJson::savejson(QString path, QJsonDocument doc)
|
||||
{
|
||||
QFileInfo info(path);
|
||||
if(!info.isFile())
|
||||
return false;
|
||||
if(!info.dir().exists())
|
||||
QDir().mkdir(info.dir().path());
|
||||
QFile file(path);
|
||||
if(file.open(QIODevice::OpenModeFlag::WriteOnly))
|
||||
{
|
||||
file.write(doc.toJson());
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef ANALYSISJSON_H
|
||||
#define ANALYSISJSON_H
|
||||
#include <QString>
|
||||
#include <QJsonDocument>
|
||||
#include <vector>
|
||||
|
||||
class AnalysisJson
|
||||
{
|
||||
public:
|
||||
struct json_node{
|
||||
QString title;
|
||||
QString name;
|
||||
bool is_man;
|
||||
std::int32_t err_level;
|
||||
};
|
||||
|
||||
struct json_global{
|
||||
std::int32_t vid_org;
|
||||
std::int32_t pid_org;
|
||||
std::int32_t vid_to;
|
||||
std::int32_t pid_to;
|
||||
};
|
||||
|
||||
AnalysisJson() = delete ;
|
||||
AnalysisJson(QString path);
|
||||
std::vector<json_node> GetNode();
|
||||
json_global GetGlobal();
|
||||
bool savejson(QString path,std::vector<json_node> json);
|
||||
bool savejson(QString path, QJsonDocument doc);
|
||||
|
||||
private:
|
||||
QJsonDocument m_json;
|
||||
};
|
||||
|
||||
#endif // ANALYSISJSON_H
|
|
@ -0,0 +1,113 @@
|
|||
#include "dialog_accountmanage.h"
|
||||
#include "ui_dialog_accountmanage.h"
|
||||
#include "dialog_rootfuntion.h"
|
||||
#include "mainwindow.h"
|
||||
#include <QMessageBox>
|
||||
|
||||
|
||||
Dialog_accountManage::Dialog_accountManage(HGPdtToolDbUserMgr pdtToolDbuserMgr, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_pdtToolDbuserMgr(pdtToolDbuserMgr),
|
||||
ui(new Ui::Dialog_accountManage)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
|
||||
|
||||
HGChar* userNameList[100];
|
||||
HGUInt count = 0;
|
||||
HGPdtToolDb_GetUserList(pdtToolDbuserMgr, userNameList, 100, &count);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
ui->listWidget->addItem(QString(userNameList[i]));
|
||||
}
|
||||
|
||||
ui->listWidget->setCurrentRow(0);
|
||||
|
||||
HGPdtToolDb_ReleaseUserList(userNameList, count);
|
||||
}
|
||||
|
||||
Dialog_accountManage::~Dialog_accountManage()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void Dialog_accountManage::on_pbtn_newAccount_clicked()
|
||||
{
|
||||
Dialog_rootFuntion dlg(false, this);
|
||||
if (dlg.exec())
|
||||
{
|
||||
HGResult ret = HGPdtToolDb_CreateUser(m_pdtToolDbuserMgr, dlg.getAccount().toStdString().c_str(), dlg.getPassword().toStdString().c_str());
|
||||
if (ret == HGBASE_ERR_OK)
|
||||
{
|
||||
ui->listWidget->addItem(dlg.getAccount());
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::information(this, tr("tips"), tr("create user failed: ") + MainWindow::getLogInfo(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Dialog_accountManage::on_pbtn_destroyAccount_clicked()
|
||||
{
|
||||
QString userName = ui->listWidget->currentItem()->text();
|
||||
|
||||
QMessageBox msg(QMessageBox::Question, tr("Question"),
|
||||
tr("Are you sure to destroy: ") + userName,
|
||||
QMessageBox::Yes | QMessageBox::No, this);
|
||||
msg.setButtonText(QMessageBox::Yes, tr("yes"));
|
||||
msg.setButtonText(QMessageBox::No, tr("no"));
|
||||
msg.exec();
|
||||
if (msg.clickedButton() == msg.button(QMessageBox::Yes))
|
||||
{
|
||||
HGResult ret = HGPdtToolDb_DestroyUser(m_pdtToolDbuserMgr, userName.toStdString().c_str());
|
||||
if(ret == HGBASE_ERR_OK)
|
||||
{
|
||||
ui->listWidget->takeItem(ui->listWidget->currentRow());
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::information(this, tr("tips"), tr("destroy user failed: ") + MainWindow::getLogInfo(ret));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Dialog_accountManage::on_pbtn_changePwd_clicked()
|
||||
{
|
||||
Dialog_rootFuntion dlg(true, this);
|
||||
if (dlg.exec())
|
||||
{
|
||||
QString userName = ui->listWidget->currentItem()->text();
|
||||
HGResult ret = HGPdtToolDb_SetPassword(m_pdtToolDbuserMgr, userName.toStdString().c_str(), dlg.getPassword().toStdString().c_str());
|
||||
if(ret == HGBASE_ERR_OK)
|
||||
{
|
||||
QMessageBox::information(this, tr("tips"), tr("change password succeed"));
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::information(this, tr("tips"), tr("change password failed: ") + MainWindow::getLogInfo(ret));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Dialog_accountManage::on_pbtn_exit_clicked()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
void Dialog_accountManage::on_listWidget_itemDoubleClicked(QListWidgetItem *item)
|
||||
{
|
||||
(void)item;
|
||||
on_pbtn_changePwd_clicked();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef DIALOG_ACCOUNTMANAGE_H
|
||||
#define DIALOG_ACCOUNTMANAGE_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "HGPdtToolDb.h"
|
||||
#include <QListWidgetItem>
|
||||
|
||||
namespace Ui {
|
||||
class Dialog_accountManage;
|
||||
}
|
||||
|
||||
class Dialog_accountManage : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Dialog_accountManage(HGPdtToolDbUserMgr pdtToolDbuserMgr, QWidget *parent = nullptr);
|
||||
~Dialog_accountManage();
|
||||
|
||||
private slots:
|
||||
void on_pbtn_newAccount_clicked();
|
||||
|
||||
void on_pbtn_destroyAccount_clicked();
|
||||
|
||||
void on_pbtn_changePwd_clicked();
|
||||
|
||||
void on_pbtn_exit_clicked();
|
||||
|
||||
void on_listWidget_itemDoubleClicked(QListWidgetItem *item);
|
||||
|
||||
private:
|
||||
Ui::Dialog_accountManage *ui;
|
||||
|
||||
HGPdtToolDbUserMgr m_pdtToolDbuserMgr;
|
||||
};
|
||||
|
||||
#endif // DIALOG_ACCOUNTMANAGE_H
|
|
@ -0,0 +1,99 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Dialog_accountManage</class>
|
||||
<widget class="QDialog" name="Dialog_accountManage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>425</width>
|
||||
<height>209</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Account List:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QListWidget" name="listWidget"/>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_newAccount">
|
||||
<property name="text">
|
||||
<string>NEW</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_destroyAccount">
|
||||
<property name="text">
|
||||
<string>Destroy</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_changePwd">
|
||||
<property name="text">
|
||||
<string>Set Password</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,49 @@
|
|||
#include "dialog_changepwd.h"
|
||||
#include "ui_dialog_changepwd.h"
|
||||
#include <QMessageBox>
|
||||
#include "mainwindow.h"
|
||||
|
||||
Dialog_changePwd::Dialog_changePwd(HGPdtToolDbUserMgr pdtToolDbuserMgr, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_pdtToolDbuserMgr(pdtToolDbuserMgr),
|
||||
ui(new Ui::Dialog_changePwd)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
|
||||
|
||||
ui->lineEdit_oldPwd->setEchoMode(QLineEdit::EchoMode::Password);
|
||||
ui->lineEdit_newPwd->setEchoMode(QLineEdit::EchoMode::Password);
|
||||
ui->lineEdit_confirmNewPwd->setEchoMode(QLineEdit::EchoMode::Password);
|
||||
}
|
||||
|
||||
Dialog_changePwd::~Dialog_changePwd()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void Dialog_changePwd::on_pbtn_ok_clicked()
|
||||
{
|
||||
QString oldPwd = ui->lineEdit_oldPwd->text();
|
||||
QString newPwd = ui->lineEdit_newPwd->text();
|
||||
QString confirmNewPwd = ui->lineEdit_confirmNewPwd->text();
|
||||
|
||||
if(newPwd != confirmNewPwd)
|
||||
{
|
||||
QMessageBox::information(this, tr("tips"), tr("The passwords entered twice are inconsistent"));
|
||||
return;
|
||||
}
|
||||
|
||||
HGResult ret = HGPdtToolDb_ModifyPassword(m_pdtToolDbuserMgr, oldPwd.toStdString().c_str(), newPwd.toStdString().c_str());
|
||||
if(ret != HGBASE_ERR_OK)
|
||||
{
|
||||
QMessageBox::information(this, tr("tips"), tr("Change passwords failed: ") + MainWindow::getLogInfo(ret));
|
||||
return;
|
||||
}
|
||||
accept();
|
||||
}
|
||||
|
||||
void Dialog_changePwd::on_pbtn_cancel_clicked()
|
||||
{
|
||||
reject();
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#ifndef DIALOG_CHANGEPWD_H
|
||||
#define DIALOG_CHANGEPWD_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "HGPdtToolDb.h"
|
||||
|
||||
namespace Ui {
|
||||
class Dialog_changePwd;
|
||||
}
|
||||
|
||||
class Dialog_changePwd : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Dialog_changePwd(HGPdtToolDbUserMgr pdtToolDbuserMgr, QWidget *parent = nullptr);
|
||||
~Dialog_changePwd();
|
||||
|
||||
private slots:
|
||||
void on_pbtn_ok_clicked();
|
||||
|
||||
void on_pbtn_cancel_clicked();
|
||||
|
||||
private:
|
||||
Ui::Dialog_changePwd *ui;
|
||||
|
||||
HGPdtToolDbUserMgr m_pdtToolDbuserMgr;
|
||||
|
||||
};
|
||||
|
||||
#endif // DIALOG_CHANGEPWD_H
|
|
@ -0,0 +1,172 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Dialog_changePwd</class>
|
||||
<widget class="QDialog" name="Dialog_changePwd">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>389</width>
|
||||
<height>150</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>old password:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_oldPwd"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>new password:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_newPwd"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>confirm new password:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_confirmNewPwd"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_ok">
|
||||
<property name="text">
|
||||
<string>OK</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_cancel">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,114 @@
|
|||
#include "dialog_login.h"
|
||||
#include "ui_dialog_login.h"
|
||||
#include <QMessageBox>
|
||||
#include "mainwindow.h"
|
||||
|
||||
Dialog_logIn::Dialog_logIn(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_pdtToolDbuserMgr(nullptr),
|
||||
ui(new Ui::Dialog_logIn)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
setWindowFlags(Qt::FramelessWindowHint);
|
||||
|
||||
ui->pbtn_setting->setToolTip(tr("Set host and port"));
|
||||
ui->pbtn_minum->setToolTip(tr("Minimize"));
|
||||
ui->pbtn_close->setToolTip(tr("Close"));
|
||||
|
||||
ui->label_title->setText(tr("LogIn"));
|
||||
|
||||
ui->lineEdit_account->setText("root");
|
||||
ui->lineEdit_password->setEchoMode(QLineEdit::EchoMode::Password);
|
||||
ui->lineEdit_host->setText("192.168.1.70");
|
||||
ui->lineEdit_port->setText("3306");
|
||||
|
||||
ui->label_host->setVisible(false);
|
||||
ui->label_port->setVisible(false);
|
||||
ui->lineEdit_host->setVisible(false);
|
||||
ui->lineEdit_port->setVisible(false);
|
||||
}
|
||||
|
||||
Dialog_logIn::~Dialog_logIn()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
HGPdtToolDbUserMgr Dialog_logIn::GetUserMgr()
|
||||
{
|
||||
return m_pdtToolDbuserMgr;
|
||||
}
|
||||
|
||||
void Dialog_logIn::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if(event->button()==Qt::LeftButton)
|
||||
{
|
||||
m_leftMousePressed = true;
|
||||
m_startPos = event->globalPos();
|
||||
}
|
||||
}
|
||||
|
||||
void Dialog_logIn::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
if(m_leftMousePressed)
|
||||
{
|
||||
this->window()->move(this->window()->geometry().topLeft() + event->globalPos() - m_startPos);
|
||||
m_startPos = event->globalPos();
|
||||
}
|
||||
}
|
||||
|
||||
void Dialog_logIn::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
if(event->button()==Qt::LeftButton)
|
||||
{
|
||||
m_leftMousePressed = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Dialog_logIn::on_pbtn_login_clicked()
|
||||
{
|
||||
QString account = ui->lineEdit_account->text();
|
||||
QString password = ui->lineEdit_password->text();
|
||||
QString host = ui->lineEdit_host->text();
|
||||
QString port = ui->lineEdit_port->text();
|
||||
|
||||
HGResult ret = HGPdtToolDb_CreateUserMgr(host.toStdString().c_str(), port.toInt(),
|
||||
account.toStdString().c_str(), password.toStdString().c_str(), &m_pdtToolDbuserMgr);
|
||||
if (NULL != m_pdtToolDbuserMgr)
|
||||
{
|
||||
accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
QMessageBox::information(this, tr("tips"), tr("Login failed: ") + MainWindow::getLogInfo(ret));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Dialog_logIn::on_pushButton_exit_clicked()
|
||||
{
|
||||
reject();
|
||||
}
|
||||
|
||||
void Dialog_logIn::on_pbtn_setting_clicked(bool checked)
|
||||
{
|
||||
ui->label_user->setVisible(!checked);
|
||||
ui->label_password->setVisible(!checked);
|
||||
ui->lineEdit_account->setVisible(!checked);
|
||||
ui->lineEdit_password->setVisible(!checked);
|
||||
|
||||
ui->label_host->setVisible(checked);
|
||||
ui->label_port->setVisible(checked);
|
||||
ui->lineEdit_host->setVisible(checked);
|
||||
ui->lineEdit_port->setVisible(checked);
|
||||
}
|
||||
|
||||
void Dialog_logIn::on_pbtn_minum_clicked()
|
||||
{
|
||||
this->window()->showMinimized();
|
||||
}
|
||||
|
||||
void Dialog_logIn::on_pbtn_close_clicked()
|
||||
{
|
||||
close();
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef DIALOG_LOGIN_H
|
||||
#define DIALOG_LOGIN_H
|
||||
|
||||
#include <QDialog>
|
||||
#include "HGPdtToolDb.h"
|
||||
|
||||
namespace Ui {
|
||||
class Dialog_logIn;
|
||||
}
|
||||
|
||||
class Dialog_logIn : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Dialog_logIn(QWidget *parent = nullptr);
|
||||
~Dialog_logIn();
|
||||
|
||||
HGPdtToolDbUserMgr GetUserMgr();
|
||||
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
|
||||
private slots:
|
||||
void on_pbtn_login_clicked();
|
||||
|
||||
void on_pushButton_exit_clicked();
|
||||
|
||||
void on_pbtn_setting_clicked(bool checked);
|
||||
|
||||
void on_pbtn_minum_clicked();
|
||||
|
||||
void on_pbtn_close_clicked();
|
||||
|
||||
private:
|
||||
Ui::Dialog_logIn *ui;
|
||||
|
||||
HGPdtToolDbUserMgr m_pdtToolDbuserMgr;
|
||||
QPoint m_startPos;
|
||||
QPoint m_endPos;
|
||||
bool m_leftMousePressed;
|
||||
};
|
||||
|
||||
#endif // DIALOG_LOGIN_H
|
|
@ -0,0 +1,366 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Dialog_logIn</class>
|
||||
<widget class="QDialog" name="Dialog_logIn">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>434</width>
|
||||
<height>245</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="widget" native="true">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>441</width>
|
||||
<height>30</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>16777215</width>
|
||||
<height>31</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="styleSheet">
|
||||
<string notr="true">QWidget#widget
|
||||
{
|
||||
background-color: rgb(245, 245, 245);
|
||||
}
|
||||
QLabel#label_icon
|
||||
{
|
||||
image:url(:image/image_rsc/icon/admin.png);
|
||||
}
|
||||
QPushButton#pbtn_setting
|
||||
{
|
||||
border-style: solid;
|
||||
border-width: 0px;
|
||||
border-radius: 0px;
|
||||
background-color: rgba(223, 223, 223, 0);
|
||||
image:url(:image/image_rsc/icon/setting.ico);
|
||||
}
|
||||
QPushButton#pbtn_minum
|
||||
{
|
||||
border-style: solid;
|
||||
border-width: 0px;
|
||||
border-radius: 0px;
|
||||
background-color: rgba(223, 223, 223, 0);
|
||||
image:url(:image/image_rsc/icon/minum.ico);
|
||||
}
|
||||
QPushButton#pbtn_close
|
||||
{
|
||||
border-style: solid;
|
||||
border-width: 0px;
|
||||
border-radius: 0px;
|
||||
background-color: rgba(223, 223, 223, 0);
|
||||
image:url(:image/image_rsc/icon/close.ico);
|
||||
}
|
||||
QPushButton::focus{outline: none;}
|
||||
QPushButton#pbtn_setting::hover
|
||||
{
|
||||
border-style: solid;
|
||||
border-width: 0px;
|
||||
border-radius: 0px;
|
||||
background-color: rgba(223, 223, 223, 150);
|
||||
}
|
||||
QPushButton#pbtn_minum::hover
|
||||
{
|
||||
border-style: solid;
|
||||
border-width: 0px;
|
||||
border-radius: 0px;
|
||||
background-color: rgba(223, 223, 223, 150);
|
||||
}
|
||||
QPushButton#pbtn_close::hover
|
||||
{
|
||||
border-style: solid;
|
||||
border-width: 0px;
|
||||
border-radius: 0px;
|
||||
background-color: rgba(223, 223, 223, 150);
|
||||
}
|
||||
</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_title">
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>13 楷体</family>
|
||||
<pointsize>9</pointsize>
|
||||
<weight>50</weight>
|
||||
<italic>false</italic>
|
||||
<bold>false</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>112</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_setting">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_minum">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_close">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>40</y>
|
||||
<width>321</width>
|
||||
<height>191</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_user">
|
||||
<property name="text">
|
||||
<string>account:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_account"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_6">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_password">
|
||||
<property name="text">
|
||||
<string>password:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_password"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_8">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_host">
|
||||
<property name="text">
|
||||
<string>host:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_host"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_9">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_5">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_10">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_port">
|
||||
<property name="text">
|
||||
<string>port:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_port"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_11">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_login">
|
||||
<property name="text">
|
||||
<string>LOG IN</string>
|
||||
</property>
|
||||
<property name="default">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pushButton_exit">
|
||||
<property name="text">
|
||||
<string>EXIT</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,48 @@
|
|||
#include "dialog_rootfuntion.h"
|
||||
#include "ui_dialog_rootfuntion.h"
|
||||
|
||||
Dialog_rootFuntion::Dialog_rootFuntion(bool resetPassword, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
m_resetPassword(resetPassword),
|
||||
ui(new Ui::Dialog_rootFuntion)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);
|
||||
setWindowTitle(tr("Create account"));
|
||||
|
||||
ui->lineEdit_password->setEchoMode(QLineEdit::EchoMode::Password);
|
||||
|
||||
if (m_resetPassword)
|
||||
{
|
||||
setWindowTitle(tr("Reset password"));
|
||||
ui->label_password->setText(tr("new password:"));
|
||||
ui->label_account->setVisible(false);
|
||||
ui->lineEdit_account->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
Dialog_rootFuntion::~Dialog_rootFuntion()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QString Dialog_rootFuntion::getAccount()
|
||||
{
|
||||
return ui->lineEdit_account->text();
|
||||
}
|
||||
|
||||
QString Dialog_rootFuntion::getPassword()
|
||||
{
|
||||
return ui->lineEdit_password->text();
|
||||
}
|
||||
|
||||
void Dialog_rootFuntion::on_pbtn_ok_clicked()
|
||||
{
|
||||
accept();
|
||||
}
|
||||
|
||||
void Dialog_rootFuntion::on_pbtn_cancel_clicked()
|
||||
{
|
||||
reject();
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef DIALOG_ROOTFUNTION_H
|
||||
#define DIALOG_ROOTFUNTION_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui {
|
||||
class Dialog_rootFuntion;
|
||||
}
|
||||
|
||||
class Dialog_rootFuntion : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Dialog_rootFuntion(bool resetPassword, QWidget *parent = nullptr);
|
||||
~Dialog_rootFuntion();
|
||||
|
||||
QString getAccount();
|
||||
QString getPassword();
|
||||
|
||||
private slots:
|
||||
void on_pbtn_ok_clicked();
|
||||
|
||||
void on_pbtn_cancel_clicked();
|
||||
|
||||
private:
|
||||
Ui::Dialog_rootFuntion *ui;
|
||||
|
||||
bool m_resetPassword;
|
||||
};
|
||||
|
||||
#endif // DIALOG_ROOTFUNTION_H
|
|
@ -0,0 +1,132 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Dialog_rootFuntion</class>
|
||||
<widget class="QDialog" name="Dialog_rootFuntion">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>425</width>
|
||||
<height>117</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_account">
|
||||
<property name="text">
|
||||
<string>Account:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_account"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_password">
|
||||
<property name="text">
|
||||
<string>password:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="lineEdit_password"/>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_4">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_7">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_ok">
|
||||
<property name="text">
|
||||
<string>OK</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_cancel">
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,86 @@
|
|||
#include "form_maininterface.h"
|
||||
#include "ui_form_maininterface.h"
|
||||
#include <QPainter>
|
||||
#include "imgfmt/HGImgFmt.h"
|
||||
#include "HGUIGlobal.h"
|
||||
#include "form_texttips.h"
|
||||
|
||||
Form_mainInterface::Form_mainInterface(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::Form_mainInterface)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
QString path("../../doc/config.json");
|
||||
AnalysisJson analysisJson(path);
|
||||
|
||||
std::vector<AnalysisJson::json_node> list_jsonNode = analysisJson.GetNode();
|
||||
for(int i = 0; i < list_jsonNode.size(); ++i)
|
||||
{
|
||||
AnalysisJson::json_node node = list_jsonNode[i];
|
||||
ui->listWidget->addItem(node.title);
|
||||
}
|
||||
|
||||
this->setMinimumWidth(400);
|
||||
ui->listWidget->setMinimumWidth(200);
|
||||
ui->listWidget->setCurrentRow(0);
|
||||
ui->pbtn_preStep->setEnabled(false);
|
||||
}
|
||||
|
||||
Form_mainInterface::~Form_mainInterface()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void Form_mainInterface::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
(void)event;
|
||||
QPainter p(this);
|
||||
p.setPen(QColor("gray"));
|
||||
p.drawRect(0, 0, width() -1, height() -1);
|
||||
}
|
||||
|
||||
void Form_mainInterface::on_listWidget_currentRowChanged(int currentRow)
|
||||
{
|
||||
ui->pbtn_preStep->setEnabled(ui->listWidget->currentRow() != 0);
|
||||
ui->pbtn_nextStep->setEnabled(ui->listWidget->currentRow() != ui->listWidget->count() - 1);
|
||||
|
||||
if (currentRow == 0)
|
||||
{
|
||||
Form_textTips *textTips = new Form_textTips();
|
||||
ui->stackedWidget->addWidget(textTips);
|
||||
ui->stackedWidget->setCurrentWidget(textTips);
|
||||
}
|
||||
if (currentRow == 1)
|
||||
{
|
||||
HGImgView *m_view = new HGImgView();
|
||||
ui->stackedWidget->addWidget(m_view);
|
||||
ui->stackedWidget->setCurrentWidget(m_view);
|
||||
|
||||
HGImage img;
|
||||
QString filename("C:\\Users\\yang'jia'xuan\\Pictures\\4.jpg");
|
||||
HGImgFmt_LoadImage(getStdFileName(filename).toStdString().c_str(), 0, 0, 0, 0, &img);
|
||||
m_view->addImage(img);
|
||||
}
|
||||
}
|
||||
|
||||
void Form_mainInterface::on_pbtn_preStep_clicked()
|
||||
{
|
||||
ui->listWidget->setCurrentRow(ui->listWidget->currentRow() - 1);
|
||||
}
|
||||
|
||||
void Form_mainInterface::on_pbtn_nextStep_clicked()
|
||||
{
|
||||
ui->listWidget->setCurrentRow(ui->listWidget->currentRow() + 1);
|
||||
}
|
||||
|
||||
void Form_mainInterface::on_pbtn_fail_clicked()
|
||||
{
|
||||
ui->listWidget->item(ui->listWidget->currentRow())->setBackgroundColor("red");
|
||||
}
|
||||
|
||||
void Form_mainInterface::on_pbtn_pass_clicked()
|
||||
{
|
||||
ui->listWidget->item(ui->listWidget->currentRow())->setBackgroundColor("white");
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef FORM_MAININTERFACE_H
|
||||
#define FORM_MAININTERFACE_H
|
||||
|
||||
#include <QWidget>
|
||||
#include "HGImgView.h"
|
||||
#include "analysisjson.h"
|
||||
|
||||
namespace Ui {
|
||||
class Form_mainInterface;
|
||||
}
|
||||
|
||||
class Form_mainInterface : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Form_mainInterface(QWidget *parent = nullptr);
|
||||
~Form_mainInterface();
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
|
||||
private slots:
|
||||
void on_listWidget_currentRowChanged(int currentRow);
|
||||
|
||||
void on_pbtn_preStep_clicked();
|
||||
|
||||
void on_pbtn_nextStep_clicked();
|
||||
|
||||
void on_pbtn_fail_clicked();
|
||||
|
||||
void on_pbtn_pass_clicked();
|
||||
|
||||
private:
|
||||
Ui::Form_mainInterface *ui;
|
||||
|
||||
AnalysisJson *m_analysisJson;
|
||||
};
|
||||
|
||||
#endif // FORM_MAININTERFACE_H
|
|
@ -0,0 +1,124 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form_mainInterface</class>
|
||||
<widget class="QWidget" name="Form_mainInterface">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>607</width>
|
||||
<height>429</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_sn">
|
||||
<property name="text">
|
||||
<string>SN:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,3">
|
||||
<item>
|
||||
<widget class="QListWidget" name="listWidget"/>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>-1</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_preStep">
|
||||
<property name="text">
|
||||
<string>Privious Step</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_pass">
|
||||
<property name="text">
|
||||
<string>PASS</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_fail">
|
||||
<property name="text">
|
||||
<string>FAIL</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_stop">
|
||||
<property name="text">
|
||||
<string>STOP</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="pbtn_nextStep">
|
||||
<property name="text">
|
||||
<string>Next Step</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,45 @@
|
|||
#include "form_texttips.h"
|
||||
#include "ui_form_texttips.h"
|
||||
|
||||
Form_textTips::Form_textTips(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, ui(new Ui::Form_textTips)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
QFont ft;
|
||||
ft.setPointSize(35);
|
||||
ui->textBrowser->setFont(ft);
|
||||
ui->textBrowser->setText(tr("Please complete the calibration of ship type switch"));
|
||||
}
|
||||
|
||||
Form_textTips::~Form_textTips()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
void Form_textTips::on_testItemChanged(int curRow)
|
||||
{
|
||||
switch (curRow)
|
||||
{
|
||||
case 0:
|
||||
ui->textBrowser->setText(tr("Please complete the calibration of ship type switch"));
|
||||
break;
|
||||
case 1:
|
||||
ui->textBrowser->setText(tr("Please power on the device and observe the startup status"));
|
||||
break;
|
||||
case 2:
|
||||
ui->textBrowser->setText(tr("Testing........"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef FORM_TEXTTIPS_H
|
||||
#define FORM_TEXTTIPS_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui {
|
||||
class Form_textTips;
|
||||
}
|
||||
|
||||
class Form_textTips : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Form_textTips(QWidget *parent = nullptr);
|
||||
~Form_textTips();
|
||||
|
||||
public slots:
|
||||
void on_testItemChanged(int curRow);
|
||||
|
||||
|
||||
private:
|
||||
Ui::Form_textTips *ui;
|
||||
};
|
||||
|
||||
#endif // FORM_TEXTTIPS_H
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>Form_textTips</class>
|
||||
<widget class="QWidget" name="Form_textTips">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="textBrowser"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Binary file not shown.
After Width: | Height: | Size: 257 KiB |
Binary file not shown.
After Width: | Height: | Size: 248 KiB |
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
|
@ -0,0 +1,40 @@
|
|||
#include "mainwindow.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QTranslator>
|
||||
#include "base/HGBase.h"
|
||||
#include "dialog_login.h"
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QApplication a(argc, argv);
|
||||
|
||||
QTranslator translator_qt;
|
||||
if (translator_qt.load(":translation/ProductionTool_zh_CN.qm"))
|
||||
a.installTranslator(&translator_qt);
|
||||
|
||||
while (1)
|
||||
{
|
||||
Dialog_logIn login;
|
||||
if (login.exec())
|
||||
{
|
||||
HGPdtToolDbUserMgr userMgr = login.GetUserMgr();
|
||||
assert(nullptr != userMgr);
|
||||
|
||||
MainWindow w(userMgr);
|
||||
w.showMaximized();
|
||||
a.exec();
|
||||
|
||||
if (w.isExitApp())
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,154 @@
|
|||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include <QVBoxLayout>
|
||||
#include "base/HGBase.h"
|
||||
#include "HGUIGlobal.h"
|
||||
#include "dialog_login.h"
|
||||
#include "dialog_changepwd.h"
|
||||
#include "dialog_accountmanage.h"
|
||||
|
||||
MainWindow::MainWindow(HGPdtToolDbUserMgr userMgr, QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
, ui(new Ui::MainWindow)
|
||||
, m_pdtToolDbuserMgr(userMgr)
|
||||
, m_form_mainInterface(nullptr)
|
||||
, m_top_splitter(nullptr)
|
||||
, m_bot_splitter(nullptr)
|
||||
, m_splitterCount(1)
|
||||
, m_isLogOut(false)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setWindowIcon(QIcon(":image/image_rsc/logo/logo.ico"));
|
||||
|
||||
HGUInt userType = 0;
|
||||
HGPdtToolDb_GetUserType(m_pdtToolDbuserMgr, &userType);
|
||||
if (userType == HGPDTTOOLDB_USERTYPE_NORMAL)
|
||||
ui->act_manage->setVisible(false);
|
||||
|
||||
HGChar userName[128];
|
||||
HGPdtToolDb_GetUserName(m_pdtToolDbuserMgr, userName, 128);
|
||||
setWindowTitle(userName);
|
||||
|
||||
m_top_splitter = new QSplitter(Qt::Horizontal);
|
||||
m_bot_splitter = new QSplitter(Qt::Horizontal);
|
||||
m_form_mainInterface = new Form_mainInterface();
|
||||
m_top_splitter->addWidget(m_form_mainInterface);
|
||||
|
||||
QVBoxLayout *vLayout = new QVBoxLayout;
|
||||
vLayout->addWidget(m_top_splitter);
|
||||
vLayout->addWidget(m_bot_splitter);
|
||||
vLayout->setStretch(0, 1);
|
||||
vLayout->setStretch(1, 0);
|
||||
this->centralWidget()->setLayout(vLayout);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
{
|
||||
HGPdtToolDb_DestroyUserMgr(m_pdtToolDbuserMgr);
|
||||
m_pdtToolDbuserMgr = NULL;
|
||||
|
||||
delete ui;
|
||||
}
|
||||
|
||||
bool MainWindow::isExitApp()
|
||||
{
|
||||
return !m_isLogOut;
|
||||
}
|
||||
|
||||
void MainWindow::on_act_newDevice_triggered()
|
||||
{
|
||||
m_splitterCount++;
|
||||
switch (m_splitterCount)
|
||||
{
|
||||
case 2:
|
||||
{
|
||||
Form_mainInterface *form_mainInterface = new Form_mainInterface();
|
||||
m_top_splitter->addWidget(form_mainInterface);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case 3:
|
||||
{
|
||||
Form_mainInterface *form_mainInterface = new Form_mainInterface();
|
||||
m_bot_splitter->addWidget(form_mainInterface);
|
||||
reinterpret_cast<QVBoxLayout*>(this->centralWidget()->layout())->setStretch(1, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
case 4:
|
||||
{
|
||||
Form_mainInterface *form_mainInterface = new Form_mainInterface();
|
||||
m_bot_splitter->addWidget(form_mainInterface);
|
||||
break;
|
||||
}
|
||||
|
||||
case 5:
|
||||
QMessageBox::information(this, tr("tips"), tr("cannot create more table"));
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_act_manage_triggered()
|
||||
{
|
||||
Dialog_accountManage dlg(m_pdtToolDbuserMgr, this);
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void MainWindow::on_act_changePwd_triggered()
|
||||
{
|
||||
Dialog_changePwd dlg(m_pdtToolDbuserMgr, this);
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void MainWindow::on_act_export_triggered()
|
||||
{
|
||||
HGChar cfgPath[256]= {0};
|
||||
HGBase_GetConfigPath(cfgPath, 256);
|
||||
strcat(cfgPath, "1.xls");
|
||||
HGPdtToolDb_Export(m_pdtToolDbuserMgr, getStdString(cfgPath).c_str());
|
||||
}
|
||||
|
||||
void MainWindow::on_act_logOut_triggered()
|
||||
{
|
||||
HGPdtToolDb_DestroyUserMgr(m_pdtToolDbuserMgr);
|
||||
m_isLogOut = true;
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::on_act_close_triggered()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
QString MainWindow::getLogInfo(HGResult ret)
|
||||
{
|
||||
QString str;
|
||||
if (HGPDTTOOLDB_ERR_INVALID_USER == ret)
|
||||
{
|
||||
str = tr("Illegal user");
|
||||
}
|
||||
else if (HGPDTTOOLDB_ERR_WRONG_PASSWORD == ret)
|
||||
{
|
||||
str = tr("Wrong password");
|
||||
}
|
||||
else if (HGPDTTOOLDB_ERR_DATABASE == ret)
|
||||
{
|
||||
str = tr("Database error");
|
||||
}
|
||||
else if (HGPDTTOOLDB_ERR_CONNECT == ret)
|
||||
{
|
||||
str = tr("connect error");
|
||||
}
|
||||
else
|
||||
{
|
||||
str = tr("Failed");
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
#include <QMainWindow>
|
||||
#include "form_maininterface.h"
|
||||
#include "form_texttips.h"
|
||||
#include <QtWidgets>
|
||||
#include <QSplitter>
|
||||
#include "HGPdtToolDb.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace Ui { class MainWindow; }
|
||||
QT_END_NAMESPACE
|
||||
|
||||
class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MainWindow(HGPdtToolDbUserMgr userMgr, QWidget *parent = nullptr);
|
||||
~MainWindow();
|
||||
|
||||
static QString getLogInfo(HGResult ret);
|
||||
|
||||
bool isExitApp();
|
||||
|
||||
private slots:
|
||||
void on_act_newDevice_triggered();
|
||||
|
||||
void on_act_manage_triggered();
|
||||
|
||||
void on_act_changePwd_triggered();
|
||||
|
||||
void on_act_export_triggered();
|
||||
|
||||
void on_act_logOut_triggered();
|
||||
|
||||
void on_act_close_triggered();
|
||||
|
||||
private:
|
||||
QSplitter *m_top_splitter;
|
||||
QSplitter *m_bot_splitter;
|
||||
|
||||
int m_splitterCount;
|
||||
bool m_isLogOut;
|
||||
|
||||
private:
|
||||
Ui::MainWindow *ui;
|
||||
HGPdtToolDbUserMgr m_pdtToolDbuserMgr;
|
||||
|
||||
Form_mainInterface *m_form_mainInterface;
|
||||
|
||||
};
|
||||
#endif // MAINWINDOW_H
|
|
@ -0,0 +1,81 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MainWindow</string>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralwidget"/>
|
||||
<widget class="QMenuBar" name="menubar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<widget class="QMenu" name="menu_device">
|
||||
<property name="title">
|
||||
<string>menu_device</string>
|
||||
</property>
|
||||
<addaction name="act_newDevice"/>
|
||||
<addaction name="act_close"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menu_user">
|
||||
<property name="title">
|
||||
<string>menu_user</string>
|
||||
</property>
|
||||
<addaction name="act_manage"/>
|
||||
<addaction name="act_changePwd"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="act_export"/>
|
||||
<addaction name="separator"/>
|
||||
<addaction name="act_logOut"/>
|
||||
</widget>
|
||||
<addaction name="menu_device"/>
|
||||
<addaction name="menu_user"/>
|
||||
</widget>
|
||||
<widget class="QStatusBar" name="statusbar"/>
|
||||
<action name="act_newDevice">
|
||||
<property name="text">
|
||||
<string>act_newDevice</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="act_manage">
|
||||
<property name="text">
|
||||
<string>act_manage</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="act_changePwd">
|
||||
<property name="text">
|
||||
<string>act_changePwd</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="act_export">
|
||||
<property name="text">
|
||||
<string>act_export</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="act_logOut">
|
||||
<property name="text">
|
||||
<string>act_logOut</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="act_close">
|
||||
<property name="text">
|
||||
<string>act_close</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef __HGBASE_H__
|
||||
#define __HGBASE_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
#include "HGBase64.h"
|
||||
#include "HGDes.h"
|
||||
#include "HGMd5.h"
|
||||
#include "HGLock.h"
|
||||
#include "HGEvent.h"
|
||||
#include "HGDll.h"
|
||||
#include "HGLog.h"
|
||||
#include "HGConsole.h"
|
||||
#include "HGBuffer.h"
|
||||
#include "HGImage.h"
|
||||
#include "HGThread.h"
|
||||
#include "HGUtility.h"
|
||||
#include "HGInfo.h"
|
||||
#include "HGIni.h"
|
||||
#include "HGMsgPump.h"
|
||||
#include "HGTime.h"
|
||||
#include "HGNamedPipe.h"
|
||||
|
||||
#endif /* __HGBASE_H__ */
|
|
@ -0,0 +1,255 @@
|
|||
#include "HGBase64.h"
|
||||
#include "HGInc.h"
|
||||
|
||||
HGResult HGAPI HGBase_Base64Encode(const HGByte* originalData, HGSize originalSize,
|
||||
HGByte* base64Data, HGSize* base64Size)
|
||||
{
|
||||
if (NULL == originalData || 0 == originalSize)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (NULL != base64Data)
|
||||
{
|
||||
static const HGByte base64Table[] =
|
||||
{
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
|
||||
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3',
|
||||
'4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
|
||||
HGSize numberOfCycles = originalSize / 3;
|
||||
|
||||
//#pragma omp parallel for
|
||||
for (HGSize i = 0; i < numberOfCycles; ++i)
|
||||
{
|
||||
const HGByte* originalDataEx = originalData + i * 3;
|
||||
HGByte* base64DataEx = base64Data + i * 4;
|
||||
|
||||
HGUInt temp = (((HGUInt)originalDataEx[0] << 16) | ((HGUInt)originalDataEx[1] << 8)
|
||||
| ((HGUInt)originalDataEx[2])) & 0x00FFFFFF;
|
||||
base64DataEx[0] = base64Table[(temp >> 18) & 0x3F];
|
||||
base64DataEx[1] = base64Table[(temp >> 12) & 0x3F];
|
||||
base64DataEx[2] = base64Table[(temp >> 6) & 0x3F];
|
||||
base64DataEx[3] = base64Table[temp & 0x3F];
|
||||
}
|
||||
|
||||
const HGByte* originalDataEx = originalData + numberOfCycles * 3;
|
||||
HGByte* base64DataEx = base64Data + numberOfCycles * 4;
|
||||
|
||||
HGSize sizeOfRemaining = originalSize - numberOfCycles * 3;
|
||||
if (1 == sizeOfRemaining)
|
||||
{
|
||||
HGUInt temp = ((HGUInt)originalDataEx[0] << 16) & 0x00FF0000;
|
||||
base64DataEx[0] = base64Table[(temp >> 18) & 0x3F];
|
||||
base64DataEx[1] = base64Table[(temp >> 12) & 0x3F];
|
||||
base64DataEx[2] = '=';
|
||||
base64DataEx[3] = '=';
|
||||
}
|
||||
else if (2 == sizeOfRemaining)
|
||||
{
|
||||
HGUInt temp = (((HGUInt)originalDataEx[0] << 16) | ((HGUInt)originalDataEx[1] << 8)) & 0x00FFFF00;
|
||||
base64DataEx[0] = base64Table[(temp >> 18) & 0x3F];
|
||||
base64DataEx[1] = base64Table[(temp >> 12) & 0x3F];
|
||||
base64DataEx[2] = base64Table[(temp >> 6) & 0x3F];
|
||||
base64DataEx[3] = '=';
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != base64Size)
|
||||
{
|
||||
HGSize newSize = (originalSize / 3) * 4;
|
||||
if (0 != originalSize % 3)
|
||||
{
|
||||
newSize += 4;
|
||||
}
|
||||
|
||||
*base64Size = newSize;
|
||||
}
|
||||
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_Base64Decode(const HGByte* base64Data, HGSize base64Size,
|
||||
HGByte* originalData, HGSize* originalSize)
|
||||
{
|
||||
if (NULL == base64Data || 0 == base64Size)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (NULL != originalData)
|
||||
{
|
||||
static const HGByte base64Table_1[] =
|
||||
{
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 62, 64, 64, 64, 63,
|
||||
52, 53, 54, 55, 56, 57, 58, 59,
|
||||
60, 61, 64, 64, 64, 64, 64, 64,
|
||||
64, 0, 1, 2, 3, 4, 5, 6,
|
||||
7, 8, 9, 10, 11, 12, 13, 14,
|
||||
15, 16, 17, 18, 19, 20, 21, 22,
|
||||
23, 24, 25, 64, 64, 64, 64, 64,
|
||||
64, 26, 27, 28, 29, 30, 31, 32,
|
||||
33, 34, 35, 36, 37, 38, 39, 40,
|
||||
41, 42, 43, 44, 45, 46, 47, 48,
|
||||
49, 50, 51, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64,
|
||||
64, 64, 64, 64, 64, 64, 64, 64
|
||||
};
|
||||
|
||||
HGSize numberOfCycles = (base64Size - 1) / 4;
|
||||
|
||||
//#pragma omp parallel for
|
||||
for (HGSize i = 0; i < numberOfCycles; ++i)
|
||||
{
|
||||
const HGByte* base64DataEx = base64Data + i * 4;
|
||||
HGByte* originalDataEx = originalData + i * 3;
|
||||
|
||||
HGUInt t0 = base64Table_1[base64DataEx[0]];
|
||||
HGUInt t1 = base64Table_1[base64DataEx[1]];
|
||||
HGUInt t2 = base64Table_1[base64DataEx[2]];
|
||||
HGUInt t3 = base64Table_1[base64DataEx[3]];
|
||||
|
||||
originalDataEx[0] = ((t0 << 2) | (t1 >> 4)) & 0xFF;
|
||||
originalDataEx[1] = ((t1 << 4) | (t2 >> 2)) & 0xFF;
|
||||
originalDataEx[2] = ((t2 << 6) | t3) & 0xFF;
|
||||
}
|
||||
|
||||
const HGByte* base64DataEx = base64Data + numberOfCycles * 4;
|
||||
HGByte* originalDataEx = originalData + numberOfCycles * 3;
|
||||
|
||||
HGSize sizeOfRemaining = base64Size - numberOfCycles * 4;
|
||||
if (2 == sizeOfRemaining)
|
||||
{
|
||||
if ('=' != base64DataEx[0] && '=' != base64DataEx[1])
|
||||
{
|
||||
HGUInt t0 = base64Table_1[base64DataEx[0]];
|
||||
HGUInt t1 = base64Table_1[base64DataEx[1]];
|
||||
|
||||
originalDataEx[0] = ((t0 << 2) | (t1 >> 4)) & 0xFF;
|
||||
}
|
||||
}
|
||||
else if (3 == sizeOfRemaining)
|
||||
{
|
||||
if ('=' != base64DataEx[0] && '=' != base64DataEx[1])
|
||||
{
|
||||
HGUInt t0 = base64Table_1[base64DataEx[0]];
|
||||
HGUInt t1 = base64Table_1[base64DataEx[1]];
|
||||
HGUInt t2 = base64Table_1[base64DataEx[2]];
|
||||
|
||||
if ('=' == base64DataEx[2])
|
||||
{
|
||||
originalDataEx[0] = ((t0 << 2) | (t1 >> 4)) & 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
originalDataEx[0] = ((t0 << 2) | (t1 >> 4)) & 0xFF;
|
||||
originalDataEx[1] = ((t1 << 4) | (t2 >> 2)) & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (4 == sizeOfRemaining)
|
||||
{
|
||||
if ('=' != base64DataEx[0] && '=' != base64DataEx[1])
|
||||
{
|
||||
HGUInt t0 = base64Table_1[base64DataEx[0]];
|
||||
HGUInt t1 = base64Table_1[base64DataEx[1]];
|
||||
HGUInt t2 = base64Table_1[base64DataEx[2]];
|
||||
HGUInt t3 = base64Table_1[base64DataEx[3]];
|
||||
|
||||
if ('=' == base64DataEx[2] && '=' == base64DataEx[3])
|
||||
{
|
||||
originalDataEx[0] = ((t0 << 2) | (t1 >> 4)) & 0xFF;
|
||||
}
|
||||
else if ('=' != base64DataEx[2] && '=' == base64DataEx[3])
|
||||
{
|
||||
originalDataEx[0] = ((t0 << 2) | (t1 >> 4)) & 0xFF;
|
||||
originalDataEx[1] = ((t1 << 4) | (t2 >> 2)) & 0xFF;
|
||||
}
|
||||
else if ('=' != base64DataEx[2] && '=' != base64DataEx[3])
|
||||
{
|
||||
originalDataEx[0] = ((t0 << 2) | (t1 >> 4)) & 0xFF;
|
||||
originalDataEx[1] = ((t1 << 4) | (t2 >> 2)) & 0xFF;
|
||||
originalDataEx[2] = ((t2 << 6) | t3) & 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != originalSize)
|
||||
{
|
||||
HGSize numberOfCycles = (base64Size - 1) / 4;
|
||||
const HGByte* base64DataEx = base64Data + numberOfCycles * 4;
|
||||
|
||||
HGSize newSize = numberOfCycles * 3;
|
||||
|
||||
HGSize sizeOfRemaining = base64Size - numberOfCycles * 4;
|
||||
if (2 == sizeOfRemaining)
|
||||
{
|
||||
if ('=' != base64DataEx[0] && '=' != base64DataEx[1])
|
||||
{
|
||||
newSize += 1;
|
||||
}
|
||||
}
|
||||
else if (3 == sizeOfRemaining)
|
||||
{
|
||||
if ('=' != base64DataEx[0] && '=' != base64DataEx[1])
|
||||
{
|
||||
if ('=' == base64DataEx[2])
|
||||
{
|
||||
newSize += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
newSize += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (4 == sizeOfRemaining)
|
||||
{
|
||||
if ('=' != base64DataEx[0] && '=' != base64DataEx[1])
|
||||
{
|
||||
if ('=' == base64DataEx[2] && '=' == base64DataEx[3])
|
||||
{
|
||||
newSize += 1;
|
||||
}
|
||||
else if ('=' != base64DataEx[2] && '=' == base64DataEx[3])
|
||||
{
|
||||
newSize += 2;
|
||||
}
|
||||
else if ('=' != base64DataEx[2] && '=' != base64DataEx[3])
|
||||
{
|
||||
newSize += 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*originalSize = newSize;
|
||||
}
|
||||
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef __HGBASE64_H__
|
||||
#define __HGBASE64_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
/* Base64编码
|
||||
* 参数:
|
||||
* 1) originalData: in, 原始数据地址
|
||||
* 2) originalSize: in, 原始数据长度
|
||||
* 3) base64Data: out, base64地址
|
||||
* 4) base64Size: out, 编码后base64长度
|
||||
* 说明:
|
||||
* 1) 该函数的调用需要分两次,第一次base64Data为NULL,base64Size不为NULL, 获取编码后base64长度
|
||||
* 2) 分配足够的内存后,然后调用第二次,此时base64Data为分配的地址
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_Base64Encode(const HGByte* originalData, HGSize originalSize,
|
||||
HGByte* base64Data, HGSize* base64Size);
|
||||
|
||||
/* Base64解码
|
||||
* 参数:
|
||||
* 1) base64Data: in, base64地址
|
||||
* 2) base64Size: in, base64长度
|
||||
* 3) originalData: out, 原始数据地址
|
||||
* 4) originalSize: out, 解码后原始数据长度
|
||||
* 说明:
|
||||
* 1) 该函数的调用需要分两次,第一次originalData为NULL,originalSize不为NULL, 获取解码后原始数据长度
|
||||
* 2) 分配足够的内存后,然后调用第二次,此时originalData为分配的地址
|
||||
* 3) base64Data中的数据必须是标准Base64字符, 不能有其他字符,比如\r或\n等
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_Base64Decode(const HGByte* base64Data, HGSize base64Size,
|
||||
HGByte* originalData, HGSize* originalSize);
|
||||
|
||||
#endif /* __HGBASE64_H__ */
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef __HGBASEERR_H__
|
||||
#define __HGBASEERR_H__
|
||||
|
||||
/* 无错误 */
|
||||
#define HGBASE_ERR_OK 0x00000000L
|
||||
|
||||
/* 一般错误 */
|
||||
#define HGBASE_ERR_FAIL 0x00000001L
|
||||
|
||||
/* 内存不足 */
|
||||
#define HGBASE_ERR_OUTOFMEMORY 0x00000002L
|
||||
|
||||
/* 参数非法 */
|
||||
#define HGBASE_ERR_INVALIDARG 0x00000003L
|
||||
|
||||
/* 无访问权限 */
|
||||
#define HGBASE_ERR_ACCESSDENIED 0x00000004L
|
||||
|
||||
/* 数据非法 */
|
||||
#define HGBASE_ERR_INVALIDDATA 0x00000005L
|
||||
|
||||
/* 未实现 */
|
||||
#define HGBASE_ERR_NOTIMPL 0x00000006L
|
||||
|
||||
/* 不支持该功能 */
|
||||
#define HGBASE_ERR_NOTSUPPORT 0x00000007L
|
||||
|
||||
/* 超时 */
|
||||
#define HGBASE_ERR_TIMEOUT 0x00000008L
|
||||
|
||||
/* 文件不存在 */
|
||||
#define HGBASE_ERR_FILENOTEXIST 0x00000009L
|
||||
|
||||
/* 加载动态库失败 */
|
||||
#define HGBASE_ERR_LOADLIBRARY 0x0000000AL
|
||||
|
||||
/* 文件错误 */
|
||||
#define HGBASE_ERR_FILEERROR 0x0000000BL
|
||||
|
||||
#endif /* __HGBASEERR_H__ */
|
|
@ -0,0 +1,149 @@
|
|||
#include "HGBuffer.h"
|
||||
#include "HGInc.h"
|
||||
|
||||
struct HGBufferImpl
|
||||
{
|
||||
HGBufferImpl()
|
||||
{
|
||||
m_data = NULL;
|
||||
m_size = 0;
|
||||
m_alloc = HGFALSE;
|
||||
}
|
||||
|
||||
~HGBufferImpl()
|
||||
{
|
||||
if (m_alloc)
|
||||
{
|
||||
free(m_data);
|
||||
m_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
HGByte* m_data;
|
||||
HGUSize m_size;
|
||||
HGBool m_alloc;
|
||||
};
|
||||
|
||||
HGResult HGAPI HGBase_CreateBuffer(HGUSize size, HGBuffer* buffer)
|
||||
{
|
||||
if (0 == size || NULL == buffer)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGByte* data = (HGByte*)malloc(size);
|
||||
if (NULL == data)
|
||||
{
|
||||
return HGBASE_ERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
HGBufferImpl* bufferImpl = new HGBufferImpl;
|
||||
bufferImpl->m_data = data;
|
||||
bufferImpl->m_size = size;
|
||||
bufferImpl->m_alloc = HGTRUE;
|
||||
|
||||
*buffer = (HGBuffer)bufferImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_CreateBufferFromData(const HGByte* data, HGUSize size, HGBuffer* buffer)
|
||||
{
|
||||
if (NULL == data || 0 == size || NULL == buffer)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGByte* data2 = (HGByte*)malloc(size);
|
||||
if (NULL == data2)
|
||||
{
|
||||
return HGBASE_ERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
memcpy(data2, data, size);
|
||||
|
||||
HGBufferImpl* bufferImpl = new HGBufferImpl;
|
||||
bufferImpl->m_data = data2;
|
||||
bufferImpl->m_size = size;
|
||||
bufferImpl->m_alloc = HGTRUE;
|
||||
|
||||
*buffer = (HGBuffer)bufferImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_CreateBufferWithData(HGByte* data, HGUSize size, HGBuffer* buffer)
|
||||
{
|
||||
if (NULL == data || 0 == size || NULL == buffer)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGBufferImpl* bufferImpl = new HGBufferImpl;
|
||||
bufferImpl->m_data = data;
|
||||
bufferImpl->m_size = size;
|
||||
bufferImpl->m_alloc = HGFALSE;
|
||||
|
||||
*buffer = (HGBuffer)bufferImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_CloneBuffer(HGBuffer srcBuffer, HGBuffer* buffer)
|
||||
{
|
||||
if (NULL == srcBuffer || NULL == buffer)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGBufferImpl* srcBufferImpl = (HGBufferImpl*)srcBuffer;
|
||||
|
||||
HGByte* data = (HGByte*)malloc(srcBufferImpl->m_size);
|
||||
if (NULL == data)
|
||||
{
|
||||
return HGBASE_ERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
memcpy(data, srcBufferImpl->m_data, srcBufferImpl->m_size);
|
||||
|
||||
HGBufferImpl* bufferImpl = new HGBufferImpl;
|
||||
bufferImpl->m_data = data;
|
||||
bufferImpl->m_size = srcBufferImpl->m_size;
|
||||
bufferImpl->m_alloc = HGTRUE;
|
||||
|
||||
*buffer = (HGBuffer)bufferImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_DestroyBuffer(HGBuffer buffer)
|
||||
{
|
||||
if (NULL == buffer)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGBufferImpl* bufferImpl = (HGBufferImpl*)buffer;
|
||||
delete bufferImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetBufferData(HGBuffer buffer, HGByte** data)
|
||||
{
|
||||
if (NULL == buffer || NULL == data)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGBufferImpl* bufferImpl = (HGBufferImpl*)buffer;
|
||||
*data = bufferImpl->m_data;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetBufferSize(HGBuffer buffer, HGUSize* size)
|
||||
{
|
||||
if (NULL == buffer || NULL == size)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGBufferImpl* bufferImpl = (HGBufferImpl*)buffer;
|
||||
*size = bufferImpl->m_size;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
#ifndef __HGBUFFER_H__
|
||||
#define __HGBUFFER_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
HG_DECLARE_HANDLE(HGBuffer);
|
||||
|
||||
/* 创建新的缓冲区
|
||||
* 参数:
|
||||
* 1) size: in, 缓冲区大小, 单位字节
|
||||
* 2) buffer: out, 新缓冲区句柄
|
||||
* 说明:
|
||||
* 1) 内部会分配size字节大小的内存
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateBuffer(HGUSize size, HGBuffer* buffer);
|
||||
|
||||
/* 通过已有数据创建新的缓冲区
|
||||
* 参数:
|
||||
* 1) data: in, 已有的数据地址
|
||||
* 2) size: in, 已有的数据大小, 单位字节
|
||||
* 3) buffer: out, 新缓冲区句柄
|
||||
* 说明:
|
||||
* 1) 内部会分配size字节大小的内存, 新的缓冲区创建完成时, 会将data中的数据拷贝过去
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateBufferFromData(const HGByte* data, HGUSize size, HGBuffer* buffer);
|
||||
|
||||
/* 通过已有数据创建新的缓冲区(不分配内存, 不拷贝数据)
|
||||
* 参数:
|
||||
* 1) data: in, 已有的数据地址
|
||||
* 2) size: in, 已有的数据大小, 单位字节
|
||||
* 3) buffer: out, 新缓冲区句柄
|
||||
* 说明:
|
||||
* 1) 内部不会分配内存, 将直接使用原始数据
|
||||
* 2) 需保证缓冲区销毁前原始数据一直有效
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateBufferWithData(HGByte* data, HGUSize size, HGBuffer* buffer);
|
||||
|
||||
/* 通过现有缓冲区创建新的缓冲区
|
||||
* 参数:
|
||||
* 1) srcBuffer: in, 已有缓冲区
|
||||
* 2) buffer: out, 新缓冲区句柄
|
||||
* 说明:
|
||||
* 1) 内部会分配现有缓冲区的size字节大小的内存, 新缓冲区创建完成时, 会将现有缓冲区中的数据拷贝过去
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CloneBuffer(HGBuffer srcBuffer, HGBuffer* buffer);
|
||||
|
||||
/* 销毁缓冲区
|
||||
* 参数:
|
||||
* 1) buffer: in, 缓冲区句柄
|
||||
* 说明:
|
||||
* 1) 如果内部分配了内存, 销毁的时候会自动释放该内存
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_DestroyBuffer(HGBuffer buffer);
|
||||
|
||||
/* 获取缓冲区数据地址
|
||||
* 参数:
|
||||
* 1) buffer: in, 缓冲区句柄
|
||||
* 2) data: out, 数据地址
|
||||
* 说明:
|
||||
* 1) 如果内部分配了内存, 返回的是分配的内存地址
|
||||
* 2) 如果内部没有分配内存, 返回的则是原始数据的地址
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetBufferData(HGBuffer buffer, HGByte** data);
|
||||
|
||||
/* 获取缓冲区数据大小
|
||||
* 参数:
|
||||
* 1) buffer: in, 缓冲区句柄
|
||||
* 2) size: out, 数据长度
|
||||
* 说明:
|
||||
* 1) 如果内部分配了内存, 返回的是分配的内存大小
|
||||
* 2) 如果内部没有分配内存, 返回的则是原始数据的大小
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetBufferSize(HGBuffer buffer, HGUSize* size);
|
||||
|
||||
#endif /* __HGBUFFER_H__ */
|
|
@ -0,0 +1,78 @@
|
|||
#include "HGConsole.h"
|
||||
#include "HGInc.h"
|
||||
|
||||
struct HGConsoleImpl
|
||||
{
|
||||
HGConsoleImpl()
|
||||
{
|
||||
#if defined(HG_CMP_MSC)
|
||||
m_bAllocConsole = FALSE;
|
||||
m_hConsole = INVALID_HANDLE_VALUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
~HGConsoleImpl()
|
||||
{
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (INVALID_HANDLE_VALUE != m_hConsole)
|
||||
m_hConsole = INVALID_HANDLE_VALUE;
|
||||
if (m_bAllocConsole)
|
||||
{
|
||||
FreeConsole();
|
||||
m_bAllocConsole = FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
BOOL m_bAllocConsole;
|
||||
HANDLE m_hConsole;
|
||||
#endif
|
||||
};
|
||||
|
||||
HGResult HGAPI HGBase_OpenConsole(HGConsole* console)
|
||||
{
|
||||
if (NULL == console)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGConsoleImpl* consoleImpl = new HGConsoleImpl;
|
||||
#if defined(HG_CMP_MSC)
|
||||
consoleImpl->m_bAllocConsole = AllocConsole();
|
||||
consoleImpl->m_hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
#endif
|
||||
*console = (HGConsole)consoleImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_CloseConsole(HGConsole console)
|
||||
{
|
||||
if (NULL == console)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGConsoleImpl* consoleImpl = (HGConsoleImpl*)console;
|
||||
delete consoleImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_WriteConsole(HGConsole console, const HGChar* info)
|
||||
{
|
||||
if (NULL == console || NULL == info || '\0' == *info)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGConsoleImpl* consoleImpl = (HGConsoleImpl*)console;
|
||||
#if defined(HG_CMP_MSC)
|
||||
DWORD dwNumberOfCharsWritten;
|
||||
WriteConsoleA(consoleImpl->m_hConsole, info, (DWORD)strlen(info), &dwNumberOfCharsWritten, NULL);
|
||||
WriteConsoleA(consoleImpl->m_hConsole, "\r\n", (DWORD)strlen("\r\n"), &dwNumberOfCharsWritten, NULL);
|
||||
#else
|
||||
printf(info);
|
||||
printf("\n");
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef __HGCONSOLE_H__
|
||||
#define __HGCONSOLE_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
HG_DECLARE_HANDLE(HGConsole);
|
||||
|
||||
/* 开启控制台
|
||||
* 参数:
|
||||
* 1) log: out, 控制台句柄
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_OpenConsole(HGConsole *console);
|
||||
|
||||
/* 关闭控制台
|
||||
* 参数:
|
||||
* 1) log: in, 控制台句柄
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CloseConsole(HGConsole console);
|
||||
|
||||
/* 写控制台信息
|
||||
* 参数:
|
||||
* 1) log: in, 控制台句柄
|
||||
* 2) info: in, 信息, 一次一行, info无需加换行符
|
||||
* 说明:
|
||||
* 1) 该函数不是线程安全的, 在不同线程调用的时候, 需要加锁
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_WriteConsole(HGConsole console, const HGChar* info);
|
||||
|
||||
#endif /* __HGCONSOLE_H__ */
|
|
@ -0,0 +1,66 @@
|
|||
#include "HGCrash.h"
|
||||
#include "HGInc.h"
|
||||
#if defined(HG_CMP_MSC)
|
||||
#include <Dbghelp.h>
|
||||
#endif
|
||||
|
||||
static HGCrashFunc g_crashFunc = NULL;
|
||||
static HGPointer g_crashParam = NULL;
|
||||
#if defined(HG_CMP_MSC)
|
||||
static _EXCEPTION_POINTERS* g_exceptionInfo = NULL;
|
||||
#endif
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
static LONG WINAPI UnhandledExceptionFilterEx(struct _EXCEPTION_POINTERS* exceptionInfo)
|
||||
{
|
||||
g_exceptionInfo = exceptionInfo;
|
||||
if (NULL != g_crashFunc)
|
||||
g_crashFunc(exceptionInfo->ExceptionRecord->ExceptionAddress, g_crashParam);
|
||||
g_exceptionInfo = NULL;
|
||||
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
#endif
|
||||
|
||||
HGResult HGAPI HGBase_RegisterCrashFunc(HGCrashFunc func, HGPointer param)
|
||||
{
|
||||
if (NULL == func)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
g_crashFunc = func;
|
||||
g_crashParam = param;
|
||||
SetUnhandledExceptionFilter(UnhandledExceptionFilterEx);
|
||||
return HGBASE_ERR_OK;
|
||||
#else
|
||||
return HGBASE_ERR_NOTIMPL;
|
||||
#endif
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_MakeCrashFile(const HGChar* filePath)
|
||||
{
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (NULL == g_exceptionInfo)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
HANDLE hFile = CreateFileA(filePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (INVALID_HANDLE_VALUE == hFile)
|
||||
{
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
}
|
||||
|
||||
MINIDUMP_EXCEPTION_INFORMATION mdei;
|
||||
mdei.ThreadId = GetCurrentThreadId();
|
||||
mdei.ExceptionPointers = g_exceptionInfo;
|
||||
mdei.ClientPointers = TRUE;
|
||||
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &mdei, NULL, NULL);
|
||||
CloseHandle(hFile);
|
||||
return HGBASE_ERR_OK;
|
||||
#else
|
||||
return HGBASE_ERR_NOTIMPL;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef __HGCRASH_H__
|
||||
#define __HGCRASH_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
typedef void (HGAPI *HGCrashFunc)(HGPointer crashAddr, HGPointer param);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_RegisterCrashFunc(HGCrashFunc func, HGPointer param);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_MakeCrashFile(const HGChar *filePath);
|
||||
|
||||
#endif /* __HGCRASH_H__ */
|
|
@ -0,0 +1,146 @@
|
|||
#ifndef __HGDEF_H__
|
||||
#define __HGDEF_H__
|
||||
|
||||
/****************************************************************************
|
||||
* Platform Dependent Definitions and Typedefs *
|
||||
****************************************************************************/
|
||||
|
||||
/* Microsoft C/C++ Compiler */
|
||||
#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) || defined (_WINDOWS)
|
||||
|
||||
#define HG_CMP_MSC
|
||||
#if defined(_WIN64) || defined(WIN64)
|
||||
#define HG_64BIT
|
||||
#elif defined(_WIN32) || defined(WIN32)
|
||||
#define HG_32BIT
|
||||
#endif
|
||||
|
||||
/* Apple Compiler (which is GNU now) */
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
#define HG_CMP_XCODE
|
||||
#define HG_64BIT
|
||||
|
||||
/* GNU C/C++ Compiler */
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
#define HG_CMP_GNU
|
||||
#if defined(__alpha__) || defined(__ia64__) || defined(__ppc64__) || defined(__s390x__) || defined(__x86_64__)
|
||||
#define HG_64BIT
|
||||
#else
|
||||
#define HG_32BIT
|
||||
#endif
|
||||
|
||||
/* Unrecognized */
|
||||
#else
|
||||
|
||||
#error Unrecognized compiler
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* type defines */
|
||||
typedef void HGVoid;
|
||||
typedef char HGChar;
|
||||
typedef unsigned char HGByte;
|
||||
typedef short HGShort;
|
||||
typedef unsigned short HGUShort;
|
||||
typedef int HGInt;
|
||||
typedef unsigned int HGUInt;
|
||||
typedef long long HGLonglong;
|
||||
typedef unsigned long long HGULonglong;
|
||||
typedef void* HGPointer;
|
||||
typedef HGInt HGBool;
|
||||
typedef float HGFloat;
|
||||
typedef double HGDouble;
|
||||
#ifdef HG_64BIT
|
||||
typedef HGLonglong HGSize;
|
||||
typedef HGULonglong HGUSize;
|
||||
#else
|
||||
typedef HGInt HGSize;
|
||||
typedef HGUInt HGUSize;
|
||||
#endif
|
||||
|
||||
typedef HGUInt HGColor;
|
||||
|
||||
#define HG_MAKECOLOR(r, g, b, a) (HGColor)(((HGUInt)a << 24) | ((HGUInt)b << 16) | ((HGUInt)g << 8) | (HGUInt)r)
|
||||
#define HG_GETCOLOR_R(color) (HGUInt)((HGColor)color & 0xFF)
|
||||
#define HG_GETCOLOR_G(color) (HGUInt)(((HGColor)color >> 8) & 0xFF)
|
||||
#define HG_GETCOLOR_B(color) (HGUInt)(((HGColor)color >> 16) & 0xFF)
|
||||
#define HG_GETCOLOR_A(color) (HGUInt)(((HGColor)color >> 24) & 0xFF)
|
||||
|
||||
/* error code */
|
||||
typedef HGUInt HGResult;
|
||||
|
||||
#define HGTRUE 1
|
||||
#define HGFALSE 0
|
||||
|
||||
#ifndef HGMAX
|
||||
#define HGMAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef HGMIN
|
||||
#define HGMIN(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
#ifdef __cplusplus
|
||||
#define HGEXPORT extern "C"
|
||||
#else
|
||||
#define HGEXPORT
|
||||
#endif /* __cplusplus */
|
||||
#define HGAPI __stdcall
|
||||
#define HGAPIV __cdecl
|
||||
#else
|
||||
#ifdef __cplusplus
|
||||
#define HGEXPORT extern "C" __attribute ((visibility("default")))
|
||||
#else
|
||||
#define HGEXPORT __attribute ((visibility("default")))
|
||||
#endif /* __cplusplus */
|
||||
#define HGAPI
|
||||
#define HGAPIV
|
||||
#endif
|
||||
|
||||
#define HG_DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGInt left;
|
||||
HGInt top;
|
||||
HGInt right;
|
||||
HGInt bottom;
|
||||
}HGRect;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGFloat left;
|
||||
HGFloat top;
|
||||
HGFloat right;
|
||||
HGFloat bottom;
|
||||
}HGRectF;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGInt x;
|
||||
HGInt y;
|
||||
}HGPoint;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGFloat x;
|
||||
HGFloat y;
|
||||
}HGPointF;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif /* __HGDEF_H__ */
|
|
@ -0,0 +1,472 @@
|
|||
#include "HGDes.h"
|
||||
#include "HGInc.h"
|
||||
|
||||
/* 初始置换表IP */
|
||||
static HGByte IP_Table[64] =
|
||||
{
|
||||
57, 49, 41, 33, 25, 17, 9, 1,
|
||||
59, 51, 43, 35, 27, 19, 11, 3,
|
||||
61, 53, 45, 37, 29, 21, 13, 5,
|
||||
63, 55, 47, 39, 31, 23, 15, 7,
|
||||
56, 48, 40, 32, 24, 16, 8, 0,
|
||||
58, 50, 42, 34, 26, 18, 10, 2,
|
||||
60, 52, 44, 36, 28, 20, 12, 4,
|
||||
62, 54, 46, 38, 30, 22, 14, 6
|
||||
};
|
||||
|
||||
/* 逆初始置换表IP^-1 */
|
||||
static HGByte IP_1_Table[64] =
|
||||
{
|
||||
39, 7, 47, 15, 55, 23, 63, 31,
|
||||
38, 6, 46, 14, 54, 22, 62, 30,
|
||||
37, 5, 45, 13, 53, 21, 61, 29,
|
||||
36, 4, 44, 12, 52, 20, 60, 28,
|
||||
35, 3, 43, 11, 51, 19, 59, 27,
|
||||
34, 2, 42, 10, 50, 18, 58, 26,
|
||||
33, 1, 41, 9, 49, 17, 57, 25,
|
||||
32, 0, 40, 8, 48, 16, 56, 24
|
||||
};
|
||||
|
||||
/* 扩充置换表E */
|
||||
static HGByte E_Table[48] =
|
||||
{
|
||||
31, 0, 1, 2, 3, 4,
|
||||
3, 4, 5, 6, 7, 8,
|
||||
7, 8, 9,10, 11, 12,
|
||||
11, 12, 13, 14, 15, 16,
|
||||
15, 16, 17, 18, 19, 20,
|
||||
19, 20, 21, 22, 23, 24,
|
||||
23, 24, 25, 26, 27, 28,
|
||||
27, 28, 29, 30, 31, 0
|
||||
};
|
||||
|
||||
/* 置换函数P */
|
||||
static HGByte P_Table[32] =
|
||||
{
|
||||
15, 6, 19, 20, 28, 11, 27, 16,
|
||||
0, 14, 22, 25, 4, 17, 30, 9,
|
||||
1, 7, 23, 13, 31, 26, 2, 8,
|
||||
18, 12, 29, 5, 21, 10, 3, 24
|
||||
};
|
||||
|
||||
/* S盒 */
|
||||
static HGByte S[8][4][16] =
|
||||
{
|
||||
/* S1 */
|
||||
14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,
|
||||
0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,
|
||||
4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,
|
||||
15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13,
|
||||
|
||||
/* S2 */
|
||||
15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,
|
||||
3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,
|
||||
0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,
|
||||
13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9,
|
||||
|
||||
/* S3 */
|
||||
10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,
|
||||
13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,
|
||||
13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
|
||||
1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12,
|
||||
|
||||
/* S4 */
|
||||
7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,
|
||||
13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,
|
||||
10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,
|
||||
3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14,
|
||||
|
||||
/* S5 */
|
||||
2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,
|
||||
14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,
|
||||
4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
|
||||
11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3,
|
||||
|
||||
/* S6 */
|
||||
12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,
|
||||
10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,
|
||||
9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
|
||||
4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13,
|
||||
|
||||
/* S7 */
|
||||
4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,
|
||||
13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,
|
||||
1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
|
||||
6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12,
|
||||
|
||||
/* S8 */
|
||||
13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,
|
||||
1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,
|
||||
7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
|
||||
2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11
|
||||
};
|
||||
|
||||
/* 置换选择1 */
|
||||
static HGByte PC_1[56] =
|
||||
{
|
||||
56,48,40,32,24,16,8,
|
||||
0,57,49,41,33,25,17,
|
||||
9,1,58,50,42,34,26,
|
||||
18,10,2,59,51,43,35,
|
||||
62,54,46,38,30,22,14,
|
||||
6,61,53,45,37,29,21,
|
||||
13,5,60,52,44,36,28,
|
||||
20,12,4,27,19,11,3
|
||||
};
|
||||
|
||||
/* 置换选择2 */
|
||||
static HGByte PC_2[48] =
|
||||
{
|
||||
13,16,10,23,0,4,2,27,
|
||||
14,5,20,9,22,18,11,3,
|
||||
25,7,15,6,26,19,12,1,
|
||||
40,51,30,36,46,54,29,39,
|
||||
50,44,32,46,43,48,38,55,
|
||||
33,52,45,41,49,35,28,31
|
||||
};
|
||||
|
||||
/* 对左移次数的规定 */
|
||||
static HGByte MOVE_TIMES[16] = { 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1 };
|
||||
|
||||
|
||||
static int ByteToBit8(HGByte ch, HGByte bit[8])
|
||||
{
|
||||
for (int cnt = 0; cnt < 8; cnt++)
|
||||
{
|
||||
*(bit + cnt) = (ch >> cnt) & 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Bit8ToByte(const HGByte bit[8], HGByte* ch)
|
||||
{
|
||||
if (NULL == ch)
|
||||
return -1;
|
||||
|
||||
*ch = 0;
|
||||
for (int cnt = 0; cnt < 8; cnt++)
|
||||
{
|
||||
*ch |= *(bit + cnt) << cnt;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Byte8ToBit64(const HGByte ch[8], HGByte bit[64])
|
||||
{
|
||||
for (int cnt = 0; cnt < 8; cnt++)
|
||||
{
|
||||
ByteToBit8(*(ch + cnt), bit + (cnt << 3));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int Bit64ToByte8(HGByte bit[64], HGByte ch[8])
|
||||
{
|
||||
memset(ch, 0, 8);
|
||||
for (int cnt = 0; cnt < 8; cnt++)
|
||||
{
|
||||
Bit8ToByte(bit + (cnt << 3), ch + cnt);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 密钥置换1 */
|
||||
static int DES_PC1_Transform(HGByte key[64], HGByte tempbts[56])
|
||||
{
|
||||
for (int cnt = 0; cnt < 56; cnt++)
|
||||
{
|
||||
tempbts[cnt] = key[PC_1[cnt]];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 密钥置换2 */
|
||||
static int DES_PC2_Transform(HGByte key[56], HGByte tempbts[48])
|
||||
{
|
||||
for (int cnt = 0; cnt < 48; cnt++)
|
||||
{
|
||||
tempbts[cnt] = key[PC_2[cnt]];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 循环左移 */
|
||||
static int DES_ROL(HGByte data[56], int time)
|
||||
{
|
||||
HGByte temp[56];
|
||||
HGByte temp2[28];
|
||||
|
||||
/* 保存将要循环移动到右边的位 */
|
||||
memcpy(temp, data, time);
|
||||
memcpy(temp + time, data + 28, time);
|
||||
|
||||
/* 前28位移动 */
|
||||
//memcpy(data, data + time, 28 - time);
|
||||
memcpy(temp2, data + time, 28 - time);
|
||||
memcpy(data, temp2, 28 - time);
|
||||
memcpy(data + 28 - time, temp, time);
|
||||
|
||||
/* 后28位移动 */
|
||||
//memcpy(data + 28, data + 28 + time, 28 - time);
|
||||
memcpy(temp2, data + 28 + time, 28 - time);
|
||||
memcpy(data + 28, temp2, 28 - time);
|
||||
memcpy(data + 56 - time, temp + time, time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 生成子密钥 */
|
||||
static int DES_MakeSubKeys(HGByte key[64], HGByte subKeys[16][48])
|
||||
{
|
||||
HGByte temp[56];
|
||||
DES_PC1_Transform(key, temp); /* PC1置换 */
|
||||
|
||||
for (int cnt = 0; cnt < 16; cnt++)
|
||||
{
|
||||
/* 16轮跌代,产生16个子密钥 */
|
||||
DES_ROL(temp, MOVE_TIMES[cnt]); /* 循环左移 */
|
||||
DES_PC2_Transform(temp, subKeys[cnt]); /* PC2置换,产生子密钥 */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* IP置换 */
|
||||
static int DES_IP_Transform(HGByte data[64])
|
||||
{
|
||||
HGByte temp[64];
|
||||
for (int cnt = 0; cnt < 64; cnt++)
|
||||
{
|
||||
temp[cnt] = data[IP_Table[cnt]];
|
||||
}
|
||||
|
||||
memcpy(data, temp, 64);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* IP逆置换 */
|
||||
static int DES_IP_1_Transform(HGByte data[64])
|
||||
{
|
||||
HGByte temp[64];
|
||||
for (int cnt = 0; cnt < 64; cnt++)
|
||||
{
|
||||
temp[cnt] = data[IP_1_Table[cnt]];
|
||||
}
|
||||
|
||||
memcpy(data, temp, 64);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 扩展置换 */
|
||||
static int DES_E_Transform(HGByte data[48])
|
||||
{
|
||||
HGByte temp[48];
|
||||
for (int cnt = 0; cnt < 48; cnt++)
|
||||
{
|
||||
temp[cnt] = data[E_Table[cnt]];
|
||||
}
|
||||
|
||||
memcpy(data, temp, 48);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* P置换 */
|
||||
static int DES_P_Transform(HGByte data[32])
|
||||
{
|
||||
HGByte temp[32];
|
||||
for (int cnt = 0; cnt < 32; cnt++)
|
||||
{
|
||||
temp[cnt] = data[P_Table[cnt]];
|
||||
}
|
||||
|
||||
memcpy(data, temp, 32);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 异或 */
|
||||
static int DES_XOR(HGByte R[48], HGByte L[48], int count)
|
||||
{
|
||||
for (int cnt = 0; cnt < count; cnt++)
|
||||
{
|
||||
R[cnt] ^= L[cnt];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* S盒置换 */
|
||||
static int DES_SBOX(HGByte data[48])
|
||||
{
|
||||
for (int cnt = 0; cnt < 8; cnt++)
|
||||
{
|
||||
int cur1 = cnt * 6;
|
||||
int cur2 = cnt << 2;
|
||||
|
||||
/* 计算在S盒中的行与列 */
|
||||
int line = (data[cur1] << 1) + data[cur1 + 5];
|
||||
int row = (data[cur1 + 1] << 3) + (data[cur1 + 2] << 2) + (data[cur1 + 3] << 1) + data[cur1 + 4];
|
||||
int output = S[cnt][line][row];
|
||||
|
||||
/* 化为2进制 */
|
||||
data[cur2] = (output & 0X08) >> 3;
|
||||
data[cur2 + 1] = (output & 0X04) >> 2;
|
||||
data[cur2 + 2] = (output & 0X02) >> 1;
|
||||
data[cur2 + 3] = output & 0x01;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 交换 */
|
||||
static int DES_Swap(HGByte left[32], HGByte right[32])
|
||||
{
|
||||
HGByte temp[32];
|
||||
memcpy(temp, left, 32);
|
||||
memcpy(left, right, 32);
|
||||
memcpy(right, temp, 32);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 加密单个分组 */
|
||||
static int DES_EncryptBlock(HGByte plainBlock[8], HGByte subKeys[16][48], HGByte cipherBlock[8])
|
||||
{
|
||||
HGByte plainBits[64];
|
||||
HGByte copyRight[48];
|
||||
|
||||
Byte8ToBit64(plainBlock, plainBits);
|
||||
/* 初始置换(IP置换) */
|
||||
DES_IP_Transform(plainBits);
|
||||
|
||||
/* 16轮迭代 */
|
||||
for (int cnt = 0; cnt < 16; cnt++)
|
||||
{
|
||||
memcpy(copyRight, plainBits + 32, 32);
|
||||
|
||||
/* 将右半部分进行扩展置换,从32位扩展到48位 */
|
||||
DES_E_Transform(copyRight);
|
||||
/* 将右半部分与子密钥进行异或操作 */
|
||||
DES_XOR(copyRight, subKeys[cnt], 48);
|
||||
/* 异或结果进入S盒,输出32位结果 */
|
||||
DES_SBOX(copyRight);
|
||||
/* P置换 */
|
||||
DES_P_Transform(copyRight);
|
||||
/* 将明文左半部分与右半部分进行异或 */
|
||||
DES_XOR(plainBits, copyRight, 32);
|
||||
|
||||
if (cnt != 15)
|
||||
{
|
||||
/* 最终完成左右部的交换 */
|
||||
DES_Swap(plainBits, plainBits + 32);
|
||||
}
|
||||
}
|
||||
|
||||
/* 逆初始置换(IP^1置换) */
|
||||
DES_IP_1_Transform(plainBits);
|
||||
Bit64ToByte8(plainBits, cipherBlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* 解密单个分组 */
|
||||
|
||||
static int DES_DecryptBlock(HGByte cipherBlock[8], HGByte subKeys[16][48], HGByte plainBlock[8])
|
||||
{
|
||||
HGByte cipherBits[64];
|
||||
HGByte copyRight[48];
|
||||
|
||||
Byte8ToBit64(cipherBlock, cipherBits);
|
||||
/* 初始置换(IP置换) */
|
||||
DES_IP_Transform(cipherBits);
|
||||
|
||||
/* 16轮迭代 */
|
||||
for (int cnt = 15; cnt >= 0; cnt--)
|
||||
{
|
||||
memcpy(copyRight, cipherBits + 32, 32);
|
||||
|
||||
/* 将右半部分进行扩展置换,从32位扩展到48位 */
|
||||
DES_E_Transform(copyRight);
|
||||
/* 将右半部分与子密钥进行异或操作 */
|
||||
DES_XOR(copyRight, subKeys[cnt], 48);
|
||||
/* 异或结果进入S盒,输出32位结果 */
|
||||
DES_SBOX(copyRight);
|
||||
/* P置换 */
|
||||
DES_P_Transform(copyRight);
|
||||
/* 将明文左半部分与右半部分进行异或 */
|
||||
DES_XOR(cipherBits, copyRight, 32);
|
||||
|
||||
if (cnt != 0)
|
||||
{
|
||||
/* 最终完成左右部的交换 */
|
||||
DES_Swap(cipherBits, cipherBits + 32);
|
||||
}
|
||||
}
|
||||
|
||||
/* 逆初始置换(IP^1置换) */
|
||||
DES_IP_1_Transform(cipherBits);
|
||||
Bit64ToByte8(cipherBits, plainBlock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
HGResult HGAPI HGBase_DesEncrypt(HGByte* data, HGUInt size, const HGByte* key)
|
||||
{
|
||||
if (NULL == data || 0 == size || 0 != size % 8 || NULL == key)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGByte bKey[64];
|
||||
HGByte subKeys[16][48];
|
||||
HGByte plainBlock[8];
|
||||
|
||||
/* 将密钥转换为二进制流 */
|
||||
Byte8ToBit64(key, bKey);
|
||||
/* 生成子密钥 */
|
||||
DES_MakeSubKeys(bKey, subKeys);
|
||||
|
||||
HGByte* p = data;
|
||||
HGByte* pe = data + size;
|
||||
while (p < pe)
|
||||
{
|
||||
memcpy(plainBlock, p, 8);
|
||||
DES_EncryptBlock(plainBlock, subKeys, p);
|
||||
p += 8;
|
||||
}
|
||||
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_DesDecrypt(HGByte* data, HGUInt size, const HGByte* key)
|
||||
{
|
||||
if (NULL == data || 0 == size || 0 != size % 8 || NULL == key)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGByte bKey[64];
|
||||
HGByte subKeys[16][48];
|
||||
HGByte cipherBlock[8];
|
||||
|
||||
/* 将密钥转换为二进制流 */
|
||||
Byte8ToBit64(key, bKey);
|
||||
/* 生成子密钥 */
|
||||
DES_MakeSubKeys(bKey, subKeys);
|
||||
|
||||
HGByte* p = data;
|
||||
HGByte* pe = data + size;
|
||||
while (p < pe)
|
||||
{
|
||||
memcpy(cipherBlock, p, 8);
|
||||
DES_DecryptBlock(cipherBlock, subKeys, p);
|
||||
p += 8;
|
||||
}
|
||||
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef __HGDES_H__
|
||||
#define __HGDES_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
/* DES加密
|
||||
* 参数:
|
||||
* 1) data: in, out, 明文
|
||||
* 2) size: in, 明文尺寸, 必须是8的倍数
|
||||
* 3) key: in, 加密密钥, 为8字节数组
|
||||
* 说明:
|
||||
* 1) 加密后的密文会覆盖明文,如果需要保留明文,需要提前保存
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_DesEncrypt(HGByte* data, HGUInt size, const HGByte* key);
|
||||
|
||||
/* DES解密
|
||||
* 参数:
|
||||
* 1) data: in, out, 密文
|
||||
* 2) size: in, 密文尺寸, 必须是8的倍数
|
||||
* 3) key: in, 解密密钥, 为8字节数组
|
||||
* 说明:
|
||||
* 1) 解密后的明文会覆盖密文,如果需要保留密文,需要提前保存
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_DesDecrypt(HGByte* data, HGUInt size, const HGByte* key);
|
||||
|
||||
#endif /* __HGDES_H__ */
|
|
@ -0,0 +1,94 @@
|
|||
#include "HGDll.h"
|
||||
#include "HGInc.h"
|
||||
#include "HGInfo.h"
|
||||
#if !defined(HG_CMP_MSC)
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
struct HGDllImpl
|
||||
{
|
||||
HGDllImpl()
|
||||
{
|
||||
m_hDll = NULL;
|
||||
}
|
||||
|
||||
~HGDllImpl()
|
||||
{
|
||||
if (NULL != m_hDll)
|
||||
{
|
||||
#if !defined(HG_CMP_MSC)
|
||||
dlclose(m_hDll);
|
||||
#else
|
||||
FreeLibrary(m_hDll);
|
||||
#endif
|
||||
m_hDll = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
void* m_hDll;
|
||||
#else
|
||||
HMODULE m_hDll;
|
||||
#endif
|
||||
};
|
||||
|
||||
HGResult HGAPI HGBase_CreateDll(const HGChar* fileName, HGDll* dll)
|
||||
{
|
||||
if (NULL == fileName || NULL == dll)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
void* hDll = dlopen(fileName, RTLD_LAZY);
|
||||
if (NULL == hDll)
|
||||
{
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "HGBase_CreateDll: dlopen fail, %s dlerror=%s", fileName, dlerror());
|
||||
return HGBASE_ERR_LOADLIBRARY;
|
||||
}
|
||||
#else
|
||||
HMODULE hDll = LoadLibraryExA((const char *)fileName, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
|
||||
if (NULL == hDll)
|
||||
{
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "HGBase_CreateDll: LoadLibraryExA fail, %s GetLastError=%u", fileName, GetLastError());
|
||||
return HGBASE_ERR_LOADLIBRARY;
|
||||
}
|
||||
#endif
|
||||
HGDllImpl* dllImpl = new HGDllImpl;
|
||||
dllImpl->m_hDll = hDll;
|
||||
*dll = (HGDll)dllImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_DestroyDll(HGDll dll)
|
||||
{
|
||||
if (NULL == dll)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGDllImpl* dllImpl = (HGDllImpl*)dll;
|
||||
delete dllImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetDllProcAddress(HGDll dll, const HGChar* symbol, HGPointer* func)
|
||||
{
|
||||
if (NULL == dll || NULL == symbol || NULL == func)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGDllImpl* dllImpl = (HGDllImpl*)dll;
|
||||
#if !defined(HG_CMP_MSC)
|
||||
*func = dlsym(dllImpl->m_hDll, symbol);
|
||||
#else
|
||||
* func = GetProcAddress(dllImpl->m_hDll, (const char *)symbol);
|
||||
#endif
|
||||
if (NULL == *func)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#ifndef __HGDLL_H__
|
||||
#define __HGDLL_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
HG_DECLARE_HANDLE(HGDll);
|
||||
|
||||
/* 加载DLL
|
||||
* 参数:
|
||||
* 1) fileName: in, dll/so文件路径, 可以是绝对路径或相对路径
|
||||
* 2) dll: out, DLL句柄
|
||||
* 说明:
|
||||
* 1) 在windows系统上, fileName需要是GBK编码
|
||||
* 2) 在linux系统上, fileName需要是UTF8编码
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateDll(const HGChar* fileName, HGDll* dll);
|
||||
|
||||
/* 销毁DLL
|
||||
* 参数:
|
||||
* 1) dll: in, DLL句柄
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_DestroyDll(HGDll dll);
|
||||
|
||||
/* 查找函数地址
|
||||
* 参数:
|
||||
* 1) dll: in, DLL句柄
|
||||
* 2) symbol: in, 函数名
|
||||
* 3) func: out, 函数地址
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetDllProcAddress(HGDll dll, const HGChar* symbol, HGPointer* func);
|
||||
|
||||
#endif /* __HGDLL_H__ */
|
|
@ -0,0 +1,238 @@
|
|||
#include "HGEvent.h"
|
||||
#include "HGInc.h"
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
struct event_t
|
||||
{
|
||||
HGBool state;
|
||||
HGBool manual_reset;
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
};
|
||||
#endif
|
||||
|
||||
HGResult HGAPI HGBase_CreateEvent(HGBool manualReset, HGBool initState, HGEvent* event)
|
||||
{
|
||||
if (NULL == event)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
event_t* hEvent = new event_t;
|
||||
|
||||
hEvent->state = initState;
|
||||
hEvent->manual_reset = manualReset;
|
||||
if (0 != pthread_mutex_init(&hEvent->mutex, NULL))
|
||||
{
|
||||
delete hEvent;
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
if (0 != pthread_cond_init(&hEvent->cond, NULL))
|
||||
{
|
||||
pthread_mutex_destroy(&hEvent->mutex);
|
||||
delete hEvent;
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
*event = (HGEvent)hEvent;
|
||||
#else
|
||||
HANDLE hEvent = CreateEventW(NULL, (BOOL)manualReset, (BOOL)initState, NULL);
|
||||
*event = (HGEvent)hEvent;
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_DestroyEvent(HGEvent event)
|
||||
{
|
||||
if (NULL == event)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
event_t* hEvent = (event_t*)event;
|
||||
pthread_cond_destroy(&hEvent->cond);
|
||||
pthread_mutex_destroy(&hEvent->mutex);
|
||||
delete hEvent;
|
||||
#else
|
||||
HANDLE hEvent = (HANDLE)event;
|
||||
CloseHandle(hEvent);
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_WaitEvent(HGEvent event)
|
||||
{
|
||||
if (NULL == event)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
event_t* hEvent = (event_t*)event;
|
||||
if (0 != pthread_mutex_lock(&hEvent->mutex))
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
while (!hEvent->state)
|
||||
{
|
||||
if (0 != pthread_cond_wait(&hEvent->cond, &hEvent->mutex))
|
||||
{
|
||||
pthread_mutex_unlock(&hEvent->mutex);
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
}
|
||||
if (!hEvent->manual_reset)
|
||||
{
|
||||
hEvent->state = HGFALSE;
|
||||
}
|
||||
if (0 != pthread_mutex_unlock(&hEvent->mutex))
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
#else
|
||||
HANDLE hEvent = (HANDLE)event;
|
||||
DWORD ret = WaitForSingleObject(hEvent, INFINITE);
|
||||
if (WAIT_OBJECT_0 != ret)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_WaitEventTimeout(HGEvent event, HGUInt milliseconds)
|
||||
{
|
||||
if (NULL == event)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
struct timespec abstime;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
abstime.tv_sec = tv.tv_sec + milliseconds / 1000;
|
||||
abstime.tv_nsec = tv.tv_usec * 1000 + (milliseconds % 1000) * 1000000;
|
||||
if (abstime.tv_nsec >= 1000000000)
|
||||
{
|
||||
abstime.tv_nsec -= 1000000000;
|
||||
abstime.tv_sec++;
|
||||
}
|
||||
|
||||
int rc = 0;
|
||||
event_t* hEvent = (event_t*)event;
|
||||
if (pthread_mutex_lock(&hEvent->mutex) != 0)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
while (!hEvent->state)
|
||||
{
|
||||
rc = pthread_cond_timedwait(&hEvent->cond, &hEvent->mutex, &abstime);
|
||||
if (0 != rc)
|
||||
{
|
||||
if (rc == ETIMEDOUT)
|
||||
break;
|
||||
|
||||
pthread_mutex_unlock(&hEvent->mutex);
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
}
|
||||
if (rc == 0 && !hEvent->manual_reset)
|
||||
{
|
||||
hEvent->state = HGFALSE;
|
||||
}
|
||||
if (pthread_mutex_unlock(&hEvent->mutex) != 0)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
if (rc == ETIMEDOUT)
|
||||
{
|
||||
return HGBASE_ERR_TIMEOUT;
|
||||
}
|
||||
return HGBASE_ERR_OK;
|
||||
#else
|
||||
HANDLE hEvent = (HANDLE)event;
|
||||
DWORD ret = WaitForSingleObject(hEvent, milliseconds);
|
||||
if (WAIT_OBJECT_0 == ret)
|
||||
{
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
else if (WAIT_TIMEOUT == ret)
|
||||
{
|
||||
return HGBASE_ERR_TIMEOUT;
|
||||
}
|
||||
return HGBASE_ERR_FAIL;
|
||||
#endif
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_SetEvent(HGEvent event)
|
||||
{
|
||||
if (NULL == event)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
event_t* hEvent = (event_t*)event;
|
||||
if (0 != pthread_mutex_lock(&hEvent->mutex))
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
hEvent->state = HGTRUE;
|
||||
if (hEvent->manual_reset)
|
||||
{
|
||||
if (0 != pthread_cond_broadcast(&hEvent->cond))
|
||||
{
|
||||
pthread_mutex_unlock(&hEvent->mutex);
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 != pthread_cond_signal(&hEvent->cond))
|
||||
{
|
||||
pthread_mutex_unlock(&hEvent->mutex);
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != pthread_mutex_unlock(&hEvent->mutex))
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
return HGBASE_ERR_OK;
|
||||
#else
|
||||
HANDLE hEvent = (HANDLE)event;
|
||||
SetEvent(hEvent);
|
||||
return HGBASE_ERR_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_ResetEvent(HGEvent event)
|
||||
{
|
||||
if (NULL == event)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
event_t* hEvent = (event_t*)event;
|
||||
if (0 != pthread_mutex_lock(&hEvent->mutex))
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
hEvent->state = HGFALSE;
|
||||
if (0 != pthread_mutex_unlock(&hEvent->mutex))
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
return HGBASE_ERR_OK;
|
||||
#else
|
||||
HANDLE hEvent = (HANDLE)event;
|
||||
ResetEvent(hEvent);
|
||||
return HGBASE_ERR_OK;
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef __HGEVENT_H__
|
||||
#define __HGEVENT_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
HG_DECLARE_HANDLE(HGEvent);
|
||||
|
||||
/* 创建事件
|
||||
* 参数:
|
||||
* 1) manualReset: in, 是否手动设置
|
||||
* 2) initState: in, 初始化时是否有信号
|
||||
* 3) event: out, 事件句柄
|
||||
* 说明:
|
||||
* 1) 当manualReset为HGTRUE时, HGBase_WaitEvent和HGBase_WaitEventTimeout调用后, 事件仍然为有信号
|
||||
* 2) 当manualReset为HGFALSE时, HGBase_WaitEvent和HGBase_WaitEventTimeout调用后, 事件为无信号
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateEvent(HGBool manualReset, HGBool initState, HGEvent* event);
|
||||
|
||||
/* 销毁事件
|
||||
* 参数:
|
||||
* 1) event: in, 事件句柄
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_DestroyEvent(HGEvent event);
|
||||
|
||||
/* 无限等待事件
|
||||
* 参数:
|
||||
* 1) event: in, 事件句柄
|
||||
* 说明:
|
||||
* 1) 如果创建时的manualReset为HGTRUE, 返回前不会将事件置为无信号;否则,返回前会将事件置为无信号
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_WaitEvent(HGEvent event);
|
||||
|
||||
/* 等待事件, 带超时时间
|
||||
* 参数:
|
||||
* 1) event: in, 事件句柄
|
||||
* 2) milliseconds: in, 超时时间, 毫秒
|
||||
* 说明:
|
||||
* 1) 在milliseconds时间内如果事件有信号,立即返回
|
||||
* 2) 如果一直无信号, 在milliseconds毫秒后也立即返回, 返回值为HGBASE_ERR_WAIT_TIMEOUT
|
||||
* 3) 如果创建时的manualReset为HGTRUE, 返回前不会将事件置为无信号;否则,返回前会将事件置为无信号
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_WaitEventTimeout(HGEvent event, HGUInt milliseconds);
|
||||
|
||||
/* 使事件有信号
|
||||
* 参数:
|
||||
* 1) event: in, 事件句柄
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_SetEvent(HGEvent event);
|
||||
|
||||
/* 使事件无信号
|
||||
* 参数:
|
||||
* 1) event: in, 事件句柄
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_ResetEvent(HGEvent event);
|
||||
|
||||
#endif /* __HGEVENT_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,391 @@
|
|||
#ifndef __HGIMAGE_H__
|
||||
#define __HGIMAGE_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
#if defined(HG_CMP_MSC)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
HG_DECLARE_HANDLE(HGImage);
|
||||
|
||||
/* 1位黑白图 */
|
||||
#define HGBASE_IMGTYPE_BINARY 1L
|
||||
/* 8位灰度图 */
|
||||
#define HGBASE_IMGTYPE_GRAY 2L
|
||||
/* 24位真彩色,B8G8R8格式 */
|
||||
#define HGBASE_IMGTYPE_BGR 3L
|
||||
/* 24位真彩色,R8G8B8格式 */
|
||||
#define HGBASE_IMGTYPE_RGB 4L
|
||||
/* 32位真彩色,带Alpha通道,B8G8R8A8格式 */
|
||||
#define HGBASE_IMGTYPE_BGRA 5L
|
||||
/* 32位真彩色,带Alpha通道,R8G8B8A8格式 */
|
||||
#define HGBASE_IMGTYPE_RGBA 6L
|
||||
|
||||
/* 顶左结构 */
|
||||
#define HGBASE_IMGORIGIN_TOP 1L
|
||||
/* 底左结构 */
|
||||
#define HGBASE_IMGORIGIN_BOTTOM 2L
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
|
||||
/* 图像信息 */
|
||||
typedef struct
|
||||
{
|
||||
HGUInt width; /* 宽(像素),列数 */
|
||||
HGUInt height; /* 高(像素),行数 */
|
||||
HGUInt type; /* 类型,参见HGBASE_IMGTYPE_* */
|
||||
HGUInt widthStep; /* 每行的字节数 */
|
||||
HGUInt origin; /* 数据排列方式,参见HGBASE_IMGORIGIN_* */
|
||||
}HGImageInfo;
|
||||
|
||||
/* 图像感兴趣区域 */
|
||||
typedef struct
|
||||
{
|
||||
HGUInt left;
|
||||
HGUInt top;
|
||||
HGUInt right;
|
||||
HGUInt bottom;
|
||||
}HGImageRoi;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
/* 创建空白的新图像
|
||||
* 参数:
|
||||
* 1) width: in, 新图像宽度
|
||||
* 2) height: in, 新图像高度
|
||||
* 3) type: in, 新图像类型
|
||||
* 4) origin: in, 新图像的数据排列方式
|
||||
* 5) image: out,新图像句柄
|
||||
* 说明:
|
||||
* 1)在windows系统上,当type为HGBASE_IMGTYPE_BINARY、HGBASE_IMGTYPE_GRAY、HGBASE_IMGTYPE_BGR或HGBASE_IMGTYPE_BGRA时,新图像内部实际创建DIB位图(有HBITMAP),
|
||||
* 否则内部分配普通内存(无HBITMAP); 在linux系统上,新图像内部分配普通内存(无HBITMAP)
|
||||
* 2) 新图像的width=width; 新图像的height=height; 新图像的type=type; 新图像的widthStep为4字节对齐; 新图像的origin=origin
|
||||
* 3) 新图像的roi为{0, 0, width, height}
|
||||
* 4) 新图像的xdpi=96, ydpi=96
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateImage(HGUInt width, HGUInt height, HGUInt type, HGUInt origin, HGImage* image);
|
||||
|
||||
/* 从源数据创建新图像(不分配内存, 也不拷贝数据)
|
||||
* 参数:
|
||||
* 1) data: in, 源数据的地址
|
||||
* 2) info: in, 源数据的图像信息
|
||||
* 3) image: out,新图像句柄
|
||||
* 说明:
|
||||
* 1) 新图像内部不会分配普通像素内存,也不会创建DIB位图(windows系统上, 无HBITMAP),而是直接使用源数据, 在该图像销毁之前需要保证源数据一直有效
|
||||
* 2) 新图像的width=info->width; 新图像的height=info->height; 新图像的type=info->type; 新图像的widthStep=info->widthStep;
|
||||
* 新图像的origin=info->origin
|
||||
* 3) 新图像的roi为{0, 0, width, height}
|
||||
* 4) 新图像的xdpi=96, ydpi=96
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateImageWithData(HGByte* data, const HGImageInfo* info, HGImage* image);
|
||||
|
||||
/* 从源数据创建新图像
|
||||
* 参数:
|
||||
* 1) data: in, 源数据的地址
|
||||
* 2) info: in, 源数据的图像信息
|
||||
* 3) roi: in, 源数据的感兴趣区域, NULL表示整个图像区域
|
||||
* 4) type: in, 新图像的类型, 0表示和源数据一样
|
||||
* 5) origin: in, 新图像的数据排列方式, 0表示和源数据一样
|
||||
* 6) image: out,新图像句柄
|
||||
* 说明:
|
||||
* 1)在windows系统上,当type为HGBASE_IMGTYPE_BINARY、HGBASE_IMGTYPE_GRAY、HGBASE_IMGTYPE_BGR或HGBASE_IMGTYPE_BGRA时,新图像内部实际创建DIB位图(有HBITMAP),
|
||||
* 否则内部分配普通内存(无HBITMAP); 在linux系统上,新图像内部分配普通内存(无HBITMAP)
|
||||
* 2) 新图像的width=roi->right-roi->left; 新图像的height=roi->bottom-roi->top; 新图像的type=type; 新图像的widthStep为4字节对齐;
|
||||
* 新图像的origin=origin, 如果origin和info->origin不一致,拷贝时像素会进行上下翻转
|
||||
* 3) 新图像的roi为{0, 0, width, height}
|
||||
* 4) 新图像的xdpi=96, ydpi=96
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateImageFromData(HGByte* data, const HGImageInfo *info, const HGImageRoi *roi,
|
||||
HGUInt type, HGUInt origin, HGImage* image);
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
|
||||
/* 从DIB位图创建新图像
|
||||
* 参数:
|
||||
* 1) hBmp: in, DIB位图句柄
|
||||
* 2) roi: DIB位图的感兴趣区域, NULL表示整个图像区域
|
||||
* 3) type: in, 新图像的类型, 0表示自动生成和DIB位图最接近的type
|
||||
* 4) origin: in, 新图像的数据排列方式, 必须指定
|
||||
* 5) image: out,新图像句柄
|
||||
* 说明:
|
||||
* 1)当type为HGBASE_IMGTYPE_BINARY、HGBASE_IMGTYPE_GRAY、HGBASE_IMGTYPE_BGR或HGBASE_IMGTYPE_BGRA时,新图像内部实际创建DIB位图(有HBITMAP),
|
||||
* 否则内部分配普通内存(无HBITMAP)
|
||||
* 2) 新图像的width=roi->right-roi->left; 新图像的height=roi->bottom-roi->top; 新图像的type=type; 新图像的widthStep为4字节对齐;
|
||||
* 新图像的origin=origin
|
||||
* 3) 新图像的roi为{0, 0, width, height}
|
||||
* 4) 新图像的xdpi=hBmp的xDPI, ydpi=hBmp的yDPI
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateImageFromHBITMAP(HBITMAP hBmp, const HGImageRoi* roi,
|
||||
HGUInt type, HGUInt origin, HGImage* image);
|
||||
|
||||
/* 从DIB内存创建新图像
|
||||
* 参数:
|
||||
* 1) hMem: in, DIB内存句柄
|
||||
* 2) roi: DIB内存的感兴趣区域, NULL表示整个图像区域
|
||||
* 3) type: in, 新图像的类型, 0表示自动生成和DIB内存最接近的type
|
||||
* 4) origin: in, 新图像的数据排列方式, 必须指定
|
||||
* 5) image: out,新图像句柄
|
||||
* 说明:
|
||||
* 1)当type为HGBASE_IMGTYPE_BINARY、HGBASE_IMGTYPE_GRAY、HGBASE_IMGTYPE_BGR或HGBASE_IMGTYPE_BGRA时,新图像内部实际创建DIB位图(有HBITMAP),
|
||||
* 否则内部分配普通内存(无HBITMAP)
|
||||
* 2) 新图像的width=roi->right-roi->left; 新图像的height=roi->bottom-roi->top; 新图像的type=type; 新图像的widthStep为4字节对齐;
|
||||
* 新图像的origin=origin
|
||||
* 3) 新图像的roi为{0, 0, width, height}
|
||||
* 4) 新图像的xdpi=DIB的xDPI, ydpi=DIB的yDPI
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateImageFromDIB(HGLOBAL hMem, const HGImageRoi* roi,
|
||||
HGUInt type, HGUInt origin, HGImage* image);
|
||||
|
||||
#endif /* HG_CMP_MSC */
|
||||
|
||||
/* 从源图像创建新图像
|
||||
* 参数:
|
||||
* 1) srcImage: in, 源图像
|
||||
* 2) type: in, 新图像的类型, 0表示和源图像一样
|
||||
* 3) origin: in, 新图像的数据排列方式, 0表示和源图像一样
|
||||
* 4) image: out,新图像句柄
|
||||
* 说明:
|
||||
* 1)在windows系统上,当type为HGBASE_IMGTYPE_BINARY、HGBASE_IMGTYPE_GRAY、HGBASE_IMGTYPE_BGR或HGBASE_IMGTYPE_BGRA时,新图像内部实际创建DIB位图(有HBITMAP),
|
||||
* 否则内部分配普通内存(无HBITMAP); 在linux系统上,新图像内部分配普通内存(无HBITMAP)
|
||||
* 2) 新图像的width=srcImage->roi.right-srcImage->roi.left; 新图像的height=srcImage->roi.bottom-srcImage->roi.top;
|
||||
* 新图像的type=type; 新图像的widthStep为4字节对齐; 新图像的origin=origin, 如果origin和srcImage->origin不一致,拷贝时像素会进行上下翻转
|
||||
* 3) 新图像的roi为{0, 0, width, height}
|
||||
* 4) 新图像的xdpi=srcImage->xdpi, ydpi=srcImage->ydpi
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CloneImage(HGImage srcImage, HGUInt type, HGUInt origin, HGImage* image);
|
||||
|
||||
/* 销毁图像
|
||||
* 参数:
|
||||
* 1) image: in, 图像句柄
|
||||
* 说明:
|
||||
* 1) 如果图像内部分配了像素内存, 销毁图像的同时会自动释放
|
||||
* 2) 如果图像内部创建了DIB位图(windows上), 销毁图像的同时会自动调用DeleteObject进行销毁
|
||||
* 3) 如果图像内存没有分配内存,也没有创建DIB位图,而是直接使用源数据,销毁图像后源数据才可以释放
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_DestroyImage(HGImage image);
|
||||
|
||||
/* 获取图像数据地址
|
||||
* 参数:
|
||||
* 1) image: in, 图像句柄
|
||||
* 2) data: out, 数据地址
|
||||
* 说明:
|
||||
* 1) 如果图像内部分配了内存, 返回的是分配的内存地址
|
||||
* 2) 如果图像内部创建了DIB位图,返回的是DIB位图像素数据的内存地址
|
||||
* 3) 否则,返回的是源数据地址
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetImageData(HGImage image, HGByte** data);
|
||||
|
||||
/* 获取图像信息
|
||||
* 参数:
|
||||
* 1) image: in, 图像句柄
|
||||
* 2) info: out, 图像信息
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetImageInfo(HGImage image, HGImageInfo* info);
|
||||
|
||||
/* 获取图像感兴趣区域
|
||||
* 参数:
|
||||
* 1) image: in, 图像句柄
|
||||
* 2) roi: out, 图像感兴趣区域
|
||||
* 说明:
|
||||
* 1) 默认的感兴趣区域整张图, 即left=0,top=0,right=width,bottom=height
|
||||
* 2) 图像算法模块可以仅处理感兴趣区域
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetImageROI(HGImage image, HGImageRoi* roi);
|
||||
|
||||
/* 设置图像感兴趣区域
|
||||
* 参数:
|
||||
* 1) image: in, 图像句柄
|
||||
* 2) roi: in, 图像感兴趣区域
|
||||
* 说明:
|
||||
* 1) roi所指定的区域必须是整个图像幅面的子集
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_SetImageROI(HGImage image, const HGImageRoi* roi);
|
||||
|
||||
/* 重置图像感兴趣区域
|
||||
* 参数:
|
||||
* 1) image: in, 图像句柄
|
||||
* 说明:
|
||||
* 1) 默认的感兴趣区域整张图, 即left=0,top=0,right=width,bottom=height
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_ResetImageROI(HGImage image);
|
||||
|
||||
/* 获取图像DPI
|
||||
* 参数:
|
||||
* 1) image: in, 图像句柄
|
||||
* 2) xDpi: out, xdpi
|
||||
* 3) yDpi: out, ydpi
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetImageDpi(HGImage image, HGUInt *xDpi, HGUInt* yDpi);
|
||||
|
||||
/* 设置图像DPI
|
||||
* 参数:
|
||||
* 1) image: in, 图像句柄
|
||||
* 2) xDpi: in, xdpi
|
||||
* 3) yDpi: in, ydpi
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_SetImageDpi(HGImage image, HGUInt xDpi, HGUInt yDpi);
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
|
||||
/* 获取图像内部的DIB位图句柄
|
||||
* 参数:
|
||||
* 1) image: in, 图像句柄
|
||||
* 2) hBmp: out, DIB位图句柄
|
||||
* 说明:
|
||||
* 1) 该函数只对windows平台有效
|
||||
* 2) 返回的HBITMAP不能用DeleteObject销毁
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetHBITMAPOfImage(HGImage image, HBITMAP *hBmp);
|
||||
|
||||
/* 创建DIB位图
|
||||
* 参数:
|
||||
* 1) image: in, 图像句柄
|
||||
* 2) hBmp: out, DIB位图句柄
|
||||
* 说明:
|
||||
* 1) 该函数只对windows平台有效
|
||||
* 2) 返回的hBmp必须用DeleteObject销毁
|
||||
* 3) 操作的只是图像的ROI区域
|
||||
* 4) HGBASE_IMGTYPE_RGB会自动转为BGR排列, HGBASE_IMGTYPE_RGBA会自动转为BGRA排列
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateHBITMAPFromImage(HGImage image, HBITMAP* hBmp);
|
||||
|
||||
/* 创建DIB内存
|
||||
* 参数:
|
||||
* 1) image: in, 图像句柄
|
||||
* 2) hMem: out, DIB内存句柄
|
||||
* 说明:
|
||||
* 1) 该函数只对windows平台有效
|
||||
* 2) 返回的hMem必须用GlobalFree销毁
|
||||
* 3) 操作的只是图像的ROI区域
|
||||
* 4) HGBASE_IMGTYPE_RGB会自动转为BGR排列, HGBASE_IMGTYPE_RGBA会自动转为BGRA排列
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateDIBFromImage(HGImage image, HGLOBAL* hMem);
|
||||
|
||||
#endif /* HG_CMP_MSC */
|
||||
|
||||
/* 图像左右镜像
|
||||
* 参数:
|
||||
* 1) image: in, 源图像句柄
|
||||
* 2) destImage: in, 目标图像句柄
|
||||
* 说明:
|
||||
* 1) 操作的只是图像的ROI区域, 源图像和目标图像的ROI大小必须一样
|
||||
* 2) 源图像和目标图像的type必须一样
|
||||
* 3) 自动处理origon不一致的情况
|
||||
* 4) image和destImage可以是同一个句柄
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_ImageMirror(HGImage image, HGImage destImage);
|
||||
|
||||
/* 图像上下镜像
|
||||
* 参数:
|
||||
* 1) image: in, 源图像句柄
|
||||
* 2) destImage: in, 目标图像句柄
|
||||
* 说明:
|
||||
* 1) 操作的只是图像的ROI区域, 源图像和目标图像的ROI大小必须一样
|
||||
* 2) 源图像和目标图像的type必须一样
|
||||
* 3) 自动处理origon不一致的情况
|
||||
* 4) image和destImage可以是同一个句柄
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_ImageFlip(HGImage image, HGImage destImage);
|
||||
|
||||
/* 图像左转
|
||||
* 参数:
|
||||
* 1) image: in, 源图像句柄
|
||||
* 2) destImage: in, 目标图像句柄
|
||||
* 说明:
|
||||
* 1) 操作的只是图像的ROI区域, 源图像和目标图像的ROI大小必须宽高互反
|
||||
* 2) 源图像和目标图像的type必须一样
|
||||
* 3) 自动处理origon不一致的情况
|
||||
* 4) image和destImage不能是同一个句柄
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_ImageRotateLeft(HGImage image, HGImage destImage);
|
||||
|
||||
/* 图像右转
|
||||
* 参数:
|
||||
* 1) image: in, 源图像句柄
|
||||
* 2) destImage: in, 目标图像句柄
|
||||
* 说明:
|
||||
* 1) 操作的只是图像的ROI区域, 源图像和目标图像的ROI大小必须宽高互反
|
||||
* 2) 源图像和目标图像的type必须一样
|
||||
* 3) 自动处理origon不一致的情况
|
||||
* 4) image和destImage不能是同一个句柄
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_ImageRotateRight(HGImage image, HGImage destImage);
|
||||
|
||||
/* 图像左转后再左右镜像
|
||||
* 参数:
|
||||
* 1) image: in, 源图像句柄
|
||||
* 2) destImage: in, 目标图像句柄
|
||||
* 说明:
|
||||
* 1) 操作的只是图像的ROI区域, 源图像和目标图像的ROI大小必须宽高互反
|
||||
* 2) 源图像和目标图像的type必须一样
|
||||
* 3) 自动处理origon不一致的情况
|
||||
* 4) image和destImage不能是同一个句柄
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_ImageRotateLeftMirror(HGImage image, HGImage destImage);
|
||||
|
||||
/* 图像右转后再左右镜像
|
||||
* 参数:
|
||||
* 1) image: in, 源图像句柄
|
||||
* 2) destImage: in, 目标图像句柄
|
||||
* 说明:
|
||||
* 1) 操作的只是图像的ROI区域, 源图像和目标图像的ROI大小必须宽高互反
|
||||
* 2) 源图像和目标图像的type必须一样
|
||||
* 3) 自动处理origon不一致的情况
|
||||
* 4) image和destImage不能是同一个句柄
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_ImageRotateRightMirror(HGImage image, HGImage destImage);
|
||||
|
||||
/* 图像旋转180度
|
||||
* 参数:
|
||||
* 1) image: in, 源图像句柄
|
||||
* 2) destImage: in, 目标图像句柄
|
||||
* 说明:
|
||||
* 1) 操作的只是图像的ROI区域, 源图像和目标图像的ROI大小必须一样
|
||||
* 2) 源图像和目标图像的type必须一样
|
||||
* 3) 自动处理origon不一致的情况
|
||||
* 4) image和destImage可以是同一个句柄
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_ImageRotate180(HGImage image, HGImage destImage);
|
||||
|
||||
/* 图像灰度化
|
||||
* 参数:
|
||||
* 1) image: in, 源图像句柄
|
||||
* 2) destImage: in, 目标图像句柄
|
||||
* 说明:
|
||||
* 1) 操作的只是图像的ROI区域, 源图像和目标图像的ROI大小必须一样
|
||||
* 2) 源图像和目标图像的type必须一样
|
||||
* 3) 自动处理origon不一致的情况
|
||||
* 4) image和destImage可以是同一个句柄
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_ImageGrayscale(HGImage image, HGImage destImage);
|
||||
|
||||
/* 图像反色
|
||||
* 参数:
|
||||
* 1) image: in, 源图像句柄
|
||||
* 2) destImage: in, 目标图像句柄
|
||||
* 说明:
|
||||
* 1) 操作的只是图像的ROI区域, 源图像和目标图像的ROI大小必须一样
|
||||
* 2) 源图像和目标图像的type必须一样
|
||||
* 3) 自动处理origon不一致的情况
|
||||
* 4) image和destImage可以是同一个句柄
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_ReverseImage(HGImage image, HGImage destImage);
|
||||
|
||||
/* 拷贝图像
|
||||
* 参数:
|
||||
* 1) image: in, 源图像句柄
|
||||
* 2) destImage: in, 目标图像句柄
|
||||
* 说明:
|
||||
* 1) 操作的只是图像的ROI区域, 源图像和目标图像的ROI大小必须一样
|
||||
* 2) 拷贝的时候会自动处理type不一致的情况
|
||||
* 3) 拷贝的时候自动处理origin不一致的情况
|
||||
* 4) image和destImage不能是同一个图像句柄
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CopyImage(HGImage image, HGImage destImage);
|
||||
|
||||
#endif /* __HGIMAGE_H__ */
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef __HGINC_H__
|
||||
#define __HGINC_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/timeb.h>
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <setjmp.h>
|
||||
#include <malloc.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
#include <windows.h>
|
||||
#include <WinSock2.h>
|
||||
#include <io.h>
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <dlfcn.h>
|
||||
#include <fcntl.h>
|
||||
#include <iconv.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <dirent.h>
|
||||
#endif
|
||||
|
||||
#endif /* __HGINC_H__ */
|
|
@ -0,0 +1,35 @@
|
|||
#include "HGInfo.h"
|
||||
#include "HGInfoImpl.hpp"
|
||||
#include "HGInc.h"
|
||||
|
||||
HGInfoImpl* g_infoImpl = NULL;
|
||||
|
||||
HGResult HGAPI HGBase_EnableInfo()
|
||||
{
|
||||
if (NULL == g_infoImpl)
|
||||
return HGBASE_ERR_FAIL;
|
||||
|
||||
return g_infoImpl->Enable();
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_DisableInfo()
|
||||
{
|
||||
if (NULL == g_infoImpl)
|
||||
return HGBASE_ERR_FAIL;
|
||||
|
||||
return g_infoImpl->Disable();
|
||||
}
|
||||
|
||||
HGResult HGAPIV HGBase_WriteInfo(HGUInt type, const HGChar* format, ...)
|
||||
{
|
||||
if (NULL == g_infoImpl)
|
||||
return HGBASE_ERR_FAIL;
|
||||
|
||||
char buf[1024] = { 0 };
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
vsnprintf(buf, 1024, format, va);
|
||||
va_end(va);
|
||||
|
||||
return g_infoImpl->Write(type, buf);
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef __HGINFO_H__
|
||||
#define __HGINFO_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
/* 致命错误 */
|
||||
#define HGBASE_INFOTYPE_FATAL 1L
|
||||
/* 一般错误 */
|
||||
#define HGBASE_INFOTYPE_ERROR 2L
|
||||
/* 警告 */
|
||||
#define HGBASE_INFOTYPE_WARNING 4L
|
||||
/* 一般描述信息 */
|
||||
#define HGBASE_INFOTYPE_DESC 8L
|
||||
/* 调试信息 */
|
||||
#define HGBASE_INFOTYPE_DEBUG 16L
|
||||
|
||||
/* 启用日志/控制台信息
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_EnableInfo();
|
||||
|
||||
/* 禁用日志/控制台信息
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_DisableInfo();
|
||||
|
||||
/* 写日志/控制台信息
|
||||
* 参数:
|
||||
* 1) type: in, 信息类型, 参见HGBASE_INFOTYPE_*
|
||||
* 2) format: in, 信息格式
|
||||
* 说明:
|
||||
* 1) 信息的完整输出行: [日期-时间] [进程号/线程号] [信息类型] [信息]
|
||||
* 2) 信息的实际输出行取决于config.ini的配置
|
||||
*/
|
||||
HGEXPORT HGResult HGAPIV HGBase_WriteInfo(HGUInt type, const HGChar* format, ...);
|
||||
|
||||
#endif /* __HGINFO_H__ */
|
|
@ -0,0 +1,171 @@
|
|||
#include "HGInfoImpl.hpp"
|
||||
#include "HGInfo.h"
|
||||
#include "HGInc.h"
|
||||
#include "HGUtility.h"
|
||||
#include "HGIni.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
HGInfoImpl::HGInfoImpl()
|
||||
{
|
||||
HGBase_CreateLock(&m_lock);
|
||||
m_enabled = HGFALSE;
|
||||
m_log = NULL;
|
||||
m_console = NULL;
|
||||
m_type = 0;
|
||||
m_showTime = HGFALSE;
|
||||
m_showId = HGFALSE;
|
||||
m_showType = HGFALSE;
|
||||
|
||||
Enable();
|
||||
}
|
||||
|
||||
HGInfoImpl::~HGInfoImpl()
|
||||
{
|
||||
Disable();
|
||||
|
||||
HGBase_DestroyLock(m_lock);
|
||||
m_lock = NULL;
|
||||
}
|
||||
|
||||
HGResult HGInfoImpl::Enable()
|
||||
{
|
||||
if (m_enabled)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
HGChar cfgPath[256] = { 0 };
|
||||
HGBase_GetConfigPath(cfgPath, 256);
|
||||
strcat(cfgPath, "config.ini");
|
||||
|
||||
HGBool writeLog;
|
||||
HGBase_GetProfileInt(cfgPath, "info", "writeLog", 1, &writeLog);
|
||||
HGBool writeConsole;
|
||||
HGBase_GetProfileInt(cfgPath, "info", "writeConsole", 0, &writeConsole);
|
||||
HGUInt defType = HGBASE_INFOTYPE_FATAL | HGBASE_INFOTYPE_ERROR | HGBASE_INFOTYPE_WARNING;
|
||||
HGBase_GetProfileInt(cfgPath, "info", "type", (HGInt)defType, (HGInt*)&m_type);
|
||||
HGBase_GetProfileInt(cfgPath, "info", "showTime", 1, &m_showTime);
|
||||
HGBase_GetProfileInt(cfgPath, "info", "showId", 0, &m_showId);
|
||||
HGBase_GetProfileInt(cfgPath, "info", "showType", 1, &m_showType);
|
||||
|
||||
if (writeLog)
|
||||
{
|
||||
HGChar logPath[256];
|
||||
HGBase_GetLogFilePath(logPath, 256);
|
||||
HGBase_CreateDir(logPath);
|
||||
|
||||
timeb tb;
|
||||
ftime(&tb);
|
||||
struct tm* p = localtime(&tb.time);
|
||||
|
||||
char fileName[256];
|
||||
#if defined(HG_CMP_MSC)
|
||||
sprintf(fileName, "\\%04d%02d%02d.log", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday);
|
||||
#else
|
||||
sprintf(fileName, "/%04d%02d%02d.log", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday);
|
||||
#endif
|
||||
strcat(logPath, fileName);
|
||||
HGBase_OpenLog(logPath, &m_log);
|
||||
}
|
||||
|
||||
if (writeConsole)
|
||||
{
|
||||
HGBase_OpenConsole(&m_console);
|
||||
}
|
||||
|
||||
m_enabled = HGTRUE;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGInfoImpl::Disable()
|
||||
{
|
||||
if (!m_enabled)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
HGBase_CloseConsole(m_console);
|
||||
m_console = NULL;
|
||||
HGBase_CloseLog(m_log);
|
||||
m_log = NULL;
|
||||
|
||||
m_enabled = HGFALSE;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGInfoImpl::Write(HGUInt type, const HGChar* info)
|
||||
{
|
||||
if (!m_enabled)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
if (HGBASE_INFOTYPE_FATAL != type && HGBASE_INFOTYPE_ERROR != type
|
||||
&& HGBASE_INFOTYPE_WARNING != type && HGBASE_INFOTYPE_DESC != type
|
||||
&& HGBASE_INFOTYPE_DEBUG != type)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (NULL == info || '\0' == *info)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (0 == (type & m_type))
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
char writeInfo[2048] = { 0 };
|
||||
|
||||
if (m_showTime)
|
||||
{
|
||||
timeb tb;
|
||||
ftime(&tb);
|
||||
struct tm* p = localtime(&tb.time);
|
||||
char timeStr[64] = { 0 };
|
||||
sprintf(timeStr, "[%04d/%02d/%02d-%02d:%02d:%02d.%03d]", (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday,
|
||||
p->tm_hour, p->tm_min, p->tm_sec, tb.millitm);
|
||||
strcat(writeInfo, timeStr);
|
||||
strcat(writeInfo, " ");
|
||||
}
|
||||
|
||||
if (m_showId)
|
||||
{
|
||||
char idStr[32] = { 0 };
|
||||
#if defined(HG_CMP_MSC)
|
||||
sprintf(idStr, "[0x%08X/0x%08X]", GetCurrentProcessId(), GetCurrentThreadId());
|
||||
#else
|
||||
sprintf(idStr, "[0x%08X/0x%08X]", (HGUInt)getpid(), (HGUInt)syscall(SYS_gettid));
|
||||
#endif
|
||||
strcat(writeInfo, idStr);
|
||||
strcat(writeInfo, " ");
|
||||
}
|
||||
|
||||
if (m_showType)
|
||||
{
|
||||
char typeStr[24] = { 0 };
|
||||
if (HGBASE_INFOTYPE_FATAL == type)
|
||||
sprintf(typeStr, "[%s]", "FAT");
|
||||
else if (HGBASE_INFOTYPE_ERROR == type)
|
||||
sprintf(typeStr, "[%s]", "ERR");
|
||||
else if (HGBASE_INFOTYPE_WARNING == type)
|
||||
sprintf(typeStr, "[%s]", "WAR");
|
||||
else if (HGBASE_INFOTYPE_DESC == type)
|
||||
sprintf(typeStr, "[%s]", "DES");
|
||||
else
|
||||
sprintf(typeStr, "[%s]", "DEB");
|
||||
strcat(writeInfo, typeStr);
|
||||
strcat(writeInfo, " ");
|
||||
}
|
||||
|
||||
strcat(writeInfo, info);
|
||||
|
||||
HGBase_EnterLock(m_lock);
|
||||
HGBase_WriteLog(m_log, writeInfo);
|
||||
HGBase_WriteConsole(m_console, writeInfo);
|
||||
HGBase_LeaveLock(m_lock);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef __HGINFOIMPL_HPP__
|
||||
#define __HGINFOIMPL_HPP__
|
||||
|
||||
#include "HGLog.h"
|
||||
#include "HGConsole.h"
|
||||
#include "HGLock.h"
|
||||
|
||||
class HGInfoImpl
|
||||
{
|
||||
public:
|
||||
HGInfoImpl();
|
||||
~HGInfoImpl();
|
||||
|
||||
HGResult Enable();
|
||||
HGResult Disable();
|
||||
HGResult Write(HGUInt type, const HGChar* info);
|
||||
|
||||
private:
|
||||
HGLock m_lock;
|
||||
HGBool m_enabled;
|
||||
HGLog m_log;
|
||||
HGConsole m_console;
|
||||
HGUInt m_type;
|
||||
HGBool m_showTime;
|
||||
HGBool m_showId;
|
||||
HGBool m_showType;
|
||||
};
|
||||
|
||||
#endif /* __HGINFOIMPL_HPP__ */
|
|
@ -0,0 +1,339 @@
|
|||
#include "HGIni.h"
|
||||
#include "HGInc.h"
|
||||
#include "HGInfo.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
static HGUInt IniWriteValue(const char* section, const char* key, const char* val, const char* file)
|
||||
{
|
||||
typedef std::vector<std::pair<std::string, std::string> > KeyList;
|
||||
typedef std::vector<std::pair<std::string, KeyList> > SectionList;
|
||||
|
||||
SectionList sectList;
|
||||
|
||||
FILE* fp = fopen(file, "r");
|
||||
if (fp != NULL)
|
||||
{
|
||||
KeyList* pCurKeyList = NULL;
|
||||
|
||||
while (feof(fp) == 0)
|
||||
{
|
||||
char lineContent[256] = { 0 };
|
||||
if (NULL == fgets(lineContent, 256, fp))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((lineContent[0] == ';') || (lineContent[0] == '\0') || (lineContent[0] == '\r') || (lineContent[0] == '\n'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < strlen(lineContent); ++i)
|
||||
{
|
||||
if (lineContent[i] == '\r' || lineContent[i] == '\n')
|
||||
{
|
||||
lineContent[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lineContent[0] == '[')
|
||||
{
|
||||
std::pair<std::string, KeyList> pr;
|
||||
pr.first = lineContent;
|
||||
sectList.push_back(pr);
|
||||
pCurKeyList = §List[sectList.size() - 1].second;
|
||||
}
|
||||
else
|
||||
{
|
||||
int pos = -1;
|
||||
for (int i = 0; i < (int)strlen(lineContent); ++i)
|
||||
{
|
||||
if (lineContent[i] == '=')
|
||||
{
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != pCurKeyList)
|
||||
{
|
||||
std::pair<std::string, std::string> pr;
|
||||
if (-1 != pos)
|
||||
{
|
||||
pr.first.assign(lineContent, pos);
|
||||
pr.second.assign(lineContent + pos + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
pr.first = lineContent;
|
||||
}
|
||||
|
||||
pCurKeyList->push_back(pr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
bool bFindSect = false;
|
||||
for (size_t i = 0; i < sectList.size(); ++i)
|
||||
{
|
||||
if (strcmp(sectList[i].first.c_str(), section) == 0)
|
||||
{
|
||||
bool bFindKey = false;
|
||||
for (size_t j = 0; j < sectList[i].second.size(); ++j)
|
||||
{
|
||||
if (strcmp(sectList[i].second[j].first.c_str(), key) == 0)
|
||||
{
|
||||
sectList[i].second[j].second = val;
|
||||
bFindKey = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFindKey)
|
||||
{
|
||||
std::pair<std::string, std::string> pr;
|
||||
pr.first = key;
|
||||
pr.second = val;
|
||||
sectList[i].second.push_back(pr);
|
||||
}
|
||||
|
||||
bFindSect = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bFindSect)
|
||||
{
|
||||
std::pair<std::string, KeyList> pr;
|
||||
pr.first = section;
|
||||
std::pair<std::string, std::string> pr2;
|
||||
pr2.first = key;
|
||||
pr2.second = val;
|
||||
pr.second.push_back(pr2);
|
||||
sectList.push_back(pr);
|
||||
}
|
||||
|
||||
fp = fopen(file, "w");
|
||||
if (fp == NULL)
|
||||
{
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "IniWriteValue: fopen fail %s errno=%d", file, errno);
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < sectList.size(); ++i)
|
||||
{
|
||||
fputs(sectList[i].first.c_str(), fp);
|
||||
fputs("\n", fp);
|
||||
|
||||
for (size_t j = 0; j < sectList[i].second.size(); ++j)
|
||||
{
|
||||
fputs(sectList[i].second[j].first.c_str(), fp);
|
||||
fputs("=", fp);
|
||||
fputs(sectList[i].second[j].second.c_str(), fp);
|
||||
fputs("\n", fp);
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
static HGResult writeStringValue(const char* section, const char* key, const char* val, const char* file)
|
||||
{
|
||||
if (section == NULL || key == NULL || val == NULL || file == NULL)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
char sect[256];
|
||||
sprintf(sect, "[%s]", section);
|
||||
return IniWriteValue(sect, key, val, file);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_SetProfileInt(const HGChar* fileName, const HGChar* appName,
|
||||
const HGChar* keyName, HGInt value)
|
||||
{
|
||||
if (NULL == fileName || NULL == appName || NULL == keyName)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
char str[8];
|
||||
sprintf(str, "%d", value);
|
||||
return writeStringValue(appName, keyName, str, fileName);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_SetProfileString(const HGChar* fileName, const HGChar* appName,
|
||||
const HGChar* keyName, const HGChar* value)
|
||||
{
|
||||
if (NULL == fileName || NULL == appName || NULL == keyName)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
return writeStringValue(appName, keyName, value, fileName);
|
||||
}
|
||||
|
||||
static HGResult IniReadValue(const char* section, const char* key, char* val, const char* def, const char* file)
|
||||
{
|
||||
typedef std::vector<std::pair<std::string, std::string> > KeyList;
|
||||
typedef std::vector<std::pair<std::string, KeyList> > SectionList;
|
||||
|
||||
SectionList sectList;
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (0 != _access(file, 0))
|
||||
#else
|
||||
if (0 != access(file, 0))
|
||||
#endif
|
||||
{
|
||||
return HGBASE_ERR_FILENOTEXIST;
|
||||
}
|
||||
|
||||
FILE* fp = fopen(file, "r");
|
||||
if (fp != NULL)
|
||||
{
|
||||
KeyList* pCurKeyList = NULL;
|
||||
|
||||
while (feof(fp) == 0)
|
||||
{
|
||||
char lineContent[256] = { 0 };
|
||||
if (NULL == fgets(lineContent, 256, fp))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((lineContent[0] == ';') || (lineContent[0] == '\0') || (lineContent[0] == '\r') || (lineContent[0] == '\n'))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < strlen(lineContent); ++i)
|
||||
{
|
||||
if (lineContent[i] == '\r' || lineContent[i] == '\n')
|
||||
{
|
||||
lineContent[i] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lineContent[0] == '[')
|
||||
{
|
||||
std::pair<std::string, KeyList> pr;
|
||||
pr.first = lineContent;
|
||||
sectList.push_back(pr);
|
||||
pCurKeyList = §List[sectList.size() - 1].second;
|
||||
}
|
||||
else
|
||||
{
|
||||
int pos = -1;
|
||||
for (int i = 0; i < (int)strlen(lineContent); ++i)
|
||||
{
|
||||
if (lineContent[i] == '=')
|
||||
{
|
||||
pos = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != pCurKeyList)
|
||||
{
|
||||
std::pair<std::string, std::string> pr;
|
||||
if (-1 != pos)
|
||||
{
|
||||
pr.first.assign(lineContent, pos);
|
||||
pr.second.assign(lineContent + pos + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
pr.first = lineContent;
|
||||
}
|
||||
|
||||
pCurKeyList->push_back(pr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(val, def);
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
}
|
||||
|
||||
bool bGetVal = false;
|
||||
for (size_t i = 0; i < sectList.size(); ++i)
|
||||
{
|
||||
if (strcmp(sectList[i].first.c_str(), section) == 0)
|
||||
{
|
||||
for (size_t j = 0; j < sectList[i].second.size(); ++j)
|
||||
{
|
||||
if (strcmp(sectList[i].second[j].first.c_str(), key) == 0)
|
||||
{
|
||||
strcpy(val, sectList[i].second[j].second.c_str());
|
||||
bGetVal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bGetVal)
|
||||
{
|
||||
strcpy(val, def);
|
||||
}
|
||||
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
static HGResult readStringValue(const char* section, const char* key, char* val, const char* def, const char* file)
|
||||
{
|
||||
if (section == NULL || key == NULL || val == NULL || def == NULL || file == NULL)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
char sect[256];
|
||||
sprintf(sect, "[%s]", section);
|
||||
return IniReadValue(sect, key, val, def, file);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetProfileInt(const HGChar* fileName, const HGChar* appName,
|
||||
const HGChar* keyName, HGInt def, HGInt* value)
|
||||
{
|
||||
if (NULL == appName || NULL == keyName || NULL == value)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
char strRet[256] = { 0 };
|
||||
char strDef[32];
|
||||
sprintf(strDef, "%d", def);
|
||||
HGResult ret = readStringValue(appName, keyName, strRet, strDef, fileName);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
*value = def;
|
||||
return ret;
|
||||
}
|
||||
|
||||
*value = atoi(strRet);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetProfileString(const HGChar* fileName, const HGChar* appName,
|
||||
const HGChar* keyName, const HGChar* def, HGChar* value, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == appName || NULL == keyName || NULL == value)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
return readStringValue(appName, keyName, value, def, fileName);
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef __HGINI_H__
|
||||
#define __HGINI_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
/* 设置ini文件的值
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_SetProfileInt(const HGChar* fileName, const HGChar* appName,
|
||||
const HGChar* keyName, HGInt value);
|
||||
|
||||
/* 设置ini文件的值
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_SetProfileString(const HGChar* fileName, const HGChar* appName,
|
||||
const HGChar* keyName, const HGChar* value);
|
||||
|
||||
/* 获取ini文件的值
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetProfileInt(const HGChar* fileName, const HGChar* appName,
|
||||
const HGChar* keyName, HGInt def, HGInt* value);
|
||||
|
||||
/* 获取ini文件的值
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetProfileString(const HGChar* fileName, const HGChar* appName,
|
||||
const HGChar* keyName, const HGChar* def, HGChar* value, HGUInt maxLen);
|
||||
|
||||
#endif /* __HGINI_H__ */
|
|
@ -0,0 +1,78 @@
|
|||
#include "HGLock.h"
|
||||
#include "HGInc.h"
|
||||
|
||||
HGResult HGAPI HGBase_CreateLock(HGLock* lock)
|
||||
{
|
||||
if (NULL == lock)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
pthread_mutex_t* hLock = new pthread_mutex_t;
|
||||
if (0 != pthread_mutex_init(hLock, NULL))
|
||||
{
|
||||
delete hLock;
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
*lock = (HGLock)hLock;
|
||||
#else
|
||||
CRITICAL_SECTION* hLock = new CRITICAL_SECTION;
|
||||
InitializeCriticalSection(hLock);
|
||||
*lock = (HGLock)hLock;
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_DestroyLock(HGLock lock)
|
||||
{
|
||||
if (NULL == lock)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
pthread_mutex_t* hLock = (pthread_mutex_t*)lock;
|
||||
pthread_mutex_destroy(hLock);
|
||||
delete hLock;
|
||||
#else
|
||||
CRITICAL_SECTION* hLock = (CRITICAL_SECTION*)lock;
|
||||
DeleteCriticalSection(hLock);
|
||||
delete hLock;
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_EnterLock(HGLock lock)
|
||||
{
|
||||
if (NULL == lock)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
pthread_mutex_t* hLock = (pthread_mutex_t*)lock;
|
||||
pthread_mutex_lock(hLock);
|
||||
#else
|
||||
CRITICAL_SECTION* hLock = (CRITICAL_SECTION*)lock;
|
||||
EnterCriticalSection(hLock);
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_LeaveLock(HGLock lock)
|
||||
{
|
||||
if (NULL == lock)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
pthread_mutex_t* hLock = (pthread_mutex_t*)lock;
|
||||
pthread_mutex_unlock(hLock);
|
||||
#else
|
||||
CRITICAL_SECTION* hLock = (CRITICAL_SECTION*)lock;
|
||||
LeaveCriticalSection(hLock);
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
#ifndef __HGLOCK_H__
|
||||
#define __HGLOCK_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
HG_DECLARE_HANDLE(HGLock);
|
||||
|
||||
/* 创建互斥锁
|
||||
* 参数:
|
||||
* 1) lock: out, 互斥锁句柄
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateLock(HGLock* lock);
|
||||
|
||||
/* 销毁互斥锁
|
||||
* 参数:
|
||||
* 1) lock: in, 互斥锁句柄
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_DestroyLock(HGLock lock);
|
||||
|
||||
/* 加锁
|
||||
* 参数:
|
||||
* 1) lock: in, 互斥锁句柄
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_EnterLock(HGLock lock);
|
||||
|
||||
/* 解锁
|
||||
* 参数:
|
||||
* 1) lock: in, 互斥锁句柄
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_LeaveLock(HGLock lock);
|
||||
|
||||
#endif /* __HGLOCK_H__ */
|
|
@ -0,0 +1,89 @@
|
|||
#include "HGLog.h"
|
||||
#include "HGInc.h"
|
||||
|
||||
struct HGLogImpl
|
||||
{
|
||||
HGLogImpl()
|
||||
{
|
||||
m_file = NULL;
|
||||
}
|
||||
|
||||
~HGLogImpl()
|
||||
{
|
||||
if (NULL != m_file)
|
||||
{
|
||||
fclose(m_file);
|
||||
m_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
FILE* m_file;
|
||||
};
|
||||
|
||||
HGResult HGAPI HGBase_OpenLog(const HGChar* fileName, HGLog* log)
|
||||
{
|
||||
if (NULL == fileName || NULL == log)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
FILE *file = fopen(fileName, "a+");
|
||||
if (NULL == file)
|
||||
{
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
}
|
||||
|
||||
HGLogImpl* logImpl = new HGLogImpl;
|
||||
logImpl->m_file = file;
|
||||
*log = (HGLog)logImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_CloseLog(HGLog log)
|
||||
{
|
||||
if (NULL == log)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGLogImpl* logImpl = (HGLogImpl*)log;
|
||||
delete logImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetLogFileSize(HGLog log, HGLonglong* size)
|
||||
{
|
||||
if (NULL == log || NULL == size)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGLogImpl* logImpl = (HGLogImpl*)log;
|
||||
#if defined(HG_CMP_MSC)
|
||||
_fseeki64(logImpl->m_file, 0, SEEK_END);
|
||||
*size = _ftelli64(logImpl->m_file);
|
||||
#else
|
||||
fseeko64(logImpl->m_file, 0, SEEK_END);
|
||||
*size = ftello64(logImpl->m_file);
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_WriteLog(HGLog log, const HGChar* info)
|
||||
{
|
||||
if (NULL == log || NULL == info || '\0' == *info)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGLogImpl* logImpl = (HGLogImpl*)log;
|
||||
#if defined(HG_CMP_MSC)
|
||||
_fseeki64(logImpl->m_file, 0, SEEK_END);
|
||||
#else
|
||||
fseeko64(logImpl->m_file, 0, SEEK_END);
|
||||
#endif
|
||||
fwrite(info, 1, strlen(info), logImpl->m_file);
|
||||
fwrite("\n", 1, strlen("\n"), logImpl->m_file);
|
||||
fflush(logImpl->m_file);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
#ifndef __HGLOG_H__
|
||||
#define __HGLOG_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
HG_DECLARE_HANDLE(HGLog);
|
||||
|
||||
/* 开启日志
|
||||
* 参数:
|
||||
* 1) fileName: in, 文件名
|
||||
* 2) log: out, 日志句柄
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_OpenLog(const HGChar* fileName, HGLog* log);
|
||||
|
||||
/* 关闭日志
|
||||
* 参数:
|
||||
* 1) log: in, 日志句柄
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CloseLog(HGLog log);
|
||||
|
||||
/* 获取日志文件大小
|
||||
* 参数:
|
||||
* 1) log: in, 日志句柄
|
||||
* 2) size: out, 日志文件大小
|
||||
* 说明:
|
||||
* 1) 每次写入日志信息后,可以用该函数检查日志文件的大小,当日志文件足够大时,可以关闭该日志句柄,在新的日志文件上重新打开
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetLogFileSize(HGLog log, HGLonglong* size);
|
||||
|
||||
/* 写日志信息
|
||||
* 参数:
|
||||
* 1) log: in, 日志句柄
|
||||
* 2) info: in, 信息, 一次一行, info无需加换行符
|
||||
* 说明:
|
||||
* 1) 该函数不是线程安全的, 在不同进程或不同线程调用的时候, 需要加锁
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_WriteLog(HGLog log, const HGChar* info);
|
||||
|
||||
#endif /* __HGLOG_H__ */
|
|
@ -0,0 +1,314 @@
|
|||
#include "HGMd5.h"
|
||||
#include "HGInc.h"
|
||||
|
||||
/* Constants for MD5Transform routine. */
|
||||
/* md5转换用到的常量,算法本身规定的 */
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
|
||||
/*
|
||||
接下来的这几个宏定义是md5算法规定的,就是对信息进行md5加密都要做的运算。
|
||||
据说有经验的高手跟踪程序时根据这几个特殊的操作就可以断定是不是用的md5
|
||||
F, G, H and I are basic MD5 functions.
|
||||
*/
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
/*
|
||||
ROTATE_LEFT rotates x left n bits.
|
||||
*/
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/*
|
||||
FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
Rotation is separate from addition to prevent recomputation.
|
||||
*/
|
||||
#define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + (HGUInt)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
|
||||
#define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + (HGUInt)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
|
||||
#define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + (HGUInt)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
|
||||
#define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + (HGUInt)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); }
|
||||
|
||||
/* MD5 context. */
|
||||
struct MD5_CTX
|
||||
{
|
||||
/* state (ABCD) */
|
||||
/*四个32bits数,用于存放最终计算得到的消息摘要。当消息长度〉512bits时,也用于存放每个512bits的中间结果*/
|
||||
HGUInt state[4];
|
||||
/* number of bits, modulo 2^64 (lsb first) */
|
||||
/*存储原始信息的bits数长度,不包括填充的bits,最长为 2^64 bits,因为2^64是一个64位数的最大值*/
|
||||
HGUInt count[2];
|
||||
/* input buffer */
|
||||
/*存放输入的信息的缓冲区,512bits*/
|
||||
HGByte buffer[64];
|
||||
};
|
||||
|
||||
/* MD5 initialization. Begins an MD5 operation, writing a new context. */
|
||||
/*初始化md5的结构*/
|
||||
static void MD5Init(MD5_CTX* ctx)
|
||||
{
|
||||
/*将当前的有效信息的长度设成0,这个很简单,还没有有效信息,长度当然是0了*/
|
||||
ctx->count[0] = 0;
|
||||
ctx->count[1] = 0;
|
||||
|
||||
/* Load magic initialization constants.*/
|
||||
/*初始化链接变量,算法要求这样,这个没法解释了*/
|
||||
ctx->state[0] = 0x67452301;
|
||||
ctx->state[1] = 0xefcdab89;
|
||||
ctx->state[2] = 0x98badcfe;
|
||||
ctx->state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
/*
|
||||
将4字节的整数copy到字符形式的缓冲区中
|
||||
output:用于输出的字符缓冲区
|
||||
input:欲转换的四字节的整数形式的数组
|
||||
len:output缓冲区的长度,要求是4的整数倍
|
||||
*/
|
||||
static void MD5Encode(HGByte* output, const HGUInt* input, HGUInt len)
|
||||
{
|
||||
for (HGUInt i = 0, j = 0; j < len; i++, j += 4)
|
||||
{
|
||||
output[j] = (HGByte)(input[i] & 0xFF);
|
||||
output[j + 1] = (HGByte)((input[i] >> 8) & 0xFF);
|
||||
output[j + 2] = (HGByte)((input[i] >> 16) & 0xFF);
|
||||
output[j + 3] = (HGByte)((input[i] >> 24) & 0xFF);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
与上面的函数正好相反,这一个把字符形式的缓冲区中的数据copy到4字节的整数中(即以整数形式保存)
|
||||
output:保存转换出的整数
|
||||
input:欲转换的字符缓冲区
|
||||
len:输入的字符缓冲区的长度,要求是4的整数倍
|
||||
*/
|
||||
static void MD5Decode(HGUInt* output, const HGByte* input, HGUInt len)
|
||||
{
|
||||
for (HGUInt i = 0, j = 0; j < len; i++, j += 4)
|
||||
{
|
||||
output[i] = ((HGUInt)input[j]) | (((HGUInt)input[j + 1]) << 8) | (((HGUInt)input[j + 2]) << 16) | (((HGUInt)input[j + 3]) << 24);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
对512bits信息(即block缓冲区)进行一次处理,每次处理包括四轮
|
||||
state[4]:md5结构中的state[4],用于保存对512bits信息加密的中间结果或者最终结果
|
||||
block[64]:欲加密的512bits信息
|
||||
*/
|
||||
static void MD5Transform(HGUInt* state, const HGByte* block)
|
||||
{
|
||||
HGUInt a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
|
||||
MD5Decode(x, block, 64);
|
||||
|
||||
/* Round 1 */
|
||||
FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
|
||||
FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
|
||||
FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
|
||||
FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
|
||||
FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
|
||||
FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
|
||||
FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
|
||||
FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
|
||||
FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
|
||||
FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
|
||||
FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
|
||||
GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
|
||||
GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
|
||||
GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
|
||||
GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
|
||||
GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
|
||||
GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
|
||||
GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
|
||||
HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
|
||||
HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
|
||||
HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
|
||||
HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
|
||||
HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
|
||||
HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
|
||||
HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
|
||||
II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
|
||||
II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
|
||||
II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
|
||||
II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
|
||||
II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
|
||||
II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
|
||||
II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
|
||||
II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
/* Zeroize sensitive information. */
|
||||
memset(x, 0, sizeof(x));
|
||||
}
|
||||
|
||||
/*
|
||||
MD5 block update operation. Continues an MD5 message-digest
|
||||
operation, processing another message block, and updating the
|
||||
context.
|
||||
将与加密的信息传递给md5结构,可以多次调用
|
||||
context:初始化过了的md5结构
|
||||
input:欲加密的信息,可以任意长
|
||||
inputLen:指定input的长度
|
||||
*/
|
||||
static void MD5Update(MD5_CTX* ctx, const HGByte* data, HGUInt size)
|
||||
{
|
||||
HGUInt i, index, partLen;
|
||||
|
||||
/*
|
||||
计算已有信息的bits长度的字节数的模64, 64bytes=512bits。
|
||||
用于判断已有信息加上当前传过来的信息的总长度能不能达到512bits,
|
||||
如果能够达到则对凑够的512bits进行一次处理
|
||||
*/
|
||||
index = (HGUInt)((ctx->count[0] >> 3) & 0x3F);
|
||||
|
||||
/* Update number of bits *//*更新已有信息的bits长度 */
|
||||
if ((ctx->count[0] += ((HGUInt)size << 3)) < ((HGUInt)size << 3))
|
||||
ctx->count[1]++;
|
||||
ctx->count[1] += ((HGUInt)size >> 29);
|
||||
|
||||
/* 计算已有的字节数长度还差多少字节可以 凑成64的整倍数 */
|
||||
partLen = 64 - index;
|
||||
|
||||
/* 如果当前输入的字节数 大于 已有字节数长度补足64字节整倍数所差的字节数 */
|
||||
if (size >= partLen)
|
||||
{
|
||||
/* 用当前输入的内容把ctx->buffer的内容补足512bits */
|
||||
memcpy(&ctx->buffer[index], data, partLen);
|
||||
/* 用基本函数对填充满的512bits(已经保存到ctx->buffer中) 做一次转换,转换结果保存到ctx->state中 */
|
||||
MD5Transform(ctx->state, ctx->buffer);
|
||||
|
||||
/*
|
||||
对当前输入的剩余字节做转换(如果剩余的字节<在输入的data缓冲区中>大于512bits的话),
|
||||
转换结果保存到ctx->state中
|
||||
*/
|
||||
for (i = partLen; i + 63 < size; i += 64) /* 把i+63<size改为i+64<=size更容易理解 */
|
||||
MD5Transform(ctx->state, &data[i]);
|
||||
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
i = 0;
|
||||
}
|
||||
|
||||
/* 将输入缓冲区中的不足填充满512bits的剩余内容填充到ctx->buffer中,留待以后再作处理 */
|
||||
memcpy(&ctx->buffer[index], &data[i], size - i);
|
||||
}
|
||||
|
||||
/*
|
||||
MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||
the message digest and zeroizing the context.
|
||||
获取加密 的最终结果
|
||||
digest:保存最终的加密串
|
||||
context:你前面初始化并填入了信息的md5结构
|
||||
*/
|
||||
static void MD5Final(MD5_CTX* ctx, HGByte* md5)
|
||||
{
|
||||
/*
|
||||
用于bits填充的缓冲区,为什么要64个字节呢?因为当欲加密的信息的bits数被512除其余数为448时,
|
||||
需要填充的bits的最大值为512=64*8 。
|
||||
*/
|
||||
static const HGByte MD5_PADDING[64] =
|
||||
{
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
HGByte bits[8];
|
||||
HGUInt index, padLen;
|
||||
|
||||
/* 将要被转换的信息(所有的)的bits长度拷贝到bits中 */
|
||||
MD5Encode(bits, ctx->count, 8);
|
||||
|
||||
/* 计算所有的bits长度的字节数的模64, 64bytes=512bits */
|
||||
index = (HGUInt)((ctx->count[0] >> 3) & 0x3F);
|
||||
|
||||
/* 计算需要填充的字节数,padLen的取值范围在1-64之间 */
|
||||
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
|
||||
/* 这一次函数调用绝对不会再导致MD5Transform的被调用,因为这一次不会填满512bits */
|
||||
MD5Update(ctx, MD5_PADDING, padLen);
|
||||
/* 补上原始信息的bits长度(bits长度固定的用64bits表示),这一次能够恰巧凑够512bits,不会多也不会少 */
|
||||
MD5Update(ctx, bits, 8);
|
||||
|
||||
/* Store state in digest */
|
||||
MD5Encode(md5, ctx->state, 16);
|
||||
memset(ctx, 0, sizeof(MD5_CTX));
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_MakeMd5(const HGByte* data, HGUInt size, HGByte* md5)
|
||||
{
|
||||
if (NULL == data || 0 == size || NULL == md5)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
MD5_CTX ctx;
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, data, size);
|
||||
MD5Final(&ctx, md5);
|
||||
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
#ifndef __HGMD5_H__
|
||||
#define __HGMD5_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
/* 生成MD5值
|
||||
* 参数:
|
||||
* 1) data: in, 数据地址
|
||||
* 2) size: in, 数据长度
|
||||
* 3) md5: out, md5值, 必须至少分配16字节
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_MakeMd5(const HGByte* data, HGUInt size, HGByte* md5);
|
||||
|
||||
#endif /* __HGMD5_H__ */
|
|
@ -0,0 +1,59 @@
|
|||
#include "HGMsgPump.h"
|
||||
#include "HGMsgPumpImpl.hpp"
|
||||
|
||||
HGResult HGAPI HGBase_CreateMsgPump(HGMsgPump* msgPump)
|
||||
{
|
||||
if (NULL == msgPump)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGMsgPumpImpl* msgPumpImpl = new HGMsgPumpImpl;
|
||||
*msgPump = (HGMsgPump)msgPumpImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_DestroyMsgPump(HGMsgPump msgPump)
|
||||
{
|
||||
if (NULL == msgPump)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGMsgPumpImpl* msgPumpImpl = (HGMsgPumpImpl*)msgPump;
|
||||
delete msgPumpImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_RunMsgPump(HGMsgPump msgPump, HGMsgPumpFunc func, HGPointer param)
|
||||
{
|
||||
if (NULL == msgPump)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGMsgPumpImpl* msgPumpImpl = (HGMsgPumpImpl*)msgPump;
|
||||
return msgPumpImpl->Run(func, param);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_PostPumpMessage(HGMsgPump msgPump, const HGMsg* msg)
|
||||
{
|
||||
if (NULL == msgPump)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGMsgPumpImpl* msgPumpImpl = (HGMsgPumpImpl*)msgPump;
|
||||
return msgPumpImpl->PostMessage(msg);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_ExitMsgPump(HGMsgPump msgPump)
|
||||
{
|
||||
if (NULL == msgPump)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGMsgPumpImpl* msgPumpImpl = (HGMsgPumpImpl*)msgPump;
|
||||
return msgPumpImpl->Exit();
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
#ifndef __HGMSGPUMP_H__
|
||||
#define __HGMSGPUMP_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
HG_DECLARE_HANDLE(HGMsgPump);
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
|
||||
/* 消息结构体, 可以自定义 */
|
||||
typedef struct
|
||||
{
|
||||
HGUInt id; /* 消息ID, 不能为0 */
|
||||
HGPointer data; /* 携带的数据 */
|
||||
}HGMsg;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef void (HGAPI *HGMsgPumpFunc)(HGMsgPump msgPump, const HGMsg* msg, HGPointer param);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateMsgPump(HGMsgPump *msgPump);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_DestroyMsgPump(HGMsgPump msgPump);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_RunMsgPump(HGMsgPump msgPump, HGMsgPumpFunc func, HGPointer param);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_PostPumpMessage(HGMsgPump msgPump, const HGMsg *msg);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_ExitMsgPump(HGMsgPump msgPump);
|
||||
|
||||
#endif /* __HGMSGPUMP_H__ */
|
|
@ -0,0 +1,102 @@
|
|||
#include "HGMsgPumpImpl.hpp"
|
||||
|
||||
HGMsgPumpImpl::HGMsgPumpImpl()
|
||||
{
|
||||
HGBase_CreateEvent(HGTRUE, HGFALSE, &m_msgEvent);
|
||||
HGBase_CreateLock(&m_msgLock);
|
||||
m_bRecvMsg = HGTRUE;
|
||||
}
|
||||
|
||||
HGMsgPumpImpl::~HGMsgPumpImpl()
|
||||
{
|
||||
HGBase_DestroyLock(m_msgLock);
|
||||
m_msgLock = NULL;
|
||||
HGBase_DestroyEvent(m_msgEvent);
|
||||
m_msgEvent = NULL;
|
||||
}
|
||||
|
||||
HGResult HGMsgPumpImpl::Run(HGMsgPumpFunc func, HGPointer param)
|
||||
{
|
||||
if (NULL == func)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
HGBase_WaitEvent(m_msgEvent);
|
||||
|
||||
HGMsg msg = { 0 };
|
||||
bool getMsg = false;
|
||||
|
||||
HGBase_EnterLock(m_msgLock);
|
||||
if (!m_listMsg.empty())
|
||||
{
|
||||
msg = m_listMsg.front();
|
||||
m_listMsg.pop_front();
|
||||
getMsg = true;
|
||||
}
|
||||
if (m_listMsg.empty())
|
||||
{
|
||||
HGBase_ResetEvent(m_msgEvent);
|
||||
}
|
||||
HGBase_LeaveLock(m_msgLock);
|
||||
|
||||
if (!getMsg)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (0 == msg.id)
|
||||
{
|
||||
assert(NULL == msg.data);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
func((HGMsgPump)this, &msg, param);
|
||||
}
|
||||
}
|
||||
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGMsgPumpImpl::PostMessage(const HGMsg* msg)
|
||||
{
|
||||
if (NULL == msg || 0 == msg->id)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGResult ret = HGBASE_ERR_FAIL;
|
||||
HGBase_EnterLock(m_msgLock);
|
||||
if (m_bRecvMsg)
|
||||
{
|
||||
m_listMsg.push_back(*msg);
|
||||
HGBase_SetEvent(m_msgEvent);
|
||||
ret = HGBASE_ERR_OK;
|
||||
}
|
||||
HGBase_LeaveLock(m_msgLock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGResult HGMsgPumpImpl::Exit()
|
||||
{
|
||||
HGMsg msg;
|
||||
msg.id = 0;
|
||||
msg.data = NULL;
|
||||
|
||||
HGResult ret = HGBASE_ERR_FAIL;
|
||||
HGBase_EnterLock(m_msgLock);
|
||||
if (m_bRecvMsg)
|
||||
{
|
||||
m_listMsg.push_back(msg);
|
||||
HGBase_SetEvent(m_msgEvent);
|
||||
m_bRecvMsg = HGFALSE;
|
||||
ret = HGBASE_ERR_OK;
|
||||
}
|
||||
HGBase_LeaveLock(m_msgLock);
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef __HGMSGPUMPIMPL_H__
|
||||
#define __HGMSGPUMPIMPL_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGInc.h"
|
||||
#include "HGEvent.h"
|
||||
#include "HGLock.h"
|
||||
#include "HGMsgPump.h"
|
||||
#include <list>
|
||||
|
||||
class HGMsgPumpImpl
|
||||
{
|
||||
public:
|
||||
HGMsgPumpImpl();
|
||||
~HGMsgPumpImpl();
|
||||
|
||||
HGResult Run(HGMsgPumpFunc func, HGPointer param);
|
||||
HGResult PostMessage(const HGMsg* msg);
|
||||
HGResult Exit();
|
||||
|
||||
private:
|
||||
HGEvent m_msgEvent;
|
||||
HGLock m_msgLock;
|
||||
HGBool m_bRecvMsg;
|
||||
std::list<HGMsg> m_listMsg;
|
||||
};
|
||||
|
||||
#endif /* __HGMSGPUMPIMPL_H__ */
|
|
@ -0,0 +1,621 @@
|
|||
#include "HGNamedPipe.h"
|
||||
#include "HGInc.h"
|
||||
#include "HGThread.h"
|
||||
#include <string>
|
||||
|
||||
struct HGNamedPipeServerImpl
|
||||
{
|
||||
HGNamedPipeServerImpl()
|
||||
{
|
||||
#if defined(HG_CMP_MSC)
|
||||
m_hConnectEvent = NULL;
|
||||
m_hWriteEvent = NULL;
|
||||
m_hReadEvent = NULL;
|
||||
m_hProcessEvent = NULL;
|
||||
m_hPipe = INVALID_HANDLE_VALUE;
|
||||
m_clientPid = 0;
|
||||
m_thread = NULL;
|
||||
m_error = HGFALSE;
|
||||
m_break = HGFALSE;
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
}
|
||||
|
||||
~HGNamedPipeServerImpl()
|
||||
{
|
||||
#if defined(HG_CMP_MSC)
|
||||
HGBase_CloseThread(m_thread);
|
||||
m_thread = NULL;
|
||||
CloseHandle(m_hPipe);
|
||||
m_hPipe = INVALID_HANDLE_VALUE;
|
||||
CloseHandle(m_hProcessEvent);
|
||||
m_hProcessEvent = NULL;
|
||||
CloseHandle(m_hReadEvent);
|
||||
m_hReadEvent = NULL;
|
||||
CloseHandle(m_hWriteEvent);
|
||||
m_hWriteEvent = NULL;
|
||||
CloseHandle(m_hConnectEvent);
|
||||
m_hConnectEvent = NULL;
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
HANDLE m_hConnectEvent;
|
||||
HANDLE m_hWriteEvent;
|
||||
HANDLE m_hReadEvent;
|
||||
HANDLE m_hProcessEvent;
|
||||
HANDLE m_hPipe;
|
||||
DWORD m_clientPid;
|
||||
HGThread m_thread;
|
||||
HGBool m_error;
|
||||
HGBool m_break;
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
};
|
||||
|
||||
struct HGNamedPipeClientImpl
|
||||
{
|
||||
HGNamedPipeClientImpl()
|
||||
{
|
||||
#if defined(HG_CMP_MSC)
|
||||
m_hWriteEvent = NULL;
|
||||
m_hReadEvent = NULL;
|
||||
m_hProcessEvent = NULL;
|
||||
m_hPipe = INVALID_HANDLE_VALUE;
|
||||
m_serverPid = 0;
|
||||
m_thread = NULL;
|
||||
m_error = HGFALSE;
|
||||
m_break = HGFALSE;
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
}
|
||||
|
||||
~HGNamedPipeClientImpl()
|
||||
{
|
||||
#if defined(HG_CMP_MSC)
|
||||
HGBase_CloseThread(m_thread);
|
||||
m_thread = NULL;
|
||||
CloseHandle(m_hPipe);
|
||||
m_hPipe = INVALID_HANDLE_VALUE;
|
||||
CloseHandle(m_hProcessEvent);
|
||||
m_hProcessEvent = NULL;
|
||||
CloseHandle(m_hReadEvent);
|
||||
m_hReadEvent = NULL;
|
||||
CloseHandle(m_hWriteEvent);
|
||||
m_hWriteEvent = NULL;
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
HANDLE m_hWriteEvent;
|
||||
HANDLE m_hReadEvent;
|
||||
HANDLE m_hProcessEvent;
|
||||
HANDLE m_hPipe;
|
||||
DWORD m_serverPid;
|
||||
HGThread m_thread;
|
||||
HGBool m_error;
|
||||
HGBool m_break;
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
};
|
||||
|
||||
static void HGAPI NamedPipeServerFunc(HGThread thread, HGPointer param)
|
||||
{
|
||||
HGNamedPipeServerImpl* p = (HGNamedPipeServerImpl*)param;
|
||||
#if defined(HG_CMP_MSC)
|
||||
HANDLE handles[2];
|
||||
handles[0] = OpenProcess(SYNCHRONIZE, FALSE, p->m_clientPid);
|
||||
handles[1] = p->m_hProcessEvent;
|
||||
if (WAIT_OBJECT_0 == WaitForMultipleObjects(2, handles, FALSE, INFINITE))
|
||||
{
|
||||
p->m_error = HGTRUE;
|
||||
SetEvent(p->m_hWriteEvent);
|
||||
SetEvent(p->m_hReadEvent);
|
||||
}
|
||||
|
||||
CloseHandle(handles[0]);
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
}
|
||||
|
||||
static void NamedPipeClientFunc(HGThread thread, HGPointer param)
|
||||
{
|
||||
HGNamedPipeClientImpl* p = (HGNamedPipeClientImpl*)param;
|
||||
#if defined(HG_CMP_MSC)
|
||||
HANDLE handles[2];
|
||||
handles[0] = OpenProcess(SYNCHRONIZE, FALSE, p->m_serverPid);
|
||||
handles[1] = p->m_hProcessEvent;
|
||||
if (WAIT_OBJECT_0 == WaitForMultipleObjects(2, handles, FALSE, INFINITE))
|
||||
{
|
||||
p->m_error = HGTRUE;
|
||||
SetEvent(p->m_hWriteEvent);
|
||||
SetEvent(p->m_hReadEvent);
|
||||
}
|
||||
|
||||
CloseHandle(handles[0]);
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_OpenNamedPipeServer(const HGChar* pipeName, HGNamedPipeServer* server)
|
||||
{
|
||||
if (NULL == pipeName || NULL == server)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
HANDLE hConnectEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
|
||||
assert(NULL != hConnectEvent);
|
||||
HANDLE hWriteEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
|
||||
assert(NULL != hWriteEvent);
|
||||
HANDLE hReadEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
|
||||
assert(NULL != hReadEvent);
|
||||
HANDLE hProcessEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
|
||||
assert(NULL != hProcessEvent);
|
||||
|
||||
char name[256];
|
||||
sprintf(name, "\\\\.\\pipe\\%s", pipeName);
|
||||
HANDLE hPipe = CreateNamedPipeA(name, PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
|
||||
0, 1, 1024, 1024, 0, NULL);
|
||||
if (INVALID_HANDLE_VALUE == hPipe)
|
||||
{
|
||||
CloseHandle(hProcessEvent);
|
||||
CloseHandle(hReadEvent);
|
||||
CloseHandle(hWriteEvent);
|
||||
CloseHandle(hConnectEvent);
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
HGNamedPipeServerImpl* pipeServerImpl = new HGNamedPipeServerImpl;
|
||||
pipeServerImpl->m_hConnectEvent = hConnectEvent;
|
||||
pipeServerImpl->m_hWriteEvent = hWriteEvent;
|
||||
pipeServerImpl->m_hReadEvent = hReadEvent;
|
||||
pipeServerImpl->m_hProcessEvent = hProcessEvent;
|
||||
pipeServerImpl->m_hPipe = hPipe;
|
||||
*server = (HGNamedPipeServer)pipeServerImpl;
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_CloseNamedPipeServer(HGNamedPipeServer server)
|
||||
{
|
||||
if (NULL == server)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGNamedPipeServerImpl* pipeServerImpl = (HGNamedPipeServerImpl*)server;
|
||||
delete pipeServerImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_NamedPipeServerWrite(HGNamedPipeServer server, const HGByte* data, HGUInt size, HGUInt* writeSize)
|
||||
{
|
||||
if (NULL == server || NULL == data || 0 == size)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGNamedPipeServerImpl* pipeServerImpl = (HGNamedPipeServerImpl*)server;
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (NULL == pipeServerImpl->m_thread || pipeServerImpl->m_error || pipeServerImpl->m_break)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
OVERLAPPED overlapped = { 0 };
|
||||
overlapped.hEvent = pipeServerImpl->m_hWriteEvent;
|
||||
DWORD dwNumerOfWriteBytes = 0;
|
||||
if (!WriteFile(pipeServerImpl->m_hPipe, data, size, &dwNumerOfWriteBytes, &overlapped))
|
||||
{
|
||||
if (ERROR_IO_PENDING != GetLastError())
|
||||
{
|
||||
// 写入错误
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
WaitForSingleObject(pipeServerImpl->m_hWriteEvent, INFINITE);
|
||||
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwNumerOfWriteBytes, TRUE))
|
||||
{
|
||||
// 手动停止
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != writeSize)
|
||||
*writeSize = dwNumerOfWriteBytes;
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_NamedPipeServerRead(HGNamedPipeServer server, HGByte* data, HGUInt size, HGUInt* readSize)
|
||||
{
|
||||
if (NULL == server || NULL == data || 0 == size)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGNamedPipeServerImpl* pipeServerImpl = (HGNamedPipeServerImpl*)server;
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (NULL == pipeServerImpl->m_thread) // 未连接
|
||||
{
|
||||
OVERLAPPED overlapped = { 0 };
|
||||
overlapped.hEvent = pipeServerImpl->m_hConnectEvent;
|
||||
if (!ConnectNamedPipe(pipeServerImpl->m_hPipe, &overlapped))
|
||||
{
|
||||
DWORD err = GetLastError();
|
||||
if (ERROR_IO_PENDING != err && ERROR_PIPE_CONNECTED != err)
|
||||
{
|
||||
// 等待连接出错
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
if (ERROR_IO_PENDING == err)
|
||||
{
|
||||
// 等待连接
|
||||
WaitForSingleObject(pipeServerImpl->m_hConnectEvent, INFINITE);
|
||||
DWORD dwTransferBytes = 0; // 此值无意义
|
||||
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwTransferBytes, TRUE))
|
||||
{
|
||||
// 手动停止
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 读取对方进程ID
|
||||
memset(&overlapped, 0, sizeof(OVERLAPPED));
|
||||
overlapped.hEvent = pipeServerImpl->m_hReadEvent;
|
||||
DWORD dwNumerOfReadBytes = 0;
|
||||
DWORD clientPid = 0;
|
||||
if (!ReadFile(pipeServerImpl->m_hPipe, &clientPid, sizeof(DWORD), &dwNumerOfReadBytes, &overlapped))
|
||||
{
|
||||
if (ERROR_IO_PENDING != GetLastError())
|
||||
{
|
||||
// 读取错误
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
WaitForSingleObject(pipeServerImpl->m_hReadEvent, INFINITE);
|
||||
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwNumerOfReadBytes, TRUE))
|
||||
{
|
||||
// 手动停止
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
}
|
||||
if (sizeof(DWORD) != dwNumerOfReadBytes || 0 == clientPid)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
// 发送己方进程ID
|
||||
memset(&overlapped, 0, sizeof(OVERLAPPED));
|
||||
overlapped.hEvent = pipeServerImpl->m_hWriteEvent;
|
||||
DWORD dwNumerOfWriteBytes = 0;
|
||||
DWORD serverPid = GetCurrentProcessId();
|
||||
if (!WriteFile(pipeServerImpl->m_hPipe, &serverPid, sizeof(DWORD), &dwNumerOfWriteBytes, &overlapped))
|
||||
{
|
||||
if (ERROR_IO_PENDING != GetLastError())
|
||||
{
|
||||
// 写入错误
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
WaitForSingleObject(pipeServerImpl->m_hWriteEvent, INFINITE);
|
||||
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwNumerOfWriteBytes, TRUE))
|
||||
{
|
||||
// 手动停止
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
}
|
||||
if (sizeof(DWORD) != dwNumerOfWriteBytes)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
// 创建线程等待对方进程ID
|
||||
pipeServerImpl->m_clientPid = clientPid;
|
||||
HGBase_OpenThread(NamedPipeServerFunc, pipeServerImpl, &pipeServerImpl->m_thread);
|
||||
assert(NULL != pipeServerImpl->m_thread);
|
||||
}
|
||||
|
||||
if (pipeServerImpl->m_error || pipeServerImpl->m_break)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
OVERLAPPED overlapped = { 0 };
|
||||
overlapped.hEvent = pipeServerImpl->m_hReadEvent;
|
||||
DWORD dwNumerOfReadBytes = 0;
|
||||
if (!ReadFile(pipeServerImpl->m_hPipe, data, size, &dwNumerOfReadBytes, &overlapped))
|
||||
{
|
||||
if (ERROR_IO_PENDING != GetLastError())
|
||||
{
|
||||
// 读取错误
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
WaitForSingleObject(pipeServerImpl->m_hReadEvent, INFINITE);
|
||||
if (!GetOverlappedResult(pipeServerImpl->m_hPipe, &overlapped, &dwNumerOfReadBytes, TRUE))
|
||||
{
|
||||
// 手动停止
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != readSize)
|
||||
*readSize = dwNumerOfReadBytes;
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_NamedPipeServerStop(HGNamedPipeServer server)
|
||||
{
|
||||
if (NULL == server)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGNamedPipeServerImpl* pipeServerImpl = (HGNamedPipeServerImpl*)server;
|
||||
#if defined(HG_CMP_MSC)
|
||||
pipeServerImpl->m_break = HGTRUE;
|
||||
SetEvent(pipeServerImpl->m_hConnectEvent);
|
||||
SetEvent(pipeServerImpl->m_hWriteEvent);
|
||||
SetEvent(pipeServerImpl->m_hReadEvent);
|
||||
SetEvent(pipeServerImpl->m_hProcessEvent);
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_OpenNamedPipeClient(const HGChar* pipeName, HGNamedPipeClient* client)
|
||||
{
|
||||
if (NULL == pipeName || NULL == client)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
HANDLE hWriteEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
|
||||
assert(NULL != hWriteEvent);
|
||||
HANDLE hReadEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
|
||||
assert(NULL != hReadEvent);
|
||||
HANDLE hProcessEvent = CreateEventA(NULL, TRUE, FALSE, NULL);
|
||||
assert(NULL != hProcessEvent);
|
||||
|
||||
char name[256];
|
||||
sprintf(name, "\\\\.\\pipe\\%s", pipeName);
|
||||
HANDLE hPipe = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
||||
if (INVALID_HANDLE_VALUE == hPipe)
|
||||
{
|
||||
CloseHandle(hProcessEvent);
|
||||
CloseHandle(hReadEvent);
|
||||
CloseHandle(hWriteEvent);
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
// 发送己方进程ID
|
||||
OVERLAPPED overlapped = { 0 };
|
||||
overlapped.hEvent = hWriteEvent;
|
||||
DWORD dwNumerOfWriteBytes = 0;
|
||||
DWORD clientPid = GetCurrentProcessId();
|
||||
if (!WriteFile(hPipe, &clientPid, sizeof(DWORD), &dwNumerOfWriteBytes, &overlapped))
|
||||
{
|
||||
if (ERROR_IO_PENDING != GetLastError())
|
||||
{
|
||||
// 写入错误
|
||||
CloseHandle(hPipe);
|
||||
CloseHandle(hProcessEvent);
|
||||
CloseHandle(hReadEvent);
|
||||
CloseHandle(hWriteEvent);
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
WaitForSingleObject(hWriteEvent, INFINITE);
|
||||
if (!GetOverlappedResult(hPipe, &overlapped, &dwNumerOfWriteBytes, TRUE))
|
||||
{
|
||||
// 手动停止
|
||||
CloseHandle(hPipe);
|
||||
CloseHandle(hProcessEvent);
|
||||
CloseHandle(hReadEvent);
|
||||
CloseHandle(hWriteEvent);
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
}
|
||||
if (sizeof(DWORD) != dwNumerOfWriteBytes)
|
||||
{
|
||||
CloseHandle(hPipe);
|
||||
CloseHandle(hProcessEvent);
|
||||
CloseHandle(hReadEvent);
|
||||
CloseHandle(hWriteEvent);
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
// 读取对方进程ID
|
||||
memset(&overlapped, 0, sizeof(OVERLAPPED));
|
||||
overlapped.hEvent = hReadEvent;
|
||||
DWORD dwNumerOfReadBytes = 0;
|
||||
DWORD serverPid = 0;
|
||||
if (!ReadFile(hPipe, &serverPid, sizeof(DWORD), &dwNumerOfReadBytes, &overlapped))
|
||||
{
|
||||
if (ERROR_IO_PENDING != GetLastError())
|
||||
{
|
||||
// 读取错误
|
||||
CloseHandle(hPipe);
|
||||
CloseHandle(hProcessEvent);
|
||||
CloseHandle(hReadEvent);
|
||||
CloseHandle(hWriteEvent);
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
WaitForSingleObject(hReadEvent, INFINITE);
|
||||
if (!GetOverlappedResult(hPipe, &overlapped, &dwNumerOfReadBytes, TRUE))
|
||||
{
|
||||
// 手动停止
|
||||
CloseHandle(hPipe);
|
||||
CloseHandle(hProcessEvent);
|
||||
CloseHandle(hReadEvent);
|
||||
CloseHandle(hWriteEvent);
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
}
|
||||
if (sizeof(DWORD) != dwNumerOfReadBytes || 0 == serverPid)
|
||||
{
|
||||
CloseHandle(hPipe);
|
||||
CloseHandle(hProcessEvent);
|
||||
CloseHandle(hReadEvent);
|
||||
CloseHandle(hWriteEvent);
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
// 创建线程等待对方进程ID
|
||||
|
||||
HGNamedPipeClientImpl* pipeClientImpl = new HGNamedPipeClientImpl;
|
||||
pipeClientImpl->m_hWriteEvent = hWriteEvent;
|
||||
pipeClientImpl->m_hReadEvent = hReadEvent;
|
||||
pipeClientImpl->m_hProcessEvent = hProcessEvent;
|
||||
pipeClientImpl->m_hPipe = hPipe;
|
||||
pipeClientImpl->m_serverPid = serverPid;
|
||||
HGBase_OpenThread(NamedPipeServerFunc, pipeClientImpl, &pipeClientImpl->m_thread);
|
||||
assert(NULL != pipeClientImpl->m_thread);
|
||||
*client = (HGNamedPipeClient)pipeClientImpl;
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_CloseNamedPipeClient(HGNamedPipeClient client)
|
||||
{
|
||||
if (NULL == client)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGNamedPipeClientImpl* pipeClientImpl = (HGNamedPipeClientImpl*)client;
|
||||
delete pipeClientImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_NamedPipeClientWrite(HGNamedPipeClient client, const HGByte* data, HGUInt size, HGUInt* writeSize)
|
||||
{
|
||||
if (NULL == client)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGNamedPipeClientImpl* pipeClientImpl = (HGNamedPipeClientImpl*)client;
|
||||
#if defined(HG_CMP_MSC)
|
||||
assert(NULL != pipeClientImpl->m_thread);
|
||||
|
||||
if (pipeClientImpl->m_error || pipeClientImpl->m_break)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
OVERLAPPED overlapped = { 0 };
|
||||
overlapped.hEvent = pipeClientImpl->m_hWriteEvent;
|
||||
DWORD dwNumerOfWriteBytes = 0;
|
||||
if (!WriteFile(pipeClientImpl->m_hPipe, data, size, &dwNumerOfWriteBytes, &overlapped))
|
||||
{
|
||||
if (ERROR_IO_PENDING != GetLastError())
|
||||
{
|
||||
// 写入错误
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
WaitForSingleObject(pipeClientImpl->m_hWriteEvent, INFINITE);
|
||||
if (!GetOverlappedResult(pipeClientImpl->m_hPipe, &overlapped, &dwNumerOfWriteBytes, TRUE))
|
||||
{
|
||||
// 手动停止
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
}
|
||||
if (NULL != writeSize)
|
||||
*writeSize = dwNumerOfWriteBytes;
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_NamedPipeClientRead(HGNamedPipeClient client, HGByte* data, HGUInt size, HGUInt* readSize)
|
||||
{
|
||||
if (NULL == client)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGNamedPipeClientImpl* pipeClientImpl = (HGNamedPipeClientImpl*)client;
|
||||
#if defined(HG_CMP_MSC)
|
||||
assert(NULL != pipeClientImpl->m_thread);
|
||||
|
||||
if (pipeClientImpl->m_error || pipeClientImpl->m_break)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
OVERLAPPED overlapped = { 0 };
|
||||
overlapped.hEvent = pipeClientImpl->m_hReadEvent;
|
||||
DWORD dwNumerOfReadBytes = 0;
|
||||
if (!ReadFile(pipeClientImpl->m_hPipe, data, size, &dwNumerOfReadBytes, &overlapped))
|
||||
{
|
||||
if (ERROR_IO_PENDING != GetLastError())
|
||||
{
|
||||
// 读取错误
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
WaitForSingleObject(pipeClientImpl->m_hReadEvent, INFINITE);
|
||||
if (!GetOverlappedResult(pipeClientImpl->m_hPipe, &overlapped, &dwNumerOfReadBytes, TRUE))
|
||||
{
|
||||
// 手动停止
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != readSize)
|
||||
*readSize = dwNumerOfReadBytes;
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_NamedPipeClientStop(HGNamedPipeClient client)
|
||||
{
|
||||
if (NULL == client)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGNamedPipeClientImpl* pipeClientImpl = (HGNamedPipeClientImpl*)client;
|
||||
#if defined(HG_CMP_MSC)
|
||||
pipeClientImpl->m_break = HGTRUE;
|
||||
SetEvent(pipeClientImpl->m_hWriteEvent);
|
||||
SetEvent(pipeClientImpl->m_hReadEvent);
|
||||
SetEvent(pipeClientImpl->m_hProcessEvent);
|
||||
#else
|
||||
// TODO
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef __HGNAMEDPIPE_H__
|
||||
#define __HGNAMEDPIPE_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
HG_DECLARE_HANDLE(HGNamedPipeServer);
|
||||
HG_DECLARE_HANDLE(HGNamedPipeClient);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_OpenNamedPipeServer(const HGChar* pipeName, HGNamedPipeServer *server);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_CloseNamedPipeServer(HGNamedPipeServer server);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_NamedPipeServerWrite(HGNamedPipeServer server, const HGByte* data, HGUInt size, HGUInt* writeSize);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_NamedPipeServerRead(HGNamedPipeServer server, HGByte* data, HGUInt size, HGUInt* readSize);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_NamedPipeServerStop(HGNamedPipeServer server);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_OpenNamedPipeClient(const HGChar* pipeName, HGNamedPipeClient* client);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_CloseNamedPipeClient(HGNamedPipeClient client);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_NamedPipeClientWrite(HGNamedPipeClient client, const HGByte* data, HGUInt size, HGUInt* writeSize);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_NamedPipeClientRead(HGNamedPipeClient client, HGByte* data, HGUInt size, HGUInt* readSize);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_NamedPipeClientStop(HGNamedPipeClient client);
|
||||
|
||||
#endif /* __HGNAMEDPIPE_H__ */
|
|
@ -0,0 +1,102 @@
|
|||
#include "HGThread.h"
|
||||
#include "HGInc.h"
|
||||
|
||||
struct HGThreadImpl
|
||||
{
|
||||
HGThreadImpl()
|
||||
{
|
||||
#if !defined(HG_CMP_MSC)
|
||||
m_ntid = 0;
|
||||
#else
|
||||
m_thread = NULL;
|
||||
#endif
|
||||
m_func = NULL;
|
||||
m_param = 0;
|
||||
}
|
||||
|
||||
~HGThreadImpl()
|
||||
{
|
||||
#if !defined(HG_CMP_MSC)
|
||||
if (0 != m_ntid)
|
||||
{
|
||||
pthread_join(m_ntid, NULL);
|
||||
m_ntid = 0;
|
||||
}
|
||||
#else
|
||||
if (NULL != m_thread)
|
||||
{
|
||||
WaitForSingleObject(m_thread, INFINITE);
|
||||
CloseHandle(m_thread);
|
||||
m_thread = NULL;
|
||||
}
|
||||
#endif
|
||||
m_param = 0;
|
||||
m_func = NULL;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
static void* thread_fun(void* arg)
|
||||
{
|
||||
HGThreadImpl* p = (HGThreadImpl*)arg;
|
||||
p->m_func((HGThread)p, p->m_param);
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
static DWORD WINAPI ThreadCallback(LPVOID param)
|
||||
{
|
||||
HGThreadImpl* p = (HGThreadImpl*)param;
|
||||
p->m_func((HGThread)p, p->m_param);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
pthread_t m_ntid;
|
||||
#else
|
||||
HANDLE m_thread;
|
||||
#endif
|
||||
HGThreadFunc m_func;
|
||||
HGPointer m_param;
|
||||
};
|
||||
|
||||
HGResult HGAPI HGBase_OpenThread(HGThreadFunc func, HGPointer param, HGThread* thread)
|
||||
{
|
||||
if (NULL == func || NULL == thread)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGThreadImpl* threadImpl = new HGThreadImpl;
|
||||
threadImpl->m_func = func;
|
||||
threadImpl->m_param = param;
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
if (0 != pthread_create(&threadImpl->m_ntid, NULL, HGThreadImpl::thread_fun, threadImpl))
|
||||
{
|
||||
delete threadImpl;
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
#else
|
||||
threadImpl->m_thread = CreateThread(NULL, 0, HGThreadImpl::ThreadCallback, threadImpl, 0, NULL);
|
||||
if (NULL == threadImpl->m_thread)
|
||||
{
|
||||
delete threadImpl;
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
* thread = (HGThread)threadImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_CloseThread(HGThread thread)
|
||||
{
|
||||
if (NULL == thread)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGThreadImpl* threadImpl = (HGThreadImpl*)thread;
|
||||
delete threadImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef __HGTHREAD_H__
|
||||
#define __HGTHREAD_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
HG_DECLARE_HANDLE(HGThread);
|
||||
|
||||
/* 线程回调函数
|
||||
* 参数:
|
||||
* 1) thread: in, 线程句柄
|
||||
* 2) param: in, 回调参数
|
||||
* 说明:
|
||||
*/
|
||||
typedef void (HGAPI *HGThreadFunc)(HGThread thread, HGPointer param);
|
||||
|
||||
/* 开启线程
|
||||
* 参数:
|
||||
* 1) func: in, 线程回调函数
|
||||
* 2) param: in, 回调参数
|
||||
* 3) thread: out, 线程句柄
|
||||
* 说明:
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_OpenThread(HGThreadFunc func, HGPointer param, HGThread *thread);
|
||||
|
||||
/* 关闭线程
|
||||
* 参数:
|
||||
* 1) thread: in, 线程句柄
|
||||
* 说明:
|
||||
* 1) 该函数会等待线程正常结束, 如果线程阻塞, 该函数也会阻塞
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CloseThread(HGThread thread);
|
||||
|
||||
#endif /* __HGTHREAD_H__ */
|
|
@ -0,0 +1,37 @@
|
|||
#include "HGTime.h"
|
||||
#include "HGInc.h"
|
||||
|
||||
HGResult HGAPI HGBase_GetLocalTime(HGTimeInfo* timeInfo)
|
||||
{
|
||||
if (NULL == timeInfo)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
SYSTEMTIME st;
|
||||
GetLocalTime(&st);
|
||||
timeInfo->year = st.wYear;
|
||||
timeInfo->month = st.wMonth;
|
||||
timeInfo->day = st.wDay;
|
||||
timeInfo->dayOfWeek = st.wDayOfWeek;
|
||||
timeInfo->hour = st.wHour;
|
||||
timeInfo->minute = st.wMinute;
|
||||
timeInfo->second = st.wSecond;
|
||||
timeInfo->milliseconds = st.wMilliseconds;
|
||||
#else
|
||||
struct timeval time;
|
||||
gettimeofday(&time, NULL);
|
||||
struct tm* p = localtime(&time.tv_sec);
|
||||
assert(NULL != p);
|
||||
timeInfo->year = p->tm_year + 1900;
|
||||
timeInfo->month = 1 + p->tm_mon;
|
||||
timeInfo->day = p->tm_mday;
|
||||
timeInfo->dayOfWeek = p->tm_wday;
|
||||
timeInfo->hour = p->tm_hour;
|
||||
timeInfo->minute = p->tm_min;
|
||||
timeInfo->second = p->tm_sec;
|
||||
timeInfo->milliseconds = time.tv_usec / 1000;
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef __HGTIME_H__
|
||||
#define __HGTIME_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGUShort year;
|
||||
HGUShort month;
|
||||
HGUShort day;
|
||||
HGUShort dayOfWeek; /* 0为星期天, 1-6表示星期一到星期六 */
|
||||
HGUShort hour;
|
||||
HGUShort minute;
|
||||
HGUShort second;
|
||||
HGUShort milliseconds;
|
||||
}HGTimeInfo;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
HGEXPORT HGResult HGAPI HGBase_GetLocalTime(HGTimeInfo *timeInfo);
|
||||
|
||||
#endif /* __HGTIME_H__ */
|
|
@ -0,0 +1,650 @@
|
|||
#include "HGUtility.h"
|
||||
#include "HGInc.h"
|
||||
#include "HGInfo.h"
|
||||
#include "HGIni.h"
|
||||
#if defined(HG_CMP_MSC)
|
||||
#include <shlobj.h>
|
||||
#include <atlstr.h>
|
||||
#else
|
||||
#include "uuid/uuid.h"
|
||||
#endif
|
||||
#include <string>
|
||||
|
||||
HGResult HGAPI HGBase_GetTmpPath(HGChar* path, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == path || 0 == maxLen)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
char tmpPath[512] = {0};
|
||||
strcpy(tmpPath, "/tmp/");
|
||||
#else
|
||||
CHAR tmpPath[MAX_PATH] = { 0 };
|
||||
DWORD len = GetTempPathA(MAX_PATH, tmpPath);
|
||||
if (0 == len)
|
||||
return HGBASE_ERR_FAIL;
|
||||
if (tmpPath[strlen(tmpPath) - 1] != '\\')
|
||||
strcat(tmpPath, "\\");
|
||||
#endif
|
||||
|
||||
if (maxLen < strlen(tmpPath) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(path, tmpPath);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetCurrentDir(HGChar* dir, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == dir || 0 == maxLen)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
char buffer[512] = { 0 };
|
||||
char* p = getcwd(buffer, 512);
|
||||
if (NULL == p)
|
||||
return HGBASE_ERR_FAIL;
|
||||
if (buffer[strlen(buffer) - 1] != '/')
|
||||
strcat(buffer, "/");
|
||||
#else
|
||||
CHAR buffer[MAX_PATH] = { 0 };
|
||||
DWORD len = GetCurrentDirectoryA(MAX_PATH, buffer);
|
||||
if (0 == len)
|
||||
return HGBASE_ERR_FAIL;
|
||||
if (buffer[strlen(buffer) - 1] != '\\')
|
||||
strcat(buffer, "\\");
|
||||
#endif
|
||||
|
||||
if (maxLen < strlen(buffer) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(dir, buffer);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_SetCurrentDir(const HGChar* dir)
|
||||
{
|
||||
if (NULL == dir)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
if (0 != chdir(dir))
|
||||
return HGBASE_ERR_FAIL;
|
||||
#else
|
||||
if (!SetCurrentDirectoryA(dir))
|
||||
return HGBASE_ERR_FAIL;
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_CreateDir(const HGChar* dir)
|
||||
{
|
||||
if (NULL == dir)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
bool ret = true;
|
||||
|
||||
char muldir[512] = { 0 };
|
||||
strcpy(muldir, dir);
|
||||
for (size_t i = 0; i < strlen(muldir); ++i)
|
||||
{
|
||||
if ('/' == muldir[i])
|
||||
{
|
||||
muldir[i] = '\0';
|
||||
if ('\0' != *muldir && 0 != access(muldir, 0))
|
||||
{
|
||||
if (0 != mkdir(muldir, 0777))
|
||||
{
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "HGBase_CreateDir: mkdir fail, %s errno=%d", dir, errno);
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
muldir[i] = '/';
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
if ('\0' != *muldir && 0 != access(muldir, 0))
|
||||
{
|
||||
if (0 != mkdir(muldir, 0777))
|
||||
{
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "HGBase_CreateDir: mkdir fail, %s errno=%d", dir, errno);
|
||||
ret = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
#else
|
||||
int ret = SHCreateDirectoryExA(NULL, dir, NULL);
|
||||
if (ERROR_SUCCESS != ret && ERROR_ALREADY_EXISTS != ret)
|
||||
{
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "HGBase_CreateDir: SHCreateDirectoryExA fail, %s GetLastError=%u", dir, GetLastError());
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
}
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_DeleteDir(const HGChar* dir)
|
||||
{
|
||||
if (NULL == dir)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
if (0 != rmdir(dir))
|
||||
return HGBASE_ERR_FAIL;
|
||||
#else
|
||||
if (!RemoveDirectoryA(dir))
|
||||
return HGBASE_ERR_FAIL;
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_DeleteFile(const HGChar* fileName)
|
||||
{
|
||||
if (NULL == fileName)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
if (0 != unlink(fileName))
|
||||
return HGBASE_ERR_FAIL;
|
||||
#else
|
||||
if (!DeleteFileA(fileName))
|
||||
return HGBASE_ERR_FAIL;
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetModuleName(HGPointer addr, HGChar* name, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == name || 0 == maxLen)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
if (NULL == addr)
|
||||
{
|
||||
char dir[PATH_MAX] = {0};
|
||||
if (0 == readlink("/proc/self/exe", dir, PATH_MAX))
|
||||
return HGBASE_ERR_FAIL;
|
||||
if (maxLen < strlen(dir) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(name, dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
Dl_info dlinfo;
|
||||
if (0 == dladdr(addr, &dlinfo))
|
||||
return HGBASE_ERR_FAIL;
|
||||
if (maxLen < strlen(dlinfo.dli_fname) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(name, dlinfo.dli_fname);
|
||||
}
|
||||
#else
|
||||
HMODULE hModule = NULL;
|
||||
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
|
||||
| GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR)addr, &hModule);
|
||||
|
||||
CHAR moduleName[MAX_PATH] = { 0 };
|
||||
DWORD len = GetModuleFileNameA(hModule, moduleName, MAX_PATH);
|
||||
if (0 == len || maxLen < strlen(moduleName) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(name, moduleName);
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetUuid(HGChar* uuid, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == uuid || 0 == maxLen)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if !defined(HG_CMP_MSC)
|
||||
uuid_t id;
|
||||
uuid_generate(id);
|
||||
|
||||
char str[128] = {0};
|
||||
uuid_unparse(id, str);
|
||||
if (maxLen < strlen(str) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(uuid, str);
|
||||
#else
|
||||
GUID guid;
|
||||
if (S_OK != CoCreateGuid(&guid))
|
||||
return HGBASE_ERR_FAIL;
|
||||
|
||||
char str[128] = {0};
|
||||
sprintf(str, "%08x%04x%04x%02x%02x%02x%02x%02x%02x%02x%02x", guid.Data1, guid.Data2, guid.Data3, guid.Data4[0], guid.Data4[1],
|
||||
guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]);
|
||||
if (maxLen < strlen(str) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(uuid, str);
|
||||
#endif
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetTmpFileName(const HGChar* suffix, HGChar* fileName, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == fileName || 0 == maxLen)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGChar path[256] = { 0 }, uuid[128] = {0};
|
||||
HGBase_GetTmpPath(path, 256);
|
||||
HGBase_GetUuid(uuid, 128);
|
||||
strcat(path, uuid);
|
||||
if (NULL != suffix && 0 != *suffix)
|
||||
{
|
||||
strcat(path, ".");
|
||||
strcat(path, suffix);
|
||||
}
|
||||
|
||||
if (maxLen < strlen(path) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(fileName, path);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetConfigPath(HGChar* configPath, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == configPath || 0 == maxLen)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGChar moduleName[256];
|
||||
HGBase_GetModuleName(NULL, moduleName, 256);
|
||||
HGChar modulePath[256];
|
||||
HGBase_GetFilePath(moduleName, modulePath, 256);
|
||||
strcat(modulePath, "first.cfg");
|
||||
|
||||
HGChar dataPath[256] = {0};
|
||||
HGBase_GetProfileString(modulePath, "constraints", "local_data_path", "", dataPath, 256);
|
||||
if ('\0' != *dataPath)
|
||||
{
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (dataPath[strlen(dataPath) - 1] != '\\')
|
||||
strcat(dataPath, "\\");
|
||||
strcat(dataPath, "Cfg\\");
|
||||
#else
|
||||
if (dataPath[strlen(dataPath) - 1] != '/')
|
||||
strcat(dataPath, "/");
|
||||
strcat(dataPath, "Cfg/");
|
||||
#endif
|
||||
|
||||
if (maxLen < strlen(dataPath) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(configPath, dataPath);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
CHAR cfgPath[MAX_PATH] = { 0 };
|
||||
BOOL ret = SHGetSpecialFolderPathA(NULL, cfgPath, CSIDL_APPDATA, FALSE);
|
||||
if (!ret)
|
||||
return HGBASE_ERR_FAIL;
|
||||
if (cfgPath[strlen(cfgPath) - 1] != '\\')
|
||||
strcat(cfgPath, "\\");
|
||||
|
||||
HGChar procName[64];
|
||||
HGBase_GetProcessName(procName, 64);
|
||||
strcat(cfgPath, procName);
|
||||
strcat(cfgPath, "\\Cfg\\");
|
||||
#else
|
||||
char cfgPath[512] = { 0 };
|
||||
strcpy(cfgPath, getenv("HOME"));
|
||||
if (cfgPath[strlen(cfgPath) - 1] != '/')
|
||||
strcat(cfgPath, "/");
|
||||
|
||||
strcat(cfgPath, ".");
|
||||
HGChar procName[64];
|
||||
HGBase_GetProcessName(procName, 64);
|
||||
strcat(cfgPath, procName);
|
||||
strcat(cfgPath, "/Cfg/");
|
||||
#endif
|
||||
|
||||
if (maxLen < strlen(cfgPath) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(configPath, cfgPath);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetLogFilePath(HGChar* logFilePath, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == logFilePath || 0 == maxLen)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGChar moduleName[256];
|
||||
HGBase_GetModuleName(NULL, moduleName, 256);
|
||||
HGChar modulePath[256];
|
||||
HGBase_GetFilePath(moduleName, modulePath, 256);
|
||||
strcat(modulePath, "first.cfg");
|
||||
|
||||
HGChar dataPath[256] = { 0 };
|
||||
HGBase_GetProfileString(modulePath, "constraints", "local_data_path", "", dataPath, 256);
|
||||
if ('\0' != *dataPath)
|
||||
{
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (dataPath[strlen(dataPath) - 1] != '\\')
|
||||
strcat(dataPath, "\\");
|
||||
strcat(dataPath, "Cfg\\");
|
||||
#else
|
||||
if (dataPath[strlen(dataPath) - 1] != '/')
|
||||
strcat(dataPath, "/");
|
||||
strcat(dataPath, "Cfg/");
|
||||
#endif
|
||||
|
||||
if (maxLen < strlen(dataPath) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(logFilePath, dataPath);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
CHAR logPath[MAX_PATH] = { 0 };
|
||||
BOOL ret = SHGetSpecialFolderPathA(NULL, logPath, CSIDL_APPDATA, FALSE);
|
||||
if (!ret)
|
||||
return HGBASE_ERR_FAIL;
|
||||
if (logPath[strlen(logPath) - 1] != '\\')
|
||||
strcat(logPath, "\\");
|
||||
|
||||
HGChar procName[64];
|
||||
HGBase_GetProcessName(procName, 64);
|
||||
strcat(logPath, procName);
|
||||
strcat(logPath, "\\Log\\");
|
||||
#else
|
||||
char logPath[512] = { 0 };
|
||||
strcpy(logPath, getenv("HOME"));
|
||||
if (logPath[strlen(logPath) - 1] != '/')
|
||||
strcat(logPath, "/");
|
||||
|
||||
strcat(logPath, ".");
|
||||
HGChar procName[64];
|
||||
HGBase_GetProcessName(procName, 64);
|
||||
strcat(logPath, procName);
|
||||
strcat(logPath, "/Log/");
|
||||
#endif
|
||||
|
||||
if (maxLen < strlen(logPath) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(logFilePath, logPath);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetDocumentsPath(HGChar* documentsPath, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == documentsPath || 0 == maxLen)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
CHAR docPath[MAX_PATH] = { 0 };
|
||||
BOOL ret = SHGetSpecialFolderPathA(NULL, docPath, CSIDL_MYDOCUMENTS, FALSE);
|
||||
if (!ret)
|
||||
return HGBASE_ERR_FAIL;
|
||||
if (docPath[strlen(docPath) - 1] != '\\')
|
||||
strcat(docPath, "\\");
|
||||
#else
|
||||
char docPath[512] = { 0 };
|
||||
strcpy(docPath, getenv("HOME"));
|
||||
if (docPath[strlen(docPath) - 1] != '/')
|
||||
strcat(docPath, "/");
|
||||
strcat(docPath, "Documents/");
|
||||
#endif
|
||||
|
||||
if (maxLen < strlen(docPath) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(documentsPath, docPath);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetProcessName(HGChar* name, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == name || 0 == maxLen)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
CHAR moduleName[MAX_PATH] = { 0 };
|
||||
DWORD len = GetModuleFileNameA(NULL, moduleName, MAX_PATH);
|
||||
if (0 == len)
|
||||
return HGBASE_ERR_FAIL;
|
||||
CStringA strModuleName(moduleName);
|
||||
int pos = strModuleName.ReverseFind('\\');
|
||||
if (-1 == pos)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strModuleName = strModuleName.Right(strModuleName.GetLength() - pos - 1);
|
||||
pos = strModuleName.ReverseFind('.');
|
||||
if (-1 != pos)
|
||||
strModuleName = strModuleName.Left(pos);
|
||||
if (maxLen < (HGUInt)strModuleName.GetLength() + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(name, strModuleName);
|
||||
#else
|
||||
char aucPathBuf[1024] = { 0 };
|
||||
if (readlink("/proc/self/exe", aucPathBuf, 1024) <= 0)
|
||||
return HGBASE_ERR_FAIL;
|
||||
const char* pcName = strrchr(aucPathBuf, '/');
|
||||
if (NULL == pcName)
|
||||
return HGBASE_ERR_FAIL;
|
||||
++pcName;
|
||||
std::string procName(pcName);
|
||||
const char* pcSuffix = strrchr(procName.c_str(), '.');
|
||||
if (NULL != pcSuffix)
|
||||
procName = procName.substr(0, pcSuffix - procName.c_str());
|
||||
if (maxLen < (HGUInt)procName.size() + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(name, procName.c_str());
|
||||
#endif
|
||||
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetFilePath(const HGChar* fileName, HGChar* path, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == fileName || NULL == path || 0 == maxLen)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
const char* pcName = strrchr(fileName, '\\');
|
||||
if (NULL == pcName)
|
||||
{
|
||||
pcName = strrchr(fileName, '/');
|
||||
if (NULL == pcName)
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
#else
|
||||
const char* pcName = strrchr(fileName, '/');
|
||||
if (NULL == pcName)
|
||||
return HGBASE_ERR_FAIL;
|
||||
#endif
|
||||
|
||||
++pcName;
|
||||
if (maxLen < (HGUInt)(pcName - fileName + 1))
|
||||
return HGBASE_ERR_FAIL;
|
||||
memcpy(path, fileName, pcName - fileName);
|
||||
path[pcName - fileName] = 0;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetFileName(const HGChar* fileName, HGChar* name, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == fileName || NULL == name || 0 == maxLen)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
const char* pcName = strrchr(fileName, '\\');
|
||||
if (NULL == pcName)
|
||||
{
|
||||
pcName = strrchr(fileName, '/');
|
||||
if (NULL == pcName)
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
#else
|
||||
const char* pcName = strrchr(fileName, '/');
|
||||
if (NULL == pcName)
|
||||
return HGBASE_ERR_FAIL;
|
||||
#endif
|
||||
|
||||
++pcName;
|
||||
if (maxLen < strlen(pcName) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(name, pcName);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetFilePrefix(const HGChar* fileName, HGChar* prefix, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == fileName || NULL == prefix || 0 == maxLen)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
CStringA strPrefix;
|
||||
CStringA strFileName(fileName);
|
||||
int pos = strFileName.ReverseFind('.');
|
||||
if (-1 == pos)
|
||||
strPrefix = strFileName;
|
||||
else
|
||||
{
|
||||
CStringA strSuffix = strFileName.Right(strFileName.GetLength() - pos - 1);
|
||||
if (-1 != strSuffix.Find('\\') || -1 != strSuffix.Find('/'))
|
||||
strPrefix = strFileName;
|
||||
else
|
||||
strPrefix = strFileName.Left(pos);
|
||||
}
|
||||
if (maxLen < (HGUInt)strPrefix.GetLength() + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(prefix, strPrefix);
|
||||
#else
|
||||
std::string strPrefix;
|
||||
const char* pcSuffix = strrchr(fileName, '.');
|
||||
if (NULL == pcSuffix)
|
||||
strPrefix = fileName;
|
||||
else
|
||||
{
|
||||
if (NULL != strchr(pcSuffix + 1, '/'))
|
||||
strPrefix = fileName;
|
||||
else
|
||||
strPrefix = std::string(fileName, pcSuffix - fileName);
|
||||
}
|
||||
if (maxLen < (HGUInt)strPrefix.size() + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(prefix, strPrefix.c_str());
|
||||
#endif
|
||||
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_GetFileSuffix(const HGChar* fileName, HGChar* suffix, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == fileName || NULL == suffix || 0 == maxLen)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
CStringA strFileName(fileName);
|
||||
int pos = strFileName.ReverseFind('.');
|
||||
if (-1 == pos)
|
||||
return HGBASE_ERR_FAIL;
|
||||
CStringA strSuffix = strFileName.Right(strFileName.GetLength() - pos - 1);
|
||||
if (-1 != strSuffix.Find('\\') || -1 != strSuffix.Find('/'))
|
||||
return HGBASE_ERR_FAIL;
|
||||
if (maxLen < (HGUInt)strSuffix.GetLength() + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(suffix, strSuffix);
|
||||
#else
|
||||
const char* pcSuffix = strrchr(fileName, '.');
|
||||
if (NULL == pcSuffix)
|
||||
return HGBASE_ERR_FAIL;
|
||||
++pcSuffix;
|
||||
if (NULL != strchr(pcSuffix, '/'))
|
||||
return HGBASE_ERR_FAIL;
|
||||
if (maxLen < (HGUInt)strlen(pcSuffix) + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(suffix, pcSuffix);
|
||||
#endif
|
||||
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGBase_StandardiseFileName(const HGChar* fileName, HGChar* result, HGUInt maxLen)
|
||||
{
|
||||
if (NULL == fileName || NULL == result || 0 == maxLen)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
std::string stdFileName;
|
||||
#if defined(HG_CMP_MSC)
|
||||
bool separator = false;
|
||||
for (const HGChar* p = fileName; *p != 0; ++p)
|
||||
{
|
||||
if (*p == '\\' || *p == '/')
|
||||
{
|
||||
if (!separator)
|
||||
{
|
||||
stdFileName.push_back('\\');
|
||||
separator = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stdFileName.push_back(*p);
|
||||
separator = false;
|
||||
}
|
||||
}
|
||||
#else
|
||||
bool separator = false;
|
||||
for (const HGChar* p = fileName; *p != 0; ++p)
|
||||
{
|
||||
if (*p == '/')
|
||||
{
|
||||
if (!separator)
|
||||
{
|
||||
stdFileName.push_back('/');
|
||||
separator = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
stdFileName.push_back(*p);
|
||||
separator = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (maxLen < (HGUInt)stdFileName.size() + 1)
|
||||
return HGBASE_ERR_FAIL;
|
||||
strcpy(result, stdFileName.c_str());
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
#ifndef __HGUTILITY_H__
|
||||
#define __HGUTILITY_H__
|
||||
|
||||
#include "HGDef.h"
|
||||
#include "HGBaseErr.h"
|
||||
|
||||
/* 获取系统临时文件目录
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetTmpPath(HGChar* path, HGUInt maxLen);
|
||||
|
||||
/* 获取进程的当前工作目录
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetCurrentDir(HGChar* dir, HGUInt maxLen);
|
||||
|
||||
/* 设置进程的当前工作目录
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_SetCurrentDir(const HGChar* dir);
|
||||
|
||||
/* 创建目录
|
||||
* 该函数可以创建多级目录
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_CreateDir(const HGChar* dir);
|
||||
|
||||
/* 删除目录
|
||||
* 该函数只能用于删除空目录
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_DeleteDir(const HGChar* dir);
|
||||
|
||||
/* 删除文件
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_DeleteFile(const HGChar* fileName);
|
||||
|
||||
/* 获取模块名称
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetModuleName(HGPointer addr, HGChar* name, HGUInt maxLen);
|
||||
|
||||
/* 获取UUID
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetUuid(HGChar* uuid, HGUInt maxLen);
|
||||
|
||||
/* 获取临时文件名
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetTmpFileName(const HGChar *suffix, HGChar* fileName, HGUInt maxLen);
|
||||
|
||||
/* 获取配置文件路径
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetConfigPath(HGChar* configPath, HGUInt maxLen);
|
||||
|
||||
/* 获取日志文件路径
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetLogFilePath(HGChar* logFilePath, HGUInt maxLen);
|
||||
|
||||
/* 获取文档路径
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetDocumentsPath(HGChar* documentsPath, HGUInt maxLen);
|
||||
|
||||
/* 获取进程名
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetProcessName(HGChar* name, HGUInt maxLen);
|
||||
|
||||
/* 通过文件全路径获取路径
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetFilePath(const HGChar* fileName, HGChar* path, HGUInt maxLen);
|
||||
|
||||
/* 通过文件全路径获取文件名
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetFileName(const HGChar* fileName, HGChar* name, HGUInt maxLen);
|
||||
|
||||
/* 通过文件名获取文件前缀
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetFilePrefix(const HGChar* fileName, HGChar* prefix, HGUInt maxLen);
|
||||
|
||||
/* 通过文件名获取文件后缀
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGBase_GetFileSuffix(const HGChar *fileName, HGChar* suffix, HGUInt maxLen);
|
||||
|
||||
/* 将文件名标准化 */
|
||||
HGEXPORT HGResult HGAPI HGBase_StandardiseFileName(const HGChar* fileName, HGChar *result, HGUInt maxLen);
|
||||
|
||||
#endif /* __HGUTILITY_H__ */
|
|
@ -0,0 +1,49 @@
|
|||
#include "HGDef.h"
|
||||
#include "HGInfoImpl.hpp"
|
||||
#include "HGInc.h"
|
||||
|
||||
extern HGInfoImpl* g_infoImpl;
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
|
||||
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
|
||||
{
|
||||
switch (ul_reason_for_call)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
{
|
||||
g_infoImpl = new HGInfoImpl;
|
||||
}
|
||||
break;
|
||||
case DLL_THREAD_ATTACH:
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
{
|
||||
delete g_infoImpl;
|
||||
g_infoImpl = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void __attribute__((constructor)) global_load(void);
|
||||
void __attribute__((destructor)) global_unload(void);
|
||||
|
||||
void global_load(void)
|
||||
{
|
||||
g_infoImpl = new HGInfoImpl;
|
||||
}
|
||||
|
||||
void global_unload(void)
|
||||
{
|
||||
delete g_infoImpl;
|
||||
g_infoImpl = NULL;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,557 @@
|
|||
#include "HGBmp.h"
|
||||
#include "../base/HGInc.h"
|
||||
#include "../base/HGInfo.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "libnsbmp.h"
|
||||
};
|
||||
|
||||
HGResult HGAPI HGImgFmt_CheckBmpFile(const HGChar* fileName, HGBool* isBmp)
|
||||
{
|
||||
if (NULL == fileName || NULL == isBmp)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGBmpLoadInfo info;
|
||||
HGResult ret = HGImgFmt_LoadBmpImage(fileName, &info, 0, 0, NULL);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
*isBmp = HGTRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void* bitmap_create(int width, int height, unsigned int state)
|
||||
{
|
||||
if (width <= 0 || height <= 0)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)state; /* unused */
|
||||
return calloc((intptr_t)width * (intptr_t)height, 4);
|
||||
}
|
||||
|
||||
static unsigned char* bitmap_get_buffer(void* bitmap)
|
||||
{
|
||||
assert(NULL != bitmap);
|
||||
return (unsigned char*)bitmap;
|
||||
}
|
||||
|
||||
static size_t bitmap_get_bpp(void* bitmap)
|
||||
{
|
||||
(void)bitmap; /* unused */
|
||||
return 4;
|
||||
}
|
||||
|
||||
static void bitmap_destroy(void* bitmap)
|
||||
{
|
||||
assert(NULL != bitmap);
|
||||
free(bitmap);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_LoadBmpImage(const HGChar* fileName, HGBmpLoadInfo* info,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image)
|
||||
{
|
||||
if (NULL == fileName)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (NULL == image)
|
||||
{
|
||||
if (0 != imgType || 0 != imgOrigin)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 != imgType && HGBASE_IMGTYPE_BINARY != imgType && HGBASE_IMGTYPE_GRAY != imgType
|
||||
&& HGBASE_IMGTYPE_BGR != imgType && HGBASE_IMGTYPE_RGB != imgType
|
||||
&& HGBASE_IMGTYPE_BGRA != imgType && HGBASE_IMGTYPE_RGBA != imgType)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (0 != imgOrigin && HGBASE_IMGORIGIN_TOP != imgOrigin && HGBASE_IMGORIGIN_BOTTOM != imgOrigin)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (0 != _access(fileName, 0))
|
||||
#else
|
||||
if (0 != access(fileName, 0))
|
||||
#endif
|
||||
{
|
||||
return HGBASE_ERR_FILENOTEXIST;
|
||||
}
|
||||
|
||||
FILE* file = fopen(fileName, "rb");
|
||||
if (NULL == file)
|
||||
{
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
_fseeki64(file, 0, SEEK_END);
|
||||
uint64_t size = _ftelli64(file);
|
||||
#else
|
||||
fseeko64(file, 0, SEEK_END);
|
||||
uint64_t size = ftello64(file);
|
||||
#endif
|
||||
if (0 == size)
|
||||
{
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGBASE_ERR_FILEERROR;
|
||||
}
|
||||
|
||||
uint8_t* buffer = (uint8_t*)malloc((size_t)size);
|
||||
if (NULL == buffer)
|
||||
{
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGBASE_ERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
_fseeki64(file, 0, SEEK_SET);
|
||||
#else
|
||||
fseeko64(file, 0, SEEK_SET);
|
||||
#endif
|
||||
size_t readSize = fread(buffer, 1, (size_t)size, file);
|
||||
if (readSize != size)
|
||||
{
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
bmp_image bmp;
|
||||
bmp_bitmap_callback_vt bitmap_callbacks = { bitmap_create, bitmap_destroy, bitmap_get_buffer, bitmap_get_bpp };
|
||||
bmp_create(&bmp, &bitmap_callbacks);
|
||||
|
||||
if (BMP_OK != bmp_analyse(&bmp, (size_t)size, buffer))
|
||||
{
|
||||
bmp_finalise(&bmp);
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
if (NULL != info)
|
||||
{
|
||||
info->width = bmp.width;
|
||||
info->height = bmp.height;
|
||||
info->bitCount = bmp.bpp;
|
||||
info->compression = (uint32_t)bmp.encoding;
|
||||
info->xPelsPerMeter = bmp.x_pels_per_meter;
|
||||
info->yPelsPerMeter = bmp.y_pels_per_meter;
|
||||
}
|
||||
|
||||
if (NULL != image)
|
||||
{
|
||||
if (BMP_OK != bmp_decode(&bmp))
|
||||
{
|
||||
bmp_finalise(&bmp);
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
if (0 == imgType)
|
||||
{
|
||||
imgType = HGBASE_IMGTYPE_RGB;
|
||||
|
||||
if (1 == bmp.bpp || 4 == bmp.bpp || 8 == bmp.bpp)
|
||||
{
|
||||
bool bGray = true;
|
||||
bool bBinary = true;
|
||||
for (uint32_t i = 0; i < bmp.colours; ++i)
|
||||
{
|
||||
HGByte red = (bmp.colour_table[i] >> 16) & 0xff;
|
||||
HGByte green = (bmp.colour_table[i] >> 8) & 0xff;
|
||||
HGByte blue = (bmp.colour_table[i]) & 0xff;
|
||||
|
||||
if (red != green || red != blue || green != blue)
|
||||
{
|
||||
bGray = false;
|
||||
bBinary = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (red != 0 && red != 255)
|
||||
{
|
||||
bBinary = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (bBinary)
|
||||
imgType = HGBASE_IMGTYPE_BINARY;
|
||||
else if (bGray)
|
||||
imgType = HGBASE_IMGTYPE_GRAY;
|
||||
}
|
||||
else if (32 == bmp.bpp)
|
||||
{
|
||||
imgType = HGBASE_IMGTYPE_RGBA;
|
||||
}
|
||||
}
|
||||
|
||||
if (imgOrigin == 0)
|
||||
{
|
||||
imgOrigin = HGBASE_IMGORIGIN_TOP;
|
||||
}
|
||||
|
||||
HGImageInfo bmpImageInfo;
|
||||
bmpImageInfo.width = bmp.width;
|
||||
bmpImageInfo.height = bmp.height;
|
||||
bmpImageInfo.type = HGBASE_IMGTYPE_RGBA;
|
||||
bmpImageInfo.widthStep = bmp.width * 4;
|
||||
bmpImageInfo.origin = HGBASE_IMGORIGIN_TOP;
|
||||
|
||||
HGImage image2 = NULL;
|
||||
HGResult ret = HGBase_CreateImageWithData((HGByte*)bmp.bitmap, &bmpImageInfo, &image2);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
bmp_finalise(&bmp);
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t xDpi = (uint32_t)((double)bmp.x_pels_per_meter / 39.3700787 + 0.5);
|
||||
uint32_t yDpi = (uint32_t)((double)bmp.y_pels_per_meter / 39.3700787 + 0.5);
|
||||
HGBase_SetImageDpi(image2, xDpi, yDpi);
|
||||
|
||||
ret = HGBase_CloneImage(image2, imgType, imgOrigin, image);
|
||||
HGBase_DestroyImage(image2);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
bmp_finalise(&bmp);
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
bmp_finalise(&bmp);
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_SaveBmpImage(HGImage image, const HGBmpSaveInfo* info, const HGChar* fileName)
|
||||
{
|
||||
if (NULL == image || NULL == fileName)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (NULL != info)
|
||||
{
|
||||
// 检查合法性
|
||||
}
|
||||
|
||||
HGImageInfo imgInfo;
|
||||
HGBase_GetImageInfo(image, &imgInfo);
|
||||
uint32_t width = imgInfo.width;
|
||||
uint32_t height = imgInfo.height;
|
||||
uint32_t widthStep = imgInfo.widthStep;
|
||||
uint32_t type = imgInfo.type;
|
||||
uint32_t origin = imgInfo.origin;
|
||||
|
||||
HGUInt bpp = 0;
|
||||
if (HGBASE_IMGTYPE_BINARY == type)
|
||||
bpp = 1;
|
||||
else if (HGBASE_IMGTYPE_GRAY == type)
|
||||
bpp = 8;
|
||||
else if (HGBASE_IMGTYPE_BGR == type || HGBASE_IMGTYPE_RGB == type)
|
||||
bpp = 24;
|
||||
else if (HGBASE_IMGTYPE_BGRA == type || HGBASE_IMGTYPE_RGBA == type)
|
||||
bpp = 32;
|
||||
assert(0 != bpp);
|
||||
HGUInt stdWidthStep = ((width * bpp + 31) & ~31) >> 3;
|
||||
|
||||
if (widthStep != stdWidthStep)
|
||||
{
|
||||
HGImage imgTemp = NULL;
|
||||
|
||||
HGImageRoi imageRoi;
|
||||
HGBase_GetImageROI(image, &imageRoi);
|
||||
HGBase_ResetImageROI(image);
|
||||
HGResult ret = HGBase_CloneImage(image, 0, 0, &imgTemp);
|
||||
HGBase_SetImageROI(image, &imageRoi);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = HGImgFmt_SaveBmpImage(imgTemp, info, fileName);
|
||||
HGBase_DestroyImage(imgTemp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
FILE* file = fopen(fileName, "wb");
|
||||
if (NULL == file)
|
||||
{
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "HGImgFmt_SaveBmpImage: fopen fail, %s errno=%d", fileName, errno);
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
}
|
||||
|
||||
uint8_t* buffer = (uint8_t*)malloc(widthStep * height);
|
||||
if (NULL == buffer)
|
||||
{
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGBASE_ERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
uint8_t fh[14];
|
||||
*(uint16_t*)fh = 0x4D42;
|
||||
*(uint16_t*)(fh + 6) = 0;
|
||||
*(uint16_t*)(fh + 8) = 0;
|
||||
|
||||
uint8_t ih[40];
|
||||
*(uint32_t*)ih = 40;
|
||||
*(int32_t*)(ih + 4) = (int32_t)width;
|
||||
*(int32_t*)(ih + 8) = (int32_t)height;
|
||||
*(uint16_t*)(ih + 12) = 1;
|
||||
*(uint32_t*)(ih + 16) = 0;
|
||||
*(uint32_t*)(ih + 20) = (widthStep * height);
|
||||
*(int32_t*)(ih + 24) = 0;
|
||||
*(int32_t*)(ih + 28) = 0;
|
||||
*(uint32_t*)(ih + 32) = 0;
|
||||
*(uint32_t*)(ih + 36) = 0;
|
||||
|
||||
if (NULL != info)
|
||||
{
|
||||
*(int32_t*)(ih + 24) = (int32_t)info->xPelsPerMeter;
|
||||
*(int32_t*)(ih + 28) = (int32_t)info->yPelsPerMeter;
|
||||
}
|
||||
else
|
||||
{
|
||||
HGUInt xDpi, yDpi;
|
||||
HGBase_GetImageDpi(image, &xDpi, &yDpi);
|
||||
*(int32_t*)(ih + 24) = (uint32_t)((double)xDpi * 39.3700787 + 0.5);
|
||||
*(int32_t*)(ih + 28) = (uint32_t)((double)yDpi * 39.3700787 + 0.5);
|
||||
}
|
||||
|
||||
uint8_t* data;
|
||||
HGBase_GetImageData(image, &data);
|
||||
|
||||
if (HGBASE_IMGTYPE_BINARY == type)
|
||||
{
|
||||
*(uint32_t*)(fh + 2) = 54 + 4 * 2 + widthStep * height;
|
||||
*(uint32_t*)(fh + 10) = 54 + 4 * 2;
|
||||
*(uint16_t*)(ih + 14) = 1;
|
||||
|
||||
uint32_t colorTable[2];
|
||||
colorTable[0] = 0x00000000;
|
||||
colorTable[1] = 0x00FFFFFF;
|
||||
|
||||
fwrite(fh, 14, 1, file);
|
||||
fwrite(ih, 40, 1, file);
|
||||
fwrite(colorTable, 4, 2, file);
|
||||
|
||||
if (HGBASE_IMGORIGIN_BOTTOM == origin)
|
||||
{
|
||||
fwrite(data, 1, widthStep * height, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t* dataEx = data + (height - 1) * widthStep;
|
||||
while (dataEx >= data)
|
||||
{
|
||||
fwrite(dataEx, 1, widthStep, file);
|
||||
dataEx -= widthStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (HGBASE_IMGTYPE_GRAY == type)
|
||||
{
|
||||
*(uint32_t*)(fh + 2) = 54 + 4 * 256 + widthStep * height;
|
||||
*(uint32_t*)(fh + 10) = 54 + 4 * 256;
|
||||
*(uint16_t*)(ih + 14) = 8;
|
||||
|
||||
uint32_t colorTable[256];
|
||||
//#pragma omp parallel for
|
||||
for (int32_t i = 0; i < 256; ++i)
|
||||
{
|
||||
uint32_t v = (i & 0x000000FF) | ((i << 8) & 0x0000FF00) | ((i << 16) & 0x00FF0000);
|
||||
colorTable[i] = v;
|
||||
}
|
||||
|
||||
fwrite(fh, 14, 1, file);
|
||||
fwrite(ih, 40, 1, file);
|
||||
fwrite(colorTable, 4, 256, file);
|
||||
|
||||
if (HGBASE_IMGORIGIN_BOTTOM == origin)
|
||||
{
|
||||
fwrite(data, 1, widthStep * height, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t* dataEx = data + (height - 1) * widthStep;
|
||||
while (dataEx >= data)
|
||||
{
|
||||
fwrite(dataEx, 1, widthStep, file);
|
||||
dataEx -= widthStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (HGBASE_IMGTYPE_RGB == type)
|
||||
{
|
||||
*(uint32_t*)(fh + 2) = 54 + widthStep * height;
|
||||
*(uint32_t*)(fh + 10) = 54;
|
||||
*(uint16_t*)(ih + 14) = 24;
|
||||
|
||||
fwrite(fh, 14, 1, file);
|
||||
fwrite(ih, 40, 1, file);
|
||||
|
||||
//#pragma omp parallel for
|
||||
for (int32_t i = 0; i < (int32_t)height; ++i)
|
||||
{
|
||||
uint8_t* pEx = data + (uintptr_t)i * (uintptr_t)widthStep;
|
||||
uint8_t* pExEnd = pEx + width * 3;
|
||||
uint8_t* pDestEx = buffer + (uintptr_t)i * (uintptr_t)widthStep;
|
||||
|
||||
while (pEx < pExEnd)
|
||||
{
|
||||
pDestEx[0] = pEx[2];
|
||||
pDestEx[1] = pEx[1];
|
||||
pDestEx[2] = pEx[0];
|
||||
|
||||
pEx += 3;
|
||||
pDestEx += 3;
|
||||
}
|
||||
}
|
||||
|
||||
if (HGBASE_IMGORIGIN_BOTTOM == origin)
|
||||
{
|
||||
fwrite(buffer, 1, widthStep * height, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t* bufferEx = buffer + (height - 1) * widthStep;
|
||||
while (bufferEx >= buffer)
|
||||
{
|
||||
fwrite(bufferEx, 1, widthStep, file);
|
||||
bufferEx -= widthStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (HGBASE_IMGTYPE_BGR == type)
|
||||
{
|
||||
*(uint32_t*)(fh + 2) = 54 + widthStep * height;
|
||||
*(uint32_t*)(fh + 10) = 54;
|
||||
*(uint16_t*)(ih + 14) = 24;
|
||||
|
||||
fwrite(fh, 14, 1, file);
|
||||
fwrite(ih, 40, 1, file);
|
||||
|
||||
if (HGBASE_IMGORIGIN_BOTTOM == origin)
|
||||
{
|
||||
fwrite(data, 1, widthStep * height, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t* dataEx = data + (height - 1) * widthStep;
|
||||
while (dataEx >= data)
|
||||
{
|
||||
fwrite(dataEx, 1, widthStep, file);
|
||||
dataEx -= widthStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (HGBASE_IMGTYPE_BGRA == type)
|
||||
{
|
||||
*(uint32_t*)(fh + 2) = 54 + widthStep * height;
|
||||
*(uint32_t*)(fh + 10) = 54;
|
||||
*(uint16_t*)(ih + 14) = 32;
|
||||
|
||||
fwrite(fh, 14, 1, file);
|
||||
fwrite(ih, 40, 1, file);
|
||||
|
||||
if (HGBASE_IMGORIGIN_BOTTOM == origin)
|
||||
{
|
||||
fwrite(data, 1, widthStep * height, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t* dataEx = data + (height - 1) * widthStep;
|
||||
while (dataEx >= data)
|
||||
{
|
||||
fwrite(dataEx, 1, widthStep, file);
|
||||
dataEx -= widthStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(HGBASE_IMGTYPE_RGBA == type);
|
||||
|
||||
*(uint32_t*)(fh + 2) = 54 + widthStep * height;
|
||||
*(uint32_t*)(fh + 10) = 54;
|
||||
*(uint16_t*)(ih + 14) = 32;
|
||||
|
||||
fwrite(fh, 14, 1, file);
|
||||
fwrite(ih, 40, 1, file);
|
||||
|
||||
//#pragma omp parallel for
|
||||
for (int32_t i = 0; i < (int32_t)height; ++i)
|
||||
{
|
||||
uint8_t* pEx = data + (uintptr_t)i * (uintptr_t)widthStep;
|
||||
uint8_t* pExEnd = pEx + width * 4;
|
||||
uint8_t* pDestEx = buffer + (uintptr_t)i * (uintptr_t)widthStep;
|
||||
|
||||
while (pEx < pExEnd)
|
||||
{
|
||||
pDestEx[0] = pEx[2];
|
||||
pDestEx[1] = pEx[1];
|
||||
pDestEx[2] = pEx[0];
|
||||
pDestEx[3] = pEx[3];
|
||||
|
||||
pEx += 4;
|
||||
pDestEx += 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (HGBASE_IMGORIGIN_BOTTOM == origin)
|
||||
{
|
||||
fwrite(buffer, 1, widthStep * height, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t* bufferEx = buffer + (height - 1) * widthStep;
|
||||
while (bufferEx >= buffer)
|
||||
{
|
||||
fwrite(bufferEx, 1, widthStep, file);
|
||||
bufferEx -= widthStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
#ifndef __HGBMP_H__
|
||||
#define __HGBMP_H__
|
||||
|
||||
#include "../base/HGDef.h"
|
||||
#include "../base/HGBaseErr.h"
|
||||
#include "HGImgFmtErr.h"
|
||||
#include "../base/HGImage.h"
|
||||
|
||||
/* 压缩方式 */
|
||||
#define HGIMGFMT_BMPENCODING_RGB 0L
|
||||
#define HGIMGFMT_BMPENCODING_RLE8 1L
|
||||
#define HGIMGFMT_BMPENCODING_RLE4 2L
|
||||
#define HGIMGFMT_BMPENCODING_BITFIELDS 3L
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGUInt width; /* 宽 */
|
||||
HGUInt height; /* 高 */
|
||||
HGUShort bitCount; /* 每像素比特数 */
|
||||
HGUInt compression; /* 压缩方式, 见HGIMGFMT_BMPENCODING_ */
|
||||
HGUInt xPelsPerMeter; /* 每米的像素数x */
|
||||
HGUInt yPelsPerMeter; /* 每米的像素数y */
|
||||
}HGBmpLoadInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGUInt xPelsPerMeter; /* 每米的像素数x */
|
||||
HGUInt yPelsPerMeter; /* 每米的像素数y */
|
||||
}HGBmpSaveInfo;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
/* 检查文件是否是BMP图像
|
||||
* 参数:
|
||||
* 1) fileName: in, 文件名, windows系统上是GBK编码, linux系统上是UTF8编码
|
||||
* 2) isBmp: out, 是否是BMP图像
|
||||
* 说明:
|
||||
* 1) 该函数会打开文件判断文件头,而不是判断文件名后缀
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_CheckBmpFile(const HGChar* fileName, HGBool* isBmp);
|
||||
|
||||
/* 加载BMP图像
|
||||
* 参数:
|
||||
* 1) fileName: in, 文件名, windows系统上是GBK编码, linux系统上是UTF8编码
|
||||
* 2) info: out, BMP图像加载信息, 如果不需要该信息可传NULL
|
||||
* 3) imgType: in, 要生成的图像类型, 参见HGBASE_IMGTYPE_*, 传0表示自动获取
|
||||
* 4) imgOrigin: in, 要生成的图像数据排列方式, 参见HGBASE_IMGORIGIN_*, 传0表示自动获取
|
||||
* 5) image: out, 要生成的图像句柄
|
||||
* 说明:
|
||||
* 1) 生成的图像不使用时需要调用HGBase_DestroyImage销毁
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_LoadBmpImage(const HGChar* fileName, HGBmpLoadInfo* info,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image);
|
||||
|
||||
/* 保存BMP图像
|
||||
* 参数:
|
||||
* 1) image: in, 要保存的图像句柄
|
||||
* 2) info: in, BMP图像保存信息, 如果没有则传NULL
|
||||
* 3) fileName: in, 文件名, windows系统上是GBK编码, linux系统上是UTF8编码
|
||||
* 说明:
|
||||
* 1) 忽略fileName的文件扩展名
|
||||
* 2) 如果info不为NULL, 保存的DPI使用info指定的; 否则使用image自带的
|
||||
*/
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_SaveBmpImage(HGImage image, const HGBmpSaveInfo* info, const HGChar* fileName);
|
||||
|
||||
#endif /* __HGBMP_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,55 @@
|
|||
#ifndef __HGGIF_H__
|
||||
#define __HGGIF_H__
|
||||
|
||||
#include "../base/HGDef.h"
|
||||
#include "../base/HGBaseErr.h"
|
||||
#include "HGImgFmtErr.h"
|
||||
#include "../base/HGImage.h"
|
||||
|
||||
HG_DECLARE_HANDLE(HGGifReader);
|
||||
HG_DECLARE_HANDLE(HGGifWriter);
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGUInt width; /* 图像宽 */
|
||||
HGUInt height; /* 图像高 */
|
||||
HGUInt colorResolution; /* 位深 */
|
||||
HGUInt imageCount; /* 图像数量 */
|
||||
}HGGifLoadInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGUInt width; /* 图像宽 */
|
||||
HGUInt height; /* 图像高 */
|
||||
}HGGifSaveInfo;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_CheckGifFile(const HGChar* fileName, HGBool* isGif);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_OpenGifReader(const HGChar* fileName, HGGifLoadInfo* info, HGGifReader* reader);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_CloseGifReader(HGGifReader reader);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_RetrieveImageFromGifReader(HGGifReader reader, HGUInt *index, HGUInt *interval,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_LoadImageFromGifReader(HGGifReader reader, HGUInt index, HGUInt* interval,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_LoadGifImage(const HGChar* fileName, HGGifLoadInfo* info, HGUInt* interval,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_OpenGifWriter(const HGChar* fileName, const HGGifSaveInfo* info, HGGifWriter* writer);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_CloseGifWriter(HGGifWriter writer);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_SaveImageToGifWriter(HGGifWriter writer, HGUInt interval, HGColor bkColor, HGImage image);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_SaveGifImage(HGImage image, const HGGifSaveInfo* info,
|
||||
HGUInt interval, HGColor bkColor, const HGChar* fileName);
|
||||
|
||||
#endif /* __HGGIF_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,77 @@
|
|||
#ifndef __HGIMGFMT_H__
|
||||
#define __HGIMGFMT_H__
|
||||
|
||||
#include "../base/HGDef.h"
|
||||
#include "../base/HGBaseErr.h"
|
||||
#include "HGImgFmtErr.h"
|
||||
#include "../base/HGImage.h"
|
||||
#include "HGTiff.h"
|
||||
|
||||
HG_DECLARE_HANDLE(HGImgFmtReader);
|
||||
HG_DECLARE_HANDLE(HGImgFmtWriter);
|
||||
|
||||
/* JPEG */
|
||||
#define HGIMGFMT_TYPE_JPEG 1L
|
||||
/* BMP */
|
||||
#define HGIMGFMT_TYPE_BMP 2L
|
||||
/* PNG */
|
||||
#define HGIMGFMT_TYPE_PNG 3L
|
||||
/* TIFF */
|
||||
#define HGIMGFMT_TYPE_TIFF 4L
|
||||
/* PDF */
|
||||
#define HGIMGFMT_TYPE_PDF 5L
|
||||
/* OFD */
|
||||
#define HGIMGFMT_TYPE_OFD 6L
|
||||
/* GIF */
|
||||
#define HGIMGFMT_TYPE_GIF 7L
|
||||
/* PNM */
|
||||
#define HGIMGFMT_TYPE_PNM 8L
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGUInt width; /* 图像宽 */
|
||||
HGUInt height; /* 图像高 */
|
||||
HGUInt bpp; /* 每像素比特数 */
|
||||
HGUInt xDpi; /* x-DPI */
|
||||
HGUInt yDpi; /* y-DPI */
|
||||
}HGImgFmtLoadInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGUInt jpegQuality; /* jpeg质量 */
|
||||
HGUInt tiffCompression; /* tiff压缩方式, 见HGIMGFMT_TIFFCOMP_* */
|
||||
HGUInt tiffJpegQuality; /* tiff-jpeg质量 */
|
||||
}HGImgFmtSaveInfo;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_GetImgFmtType(const HGChar* fileName, HGUInt* fmtType);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_GetImgFmtTypeFromFileName(const HGChar* fileName, HGUInt* fmtType);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_IsMultiImgFmtType(HGUInt fmtType, HGBool *isMulti);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_LoadImage(const HGChar *fileName, HGUInt fmtType, HGImgFmtLoadInfo *info,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage *image);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_SaveImage(HGImage image, HGUInt fmtType, const HGImgFmtSaveInfo *info, const HGChar *fileName);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_OpenImageReader(const HGChar *fileName, HGUInt fmtType, HGImgFmtReader *reader);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_CloseImageReader(HGImgFmtReader reader);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_GetImagePageCount(HGImgFmtReader reader, HGUInt *count);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_LoadImageFromReader(HGImgFmtReader reader, HGUInt index, HGImgFmtLoadInfo *info,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage *image);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_OpenImageWriter(const HGChar *fileName, HGUInt fmtType, HGImgFmtWriter *writer);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_CloseImageWriter(HGImgFmtWriter writer);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_SaveImageToWriter(HGImgFmtWriter writer, HGImage image, const HGImgFmtSaveInfo *info);
|
||||
|
||||
#endif /* __HGIMGFMT_H__ */
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef __HGIMGFMTERR_H__
|
||||
#define __HGIMGFMTERR_H__
|
||||
|
||||
/* 一般错误 */
|
||||
#define HGIMGFMT_ERR_FAIL 0x00002001L
|
||||
|
||||
#endif /* __HGIMGFMTERR_H__ */
|
|
@ -0,0 +1,538 @@
|
|||
#include "HGJpeg.h"
|
||||
#include "../base/HGInc.h"
|
||||
#include "../base/HGInfo.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "jpeglib.h"
|
||||
#include "jmemsys.h"
|
||||
};
|
||||
|
||||
struct my_error_mgr
|
||||
{
|
||||
struct jpeg_error_mgr pub;
|
||||
jmp_buf setjmp_buffer;
|
||||
};
|
||||
|
||||
METHODDEF(void) my_error_exit(j_common_ptr cinfo)
|
||||
{
|
||||
my_error_mgr* myerr = (my_error_mgr*)cinfo->err;
|
||||
(*cinfo->err->output_message)(cinfo);
|
||||
longjmp(myerr->setjmp_buffer, (int)HGIMGFMT_ERR_FAIL);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_CheckJpegFile(const HGChar* fileName, HGBool* isJpeg)
|
||||
{
|
||||
if (NULL == fileName || NULL == isJpeg)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGJpegLoadInfo info;
|
||||
HGResult ret = HGImgFmt_LoadJpegImage(fileName, &info, 0, 0, NULL);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
*isJpeg = HGTRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_LoadJpegImage(const HGChar* fileName, HGJpegLoadInfo* info,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image)
|
||||
{
|
||||
if (NULL == fileName)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (NULL == image)
|
||||
{
|
||||
if (0 != imgType || 0 != imgOrigin)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 != imgType && HGBASE_IMGTYPE_BINARY != imgType && HGBASE_IMGTYPE_GRAY != imgType
|
||||
&& HGBASE_IMGTYPE_BGR != imgType && HGBASE_IMGTYPE_RGB != imgType
|
||||
&& HGBASE_IMGTYPE_BGRA != imgType && HGBASE_IMGTYPE_RGBA != imgType)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (0 != imgOrigin && HGBASE_IMGORIGIN_TOP != imgOrigin && HGBASE_IMGORIGIN_BOTTOM != imgOrigin)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (0 != _access(fileName, 0))
|
||||
#else
|
||||
if (0 != access(fileName, 0))
|
||||
#endif
|
||||
{
|
||||
return HGBASE_ERR_FILENOTEXIST;
|
||||
}
|
||||
|
||||
FILE* file = fopen(fileName, "rb");
|
||||
if (NULL == file)
|
||||
{
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
}
|
||||
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct my_error_mgr jerr;
|
||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = my_error_exit;
|
||||
|
||||
HGImage image2 = NULL;
|
||||
|
||||
int jmpResult = setjmp(jerr.setjmp_buffer);
|
||||
if (0 != jmpResult)
|
||||
{
|
||||
HGBase_DestroyImage(image2);
|
||||
image2 = NULL;
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return (HGResult)jmpResult;
|
||||
}
|
||||
|
||||
jpeg_create_decompress(&cinfo);
|
||||
jpeg_stdio_src(&cinfo, file);
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
|
||||
if (NULL != info)
|
||||
{
|
||||
info->width = cinfo.image_width;
|
||||
info->height = cinfo.image_height;
|
||||
info->numComponents = cinfo.num_components;
|
||||
info->colorSpace = cinfo.jpeg_color_space;
|
||||
info->densityUnit = cinfo.density_unit;
|
||||
info->xDensity = cinfo.X_density;
|
||||
info->yDensity = cinfo.Y_density;
|
||||
}
|
||||
|
||||
if (NULL != image)
|
||||
{
|
||||
if (0 == imgType)
|
||||
{
|
||||
if (JCS_GRAYSCALE != cinfo.out_color_space)
|
||||
imgType = HGBASE_IMGTYPE_RGB;
|
||||
else
|
||||
imgType = HGBASE_IMGTYPE_GRAY;
|
||||
}
|
||||
|
||||
if (0 == imgOrigin)
|
||||
{
|
||||
imgOrigin = HGBASE_IMGORIGIN_TOP;
|
||||
}
|
||||
|
||||
cinfo.out_color_space = JCS_RGB;
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
HGResult ret = HGBase_CreateImage(cinfo.output_width, cinfo.output_height,
|
||||
HGBASE_IMGTYPE_RGB, HGBASE_IMGORIGIN_TOP, &image2);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
longjmp(jerr.setjmp_buffer, (int)ret);
|
||||
}
|
||||
|
||||
if (1 == cinfo.density_unit)
|
||||
{
|
||||
HGBase_SetImageDpi(image2, cinfo.X_density, cinfo.Y_density);
|
||||
}
|
||||
else if (2 == cinfo.density_unit)
|
||||
{
|
||||
uint32_t xDpi = (uint32_t)(cinfo.X_density / 0.393700787402 + 0.5);
|
||||
uint32_t yDpi = (uint32_t)(cinfo.Y_density / 0.393700787402 + 0.5);
|
||||
HGBase_SetImageDpi(image2, xDpi, yDpi);
|
||||
}
|
||||
|
||||
HGImageInfo imgInfo;
|
||||
HGBase_GetImageInfo(image2, &imgInfo);
|
||||
uint8_t* data;
|
||||
HGBase_GetImageData(image2, &data);
|
||||
|
||||
while (cinfo.output_scanline < cinfo.output_height)
|
||||
{
|
||||
JSAMPROW pEx = data + (HGSize)cinfo.output_scanline * (HGSize)imgInfo.widthStep;
|
||||
jpeg_read_scanlines(&cinfo, &pEx, 1);
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
|
||||
ret = HGBase_CloneImage(image2, imgType, imgOrigin, image);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
longjmp(jerr.setjmp_buffer, (int)ret);
|
||||
}
|
||||
}
|
||||
|
||||
HGBase_DestroyImage(image2);
|
||||
image2 = NULL;
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_LoadJpegImageFromBuffer(HGBuffer buffer, HGJpegLoadInfo* info,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image)
|
||||
{
|
||||
if (NULL == buffer)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (NULL == image)
|
||||
{
|
||||
if (0 != imgType || 0 != imgOrigin)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 != imgType && HGBASE_IMGTYPE_BINARY != imgType && HGBASE_IMGTYPE_GRAY != imgType
|
||||
&& HGBASE_IMGTYPE_BGR != imgType && HGBASE_IMGTYPE_RGB != imgType
|
||||
&& HGBASE_IMGTYPE_BGRA != imgType && HGBASE_IMGTYPE_RGBA != imgType)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (0 != imgOrigin && HGBASE_IMGORIGIN_TOP != imgOrigin && HGBASE_IMGORIGIN_BOTTOM != imgOrigin)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct my_error_mgr jerr;
|
||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = my_error_exit;
|
||||
|
||||
HGImage image2 = NULL;
|
||||
|
||||
int jmpResult = setjmp(jerr.setjmp_buffer);
|
||||
if (0 != jmpResult)
|
||||
{
|
||||
HGBase_DestroyImage(image2);
|
||||
image2 = NULL;
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
return (HGResult)jmpResult;
|
||||
}
|
||||
|
||||
HGByte* memAddr = NULL;
|
||||
HGBase_GetBufferData(buffer, &memAddr);
|
||||
HGUSize size = 0;
|
||||
HGBase_GetBufferSize(buffer, &size);
|
||||
|
||||
jpeg_create_decompress(&cinfo);
|
||||
jpeg_mem_src(&cinfo, memAddr, (unsigned long)size);
|
||||
jpeg_read_header(&cinfo, TRUE);
|
||||
|
||||
if (NULL != info)
|
||||
{
|
||||
info->width = cinfo.image_width;
|
||||
info->height = cinfo.image_height;
|
||||
info->numComponents = cinfo.num_components;
|
||||
info->colorSpace = cinfo.jpeg_color_space;
|
||||
info->densityUnit = cinfo.density_unit;
|
||||
info->xDensity = cinfo.X_density;
|
||||
info->yDensity = cinfo.Y_density;
|
||||
}
|
||||
|
||||
if (NULL != image)
|
||||
{
|
||||
if (0 == imgType)
|
||||
{
|
||||
if (JCS_GRAYSCALE != cinfo.out_color_space)
|
||||
imgType = HGBASE_IMGTYPE_RGB;
|
||||
else
|
||||
imgType = HGBASE_IMGTYPE_GRAY;
|
||||
}
|
||||
|
||||
if (0 == imgOrigin)
|
||||
{
|
||||
imgOrigin = HGBASE_IMGORIGIN_TOP;
|
||||
}
|
||||
|
||||
cinfo.out_color_space = JCS_RGB;
|
||||
jpeg_start_decompress(&cinfo);
|
||||
|
||||
HGResult ret = HGBase_CreateImage(cinfo.output_width, cinfo.output_height,
|
||||
HGBASE_IMGTYPE_RGB, HGBASE_IMGORIGIN_TOP, &image2);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
longjmp(jerr.setjmp_buffer, (int)ret);
|
||||
}
|
||||
|
||||
if (1 == cinfo.density_unit)
|
||||
{
|
||||
HGBase_SetImageDpi(image2, cinfo.X_density, cinfo.Y_density);
|
||||
}
|
||||
else if (2 == cinfo.density_unit)
|
||||
{
|
||||
uint32_t xDpi = (uint32_t)(cinfo.X_density / 0.393700787402 + 0.5);
|
||||
uint32_t yDpi = (uint32_t)(cinfo.Y_density / 0.393700787402 + 0.5);
|
||||
HGBase_SetImageDpi(image2, xDpi, yDpi);
|
||||
}
|
||||
|
||||
HGImageInfo imgInfo;
|
||||
HGBase_GetImageInfo(image2, &imgInfo);
|
||||
uint8_t* data;
|
||||
HGBase_GetImageData(image2, &data);
|
||||
|
||||
while (cinfo.output_scanline < cinfo.output_height)
|
||||
{
|
||||
JSAMPROW pEx = data + (HGSize)cinfo.output_scanline * (HGSize)imgInfo.widthStep;
|
||||
jpeg_read_scanlines(&cinfo, &pEx, 1);
|
||||
}
|
||||
|
||||
jpeg_finish_decompress(&cinfo);
|
||||
|
||||
ret = HGBase_CloneImage(image2, imgType, imgOrigin, image);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
longjmp(jerr.setjmp_buffer, (int)ret);
|
||||
}
|
||||
}
|
||||
|
||||
HGBase_DestroyImage(image2);
|
||||
image2 = NULL;
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_SaveJpegImage(HGImage image, const HGJpegSaveInfo* info, const HGChar* fileName)
|
||||
{
|
||||
if (NULL == image || NULL == fileName)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (NULL != info)
|
||||
{
|
||||
// 判断info参数的合法性
|
||||
}
|
||||
|
||||
FILE* file = fopen(fileName, "wb");
|
||||
if (NULL == file)
|
||||
{
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "HGImgFmt_SaveJpegImage: fopen fail, %s errno=%d", fileName, errno);
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
}
|
||||
|
||||
struct jpeg_compress_struct cinfo;
|
||||
struct my_error_mgr jerr;
|
||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = my_error_exit;
|
||||
|
||||
HGImage image2 = NULL;
|
||||
HGImageRoi roi;
|
||||
HGBase_GetImageROI(image, &roi);
|
||||
|
||||
int jmpResult = setjmp(jerr.setjmp_buffer);
|
||||
if (0 != jmpResult)
|
||||
{
|
||||
HGBase_SetImageROI(image, &roi);
|
||||
HGBase_DestroyImage(image2);
|
||||
image2 = NULL;
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return (HGResult)jmpResult;
|
||||
}
|
||||
|
||||
jpeg_create_compress(&cinfo);
|
||||
jpeg_stdio_dest(&cinfo, file);
|
||||
|
||||
HGBase_ResetImageROI(image);
|
||||
HGImageInfo imgInfo;
|
||||
HGBase_GetImageInfo(image, &imgInfo);
|
||||
if (HGBASE_IMGTYPE_GRAY == imgInfo.type || HGBASE_IMGTYPE_BINARY == imgInfo.type)
|
||||
{
|
||||
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_GRAY, HGBASE_IMGORIGIN_TOP, &image2);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
longjmp(jerr.setjmp_buffer, (int)ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_RGB, HGBASE_IMGORIGIN_TOP, &image2);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
longjmp(jerr.setjmp_buffer, (int)ret);
|
||||
}
|
||||
|
||||
HGBase_GetImageInfo(image2, &imgInfo);
|
||||
uint32_t width = imgInfo.width;
|
||||
uint32_t height = imgInfo.height;
|
||||
uint32_t type = imgInfo.type;
|
||||
uint32_t widthStep = imgInfo.widthStep;
|
||||
uint8_t* data;
|
||||
HGBase_GetImageData(image2, &data);
|
||||
|
||||
cinfo.image_width = width;
|
||||
cinfo.image_height = height;
|
||||
cinfo.input_components = (HGBASE_IMGTYPE_GRAY != type) ? 3 : 1;
|
||||
cinfo.in_color_space = (HGBASE_IMGTYPE_GRAY != type) ? JCS_RGB : JCS_GRAYSCALE;
|
||||
jpeg_set_defaults(&cinfo);
|
||||
|
||||
int quality;
|
||||
if (NULL != info)
|
||||
{
|
||||
quality = info->quality;
|
||||
cinfo.density_unit = info->densityUnit;
|
||||
cinfo.X_density = info->xDensity;
|
||||
cinfo.Y_density = info->yDensity;
|
||||
}
|
||||
else
|
||||
{
|
||||
HGUInt xDpi, yDpi;
|
||||
HGBase_GetImageDpi(image2, &xDpi, &yDpi);
|
||||
quality = 80;
|
||||
cinfo.density_unit = 1;
|
||||
cinfo.X_density = xDpi;
|
||||
cinfo.Y_density = yDpi;
|
||||
}
|
||||
|
||||
jpeg_set_quality(&cinfo, (int)quality, TRUE);
|
||||
jpeg_start_compress(&cinfo, TRUE);
|
||||
|
||||
while (cinfo.next_scanline < cinfo.image_height)
|
||||
{
|
||||
uint8_t* pEx = data + (HGSize)cinfo.next_scanline * (HGSize)imgInfo.widthStep;
|
||||
jpeg_write_scanlines(&cinfo, &pEx, 1);
|
||||
}
|
||||
|
||||
jpeg_finish_compress(&cinfo);
|
||||
|
||||
HGBase_SetImageROI(image, &roi);
|
||||
HGBase_DestroyImage(image2);
|
||||
image2 = NULL;
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_SaveJpegImageToBuffer(HGImage image, const HGJpegSaveInfo* info, HGBuffer* buffer)
|
||||
{
|
||||
if (NULL == image || NULL == buffer)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (NULL != info)
|
||||
{
|
||||
// 判断info参数的合法性
|
||||
}
|
||||
|
||||
unsigned char* outbuffer = NULL;
|
||||
size_t outSize = 0;
|
||||
|
||||
struct jpeg_compress_struct cinfo;
|
||||
struct my_error_mgr jerr;
|
||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = my_error_exit;
|
||||
|
||||
HGImage image2 = NULL;
|
||||
HGImageRoi roi;
|
||||
HGBase_GetImageROI(image, &roi);
|
||||
|
||||
int jmpResult = setjmp(jerr.setjmp_buffer);
|
||||
if (0 != jmpResult)
|
||||
{
|
||||
HGBase_SetImageROI(image, &roi);
|
||||
HGBase_DestroyImage(image2);
|
||||
image2 = NULL;
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
// 只有libjpeg为静态库的时候,才能用free
|
||||
// 否则应该使用jpeg_free_large(NULL, outbuffer, 0);
|
||||
jpeg_free_large(NULL, outbuffer, 0);
|
||||
return (HGResult)jmpResult;
|
||||
}
|
||||
|
||||
jpeg_create_compress(&cinfo);
|
||||
jpeg_mem_dest(&cinfo, &outbuffer, &outSize);
|
||||
|
||||
HGBase_ResetImageROI(image);
|
||||
HGImageInfo imgInfo;
|
||||
HGBase_GetImageInfo(image, &imgInfo);
|
||||
if (HGBASE_IMGTYPE_GRAY == imgInfo.type || HGBASE_IMGTYPE_BINARY == imgInfo.type)
|
||||
{
|
||||
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_GRAY, HGBASE_IMGORIGIN_TOP, &image2);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
longjmp(jerr.setjmp_buffer, (int)ret);
|
||||
}
|
||||
else
|
||||
{
|
||||
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_RGB, HGBASE_IMGORIGIN_TOP, &image2);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
longjmp(jerr.setjmp_buffer, (int)ret);
|
||||
}
|
||||
|
||||
HGBase_GetImageInfo(image2, &imgInfo);
|
||||
uint32_t width = imgInfo.width;
|
||||
uint32_t height = imgInfo.height;
|
||||
uint32_t type = imgInfo.type;
|
||||
uint32_t widthStep = imgInfo.widthStep;
|
||||
uint8_t* data;
|
||||
HGBase_GetImageData(image2, &data);
|
||||
|
||||
cinfo.image_width = width;
|
||||
cinfo.image_height = height;
|
||||
cinfo.input_components = (HGBASE_IMGTYPE_GRAY != type) ? 3 : 1;
|
||||
cinfo.in_color_space = (HGBASE_IMGTYPE_GRAY != type) ? JCS_RGB : JCS_GRAYSCALE;
|
||||
jpeg_set_defaults(&cinfo);
|
||||
|
||||
int quality;
|
||||
if (NULL != info)
|
||||
{
|
||||
quality = info->quality;
|
||||
cinfo.density_unit = info->densityUnit;
|
||||
cinfo.X_density = info->xDensity;
|
||||
cinfo.Y_density = info->yDensity;
|
||||
}
|
||||
else
|
||||
{
|
||||
HGUInt xDpi, yDpi;
|
||||
HGBase_GetImageDpi(image2, &xDpi, &yDpi);
|
||||
quality = 80;
|
||||
cinfo.density_unit = 1;
|
||||
cinfo.X_density = xDpi;
|
||||
cinfo.Y_density = yDpi;
|
||||
}
|
||||
|
||||
jpeg_set_quality(&cinfo, (int)quality, TRUE);
|
||||
jpeg_start_compress(&cinfo, TRUE);
|
||||
|
||||
while (cinfo.next_scanline < cinfo.image_height)
|
||||
{
|
||||
uint8_t* pEx = data + (HGSize)cinfo.next_scanline * (HGSize)imgInfo.widthStep;
|
||||
jpeg_write_scanlines(&cinfo, &pEx, 1);
|
||||
}
|
||||
|
||||
jpeg_finish_compress(&cinfo);
|
||||
|
||||
HGBase_SetImageROI(image, &roi);
|
||||
HGBase_DestroyImage(image2);
|
||||
image2 = NULL;
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
|
||||
HGResult ret = HGBase_CreateBuffer(outSize, buffer);
|
||||
if (HGBASE_ERR_OK == ret)
|
||||
{
|
||||
HGByte* bufferData = NULL;
|
||||
HGBase_GetBufferData(*buffer, &bufferData);
|
||||
memcpy(bufferData, outbuffer, outSize);
|
||||
}
|
||||
|
||||
// 只有libjpeg为静态库的时候,才能用free
|
||||
// 否则应该使用jpeg_free_large(NULL, outbuffer, 0);
|
||||
jpeg_free_large(NULL, outbuffer, 0);
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
#ifndef __HGJPEG_H__
|
||||
#define __HGJPEG_H__
|
||||
|
||||
#include "../base/HGDef.h"
|
||||
#include "../base/HGBaseErr.h"
|
||||
#include "HGImgFmtErr.h"
|
||||
#include "../base/HGImage.h"
|
||||
#include "../base/HGBuffer.h"
|
||||
|
||||
/* 颜色空间 */
|
||||
#define HGIMGFMT_JPEGCLRSPACE_UNKNOWN 0L
|
||||
#define HGIMGFMT_JPEGCLRSPACE_GRAYSCALE 1L
|
||||
#define HGIMGFMT_JPEGCLRSPACE_RGB 2L
|
||||
|
||||
/* 分辨率单位 */
|
||||
#define HGIMGFMT_JPEGDENUNIT_INCH 1L /* 英寸 */
|
||||
#define HGIMGFMT_JPEGDENUNIT_CENTIMETER 2L /* 厘米 */
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGUInt width; /* 图像宽 */
|
||||
HGUInt height; /* 图像高 */
|
||||
HGUInt numComponents; /* 颜色数量 */
|
||||
HGUInt colorSpace; /* 颜色空间, 见HGIMGFMT_JPEGCLRSPACE_* */
|
||||
HGByte densityUnit; /* 分辨率单位, 见HGIMGFMT_JPEGDENUNIT_* */
|
||||
HGUShort xDensity; /* 分辨率x值 */
|
||||
HGUShort yDensity; /* 分辨率y值 */
|
||||
}HGJpegLoadInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGUInt quality; /* 压缩质量, 0-100 */
|
||||
HGByte densityUnit; /* 分辨率单位, 见HGIMGFMT_JPEGDENUNIT_* */
|
||||
HGUShort xDensity; /* 分辨率x值 */
|
||||
HGUShort yDensity; /* 分辨率y值 */
|
||||
}HGJpegSaveInfo;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_CheckJpegFile(const HGChar* fileName, HGBool *isJpeg);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_LoadJpegImage(const HGChar* fileName, HGJpegLoadInfo* info,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_LoadJpegImageFromBuffer(HGBuffer buffer, HGJpegLoadInfo* info,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_SaveJpegImage(HGImage image, const HGJpegSaveInfo* info, const HGChar* fileName);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_SaveJpegImageToBuffer(HGImage image, const HGJpegSaveInfo* info, HGBuffer *buffer);
|
||||
|
||||
#endif /* __HGJPEG_H__ */
|
|
@ -0,0 +1,173 @@
|
|||
#include "HGOfd.h"
|
||||
#include "HGOfdImpl.hpp"
|
||||
|
||||
HGResult HGAPI HGImgFmt_CheckOfdFile(const HGChar* fileName, HGBool* isOfd)
|
||||
{
|
||||
if (NULL == fileName || NULL == isOfd)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGOfdReader reader = NULL;
|
||||
HGResult ret = HGImgFmt_OpenOfdReader(fileName, &reader);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
*isOfd = HGTRUE;
|
||||
HGImgFmt_CloseOfdReader(reader);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_OpenOfdReader(const HGChar* fileName, HGOfdReader* reader)
|
||||
{
|
||||
if (NULL == fileName || NULL == reader)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGOfdReaderImpl* ofdReaderImpl = new HGOfdReaderImpl;
|
||||
HGResult ret = ofdReaderImpl->Open(fileName);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
delete ofdReaderImpl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
*reader = (HGOfdReader)ofdReaderImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_CloseOfdReader(HGOfdReader reader)
|
||||
{
|
||||
if (NULL == reader)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGOfdReaderImpl* ofdReaderImpl = (HGOfdReaderImpl *)reader;
|
||||
HGResult ret = ofdReaderImpl->Close();
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
delete ofdReaderImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_GetOfdPageCount(HGOfdReader reader, HGUInt* count)
|
||||
{
|
||||
if (NULL == reader)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGOfdReaderImpl* ofdReaderImpl = (HGOfdReaderImpl*)reader;
|
||||
return ofdReaderImpl->GetPageCount(count);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_GetOfdPageInfo(HGOfdReader reader, HGUInt page, HGOfdPageInfo* info)
|
||||
{
|
||||
if (NULL == reader)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGOfdReaderImpl* ofdReaderImpl = (HGOfdReaderImpl*)reader;
|
||||
return ofdReaderImpl->GetPageInfo(page, info);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_LoadImageFromOfdReader(HGOfdReader reader, HGUInt page, HGFloat xScale, HGFloat yScale,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image)
|
||||
{
|
||||
if (NULL == reader)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGOfdReaderImpl* ofdReaderImpl = (HGOfdReaderImpl*)reader;
|
||||
return ofdReaderImpl->LoadImage(page, xScale, yScale, imgType, imgOrigin, image);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_LoadOfdImage(const HGChar* fileName, HGOfdPageInfo* info, HGUInt imgType, HGUInt imgOrigin, HGImage* image)
|
||||
{
|
||||
HGOfdReader reader = NULL;
|
||||
HGResult ret = HGImgFmt_OpenOfdReader(fileName, &reader);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (HGBASE_ERR_OK == ret && NULL != info)
|
||||
ret = HGImgFmt_GetOfdPageInfo(reader, 0, info);
|
||||
|
||||
if (HGBASE_ERR_OK == ret && NULL != image)
|
||||
ret = HGImgFmt_LoadImageFromOfdReader(reader, 0, 1.0f, 1.0f, imgType, imgOrigin, image);
|
||||
|
||||
HGImgFmt_CloseOfdReader(reader);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_OpenOfdImageWriter(const HGChar* fileName, HGOfdImageWriter* writer)
|
||||
{
|
||||
if (NULL == fileName || NULL == writer)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGOfdImageWriterImpl* ofdImageWriterImpl = new HGOfdImageWriterImpl;
|
||||
HGResult ret = ofdImageWriterImpl->Open(fileName);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
delete ofdImageWriterImpl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
*writer = (HGOfdImageWriter)ofdImageWriterImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_CloseOfdImageWriter(HGOfdImageWriter writer)
|
||||
{
|
||||
if (NULL == writer)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGOfdImageWriterImpl* ofdImageWriterImpl = (HGOfdImageWriterImpl*)writer;
|
||||
HGResult ret = ofdImageWriterImpl->Close();
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
delete ofdImageWriterImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_SaveJpegImageToOfdImageWriter(HGOfdImageWriter writer, HGImage image, const HGJpegSaveInfo* info)
|
||||
{
|
||||
if (NULL == writer)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGOfdImageWriterImpl* ofdImageWriterImpl = (HGOfdImageWriterImpl*)writer;
|
||||
return ofdImageWriterImpl->SaveJpegImage(image, info);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_SaveOfdJpegImage(HGImage image, const HGJpegSaveInfo* info, const HGChar* fileName)
|
||||
{
|
||||
HGOfdImageWriter writer = NULL;
|
||||
HGResult ret = HGImgFmt_OpenOfdImageWriter(fileName, &writer);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = HGImgFmt_SaveJpegImageToOfdImageWriter(writer, image, info);
|
||||
HGImgFmt_CloseOfdImageWriter(writer);
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef __HGOFD_H__
|
||||
#define __HGOFD_H__
|
||||
|
||||
#include "../base/HGDef.h"
|
||||
#include "../base/HGBaseErr.h"
|
||||
#include "HGImgFmtErr.h"
|
||||
#include "../base/HGImage.h"
|
||||
#include "HGJpeg.h"
|
||||
|
||||
HG_DECLARE_HANDLE(HGOfdReader);
|
||||
HG_DECLARE_HANDLE(HGOfdImageWriter);
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGUInt width;
|
||||
HGUInt height;
|
||||
HGUInt bpp;
|
||||
}HGOfdPageInfo;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_CheckOfdFile(const HGChar* fileName, HGBool* isOfd);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_OpenOfdReader(const HGChar* fileName, HGOfdReader* reader);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_CloseOfdReader(HGOfdReader reader);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_GetOfdPageCount(HGOfdReader reader, HGUInt* count);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_GetOfdPageInfo(HGOfdReader reader, HGUInt page, HGOfdPageInfo* info);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_LoadImageFromOfdReader(HGOfdReader reader, HGUInt page, HGFloat xScale, HGFloat yScale,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_LoadOfdImage(const HGChar* fileName, HGOfdPageInfo* info, HGUInt imgType, HGUInt imgOrigin, HGImage* image);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_OpenOfdImageWriter(const HGChar* fileName, HGOfdImageWriter* writer);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_CloseOfdImageWriter(HGOfdImageWriter writer);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_SaveJpegImageToOfdImageWriter(HGOfdImageWriter writer, HGImage image, const HGJpegSaveInfo* info);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_SaveOfdJpegImage(HGImage image, const HGJpegSaveInfo* info, const HGChar* fileName);
|
||||
|
||||
#endif /* __HGOFD_H__ */
|
|
@ -0,0 +1,914 @@
|
|||
#include "HGOfdImpl.hpp"
|
||||
#include "../base/HGInc.h"
|
||||
#include "../base/HGInfo.h"
|
||||
#include "../base/HGUtility.h"
|
||||
#include "HGString.h"
|
||||
|
||||
#define A4page_page_PhysicalBox_Width 210.000000
|
||||
#define A4page_page_PhysicalBox_Height 297.000000
|
||||
|
||||
HGOfdReaderImpl::HGOfdReaderImpl()
|
||||
{
|
||||
m_zip = NULL;
|
||||
}
|
||||
|
||||
HGOfdReaderImpl::~HGOfdReaderImpl()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HGResult HGOfdReaderImpl::Open(const HGChar* fileName)
|
||||
{
|
||||
if (NULL != m_zip)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (0 != _access(fileName, 0))
|
||||
#else
|
||||
if (0 != access(fileName, 0))
|
||||
#endif
|
||||
{
|
||||
return HGBASE_ERR_FILENOTEXIST;
|
||||
}
|
||||
|
||||
int error = 0;
|
||||
m_zip = zip_open(StdStringToUtf8(fileName).c_str(), 0, &error);
|
||||
if (NULL == m_zip)
|
||||
{
|
||||
return HGBASE_ERR_FILEERROR;
|
||||
}
|
||||
|
||||
std::string content;
|
||||
HGResult ret = ReadXml("Doc_0/Document.xml", content);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
zip_close(m_zip);
|
||||
m_zip = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
tinyxml2::XMLDocument xmlDoc;
|
||||
if (tinyxml2::XML_SUCCESS == xmlDoc.Parse(content.c_str()))
|
||||
{
|
||||
tinyxml2::XMLElement* root = xmlDoc.RootElement();
|
||||
if (NULL != root)
|
||||
{
|
||||
tinyxml2::XMLElement* pages = root->FirstChildElement("ofd:Pages");
|
||||
if (NULL != pages)
|
||||
{
|
||||
tinyxml2::XMLElement* page = pages->FirstChildElement("ofd:Page");
|
||||
if (NULL != page)
|
||||
{
|
||||
const char* attr = page->Attribute("BaseLoc");
|
||||
if (NULL != attr)
|
||||
m_contentNames.push_back(attr);
|
||||
|
||||
tinyxml2::XMLElement* p = page->NextSiblingElement("ofd:Page");
|
||||
while (NULL != p)
|
||||
{
|
||||
const char* attr = p->Attribute("BaseLoc");
|
||||
if (NULL != attr)
|
||||
m_contentNames.push_back(attr);
|
||||
|
||||
p = p->NextSiblingElement("ofd:Page");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGResult HGOfdReaderImpl::Close()
|
||||
{
|
||||
if (NULL == m_zip)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
m_contentNames.clear();
|
||||
zip_close(m_zip);
|
||||
m_zip = NULL;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGOfdReaderImpl::GetPageCount(HGUInt* count)
|
||||
{
|
||||
if (NULL == m_zip)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
if (NULL == count)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
*count = (HGUInt)m_contentNames.size();
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
static bool GetRect(const char *text, double data[4])
|
||||
{
|
||||
bool ret = false;
|
||||
if (NULL == text)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
char str[256];
|
||||
strcpy(str, text);
|
||||
|
||||
int i = 0;
|
||||
char* pStr = strtok(str, " ");
|
||||
if (NULL != pStr)
|
||||
{
|
||||
data[i] = atof(pStr);
|
||||
++i;
|
||||
}
|
||||
while (i < 4)
|
||||
{
|
||||
pStr = strtok(NULL, " ");
|
||||
if (NULL == pStr)
|
||||
break;
|
||||
data[i] = atof(pStr);
|
||||
++i;
|
||||
}
|
||||
|
||||
return (4 == i);
|
||||
}
|
||||
|
||||
HGResult HGOfdReaderImpl::GetPageInfo(HGUInt page, HGOfdPageInfo* info)
|
||||
{
|
||||
if (NULL == m_zip)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
if (page >= (HGUInt)m_contentNames.size() || NULL == info)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
char name[128];
|
||||
sprintf(name, "Doc_0/%s", m_contentNames[page].c_str());
|
||||
|
||||
std::string content;
|
||||
HGResult ret = ReadXml(name, content);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
tinyxml2::XMLDocument xmlDoc;
|
||||
|
||||
std::string resId;
|
||||
if (tinyxml2::XML_SUCCESS == xmlDoc.Parse(content.c_str()))
|
||||
{
|
||||
tinyxml2::XMLElement* root = xmlDoc.RootElement();
|
||||
if (NULL != root)
|
||||
{
|
||||
tinyxml2::XMLElement* content = root->FirstChildElement("ofd:Content");
|
||||
if (NULL != content)
|
||||
{
|
||||
tinyxml2::XMLElement* layer = content->FirstChildElement("ofd:Layer");
|
||||
if (NULL != layer)
|
||||
{
|
||||
const char* attr = layer->Attribute("Type");
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (NULL == attr || 0 != _stricmp("Background", attr))
|
||||
#else
|
||||
if (NULL == attr || 0 != strcasecmp("Background", attr))
|
||||
#endif
|
||||
{
|
||||
tinyxml2::XMLElement* p = layer->NextSiblingElement("ofd:Layer");
|
||||
while (NULL != p)
|
||||
{
|
||||
const char* attr = p->Attribute("Type");
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (NULL != attr && 0 == _stricmp("Background", attr))
|
||||
#else
|
||||
if (NULL != attr && 0 == strcasecmp("Background", attr))
|
||||
#endif
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
p = p->NextSiblingElement("ofd:Layer");
|
||||
}
|
||||
|
||||
layer = p;
|
||||
}
|
||||
|
||||
if (NULL != layer)
|
||||
{
|
||||
tinyxml2::XMLElement* imgObject = layer->FirstChildElement("ofd:ImageObject");
|
||||
if (NULL != imgObject)
|
||||
{
|
||||
resId = imgObject->Attribute("ResourceID");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (resId.empty())
|
||||
{
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
ret = ReadXml("Doc_0/DocumentRes.xml", content);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string imgName;
|
||||
if (tinyxml2::XML_SUCCESS == xmlDoc.Parse(content.c_str()))
|
||||
{
|
||||
tinyxml2::XMLElement* root = xmlDoc.RootElement();
|
||||
if (NULL != root)
|
||||
{
|
||||
tinyxml2::XMLElement* multiMedias = root->FirstChildElement("ofd:MultiMedias");
|
||||
if (NULL != multiMedias)
|
||||
{
|
||||
tinyxml2::XMLElement* multiMedia = multiMedias->FirstChildElement("ofd:MultiMedia");
|
||||
if (NULL != multiMedia)
|
||||
{
|
||||
const char* attr = multiMedia->Attribute("ID");
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (NULL == attr || 0 != _stricmp(resId.c_str(), attr))
|
||||
#else
|
||||
if (NULL == attr || 0 != strcasecmp(resId.c_str(), attr))
|
||||
#endif
|
||||
{
|
||||
tinyxml2::XMLElement* p = multiMedia->NextSiblingElement("ofd:MultiMedia");
|
||||
while (NULL != p)
|
||||
{
|
||||
const char* attr = p->Attribute("ID");
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (NULL != attr && 0 == _stricmp(resId.c_str(), attr))
|
||||
#else
|
||||
if (NULL != attr && 0 == strcasecmp(resId.c_str(), attr))
|
||||
#endif
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
p = p->NextSiblingElement("ofd:MultiMedia");
|
||||
}
|
||||
|
||||
multiMedia = p;
|
||||
}
|
||||
|
||||
if (NULL != multiMedia)
|
||||
{
|
||||
tinyxml2::XMLElement* mediaFile = multiMedia->FirstChildElement("ofd:MediaFile");
|
||||
if (NULL != mediaFile)
|
||||
{
|
||||
imgName = mediaFile->GetText();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (imgName.empty())
|
||||
{
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
char img_name[128];
|
||||
sprintf(img_name, "Doc_0/Res/%s", imgName.c_str());
|
||||
|
||||
HGJpegLoadInfo jpegInfo;
|
||||
ret = ReadJpeg(img_name, &jpegInfo, 0, 0, 0, 0, NULL);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
info->width = jpegInfo.width;
|
||||
info->height = jpegInfo.height;
|
||||
info->bpp = jpegInfo.numComponents * 8;
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGResult HGOfdReaderImpl::LoadImage(HGUInt page, HGFloat xScale, HGFloat yScale,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image)
|
||||
{
|
||||
if (NULL == m_zip)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
if (0 != imgOrigin && HGBASE_IMGORIGIN_TOP != imgOrigin && HGBASE_IMGORIGIN_BOTTOM != imgOrigin)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (page >= (HGUInt)m_contentNames.size() || NULL == image)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
char name[128];
|
||||
sprintf(name, "Doc_0/%s", m_contentNames[page].c_str());
|
||||
|
||||
std::string content;
|
||||
HGResult ret = ReadXml(name, content);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
tinyxml2::XMLDocument xmlDoc;
|
||||
|
||||
std::string resId;
|
||||
if (tinyxml2::XML_SUCCESS == xmlDoc.Parse(content.c_str()))
|
||||
{
|
||||
tinyxml2::XMLElement* root = xmlDoc.RootElement();
|
||||
if (NULL != root)
|
||||
{
|
||||
tinyxml2::XMLElement* content = root->FirstChildElement("ofd:Content");
|
||||
if (NULL != content)
|
||||
{
|
||||
tinyxml2::XMLElement* layer = content->FirstChildElement("ofd:Layer");
|
||||
if (NULL != layer)
|
||||
{
|
||||
const char* attr = layer->Attribute("Type");
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (NULL == attr || 0 != _stricmp("Background", attr))
|
||||
#else
|
||||
if (NULL == attr || 0 != strcasecmp("Background", attr))
|
||||
#endif
|
||||
{
|
||||
tinyxml2::XMLElement* p = layer->NextSiblingElement("ofd:Layer");
|
||||
while (NULL != p)
|
||||
{
|
||||
const char* attr = p->Attribute("Type");
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (NULL != attr && 0 == _stricmp("Background", attr))
|
||||
#else
|
||||
if (NULL != attr && 0 == strcasecmp("Background", attr))
|
||||
#endif
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
p = p->NextSiblingElement("ofd:Layer");
|
||||
}
|
||||
|
||||
layer = p;
|
||||
}
|
||||
|
||||
if (NULL != layer)
|
||||
{
|
||||
tinyxml2::XMLElement* imgObject = layer->FirstChildElement("ofd:ImageObject");
|
||||
if (NULL != imgObject)
|
||||
{
|
||||
resId = imgObject->Attribute("ResourceID");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (resId.empty())
|
||||
{
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
ret = ReadXml("Doc_0/DocumentRes.xml", content);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string imgName;
|
||||
if (tinyxml2::XML_SUCCESS == xmlDoc.Parse(content.c_str()))
|
||||
{
|
||||
tinyxml2::XMLElement* root = xmlDoc.RootElement();
|
||||
if (NULL != root)
|
||||
{
|
||||
tinyxml2::XMLElement* multiMedias = root->FirstChildElement("ofd:MultiMedias");
|
||||
if (NULL != multiMedias)
|
||||
{
|
||||
tinyxml2::XMLElement* multiMedia = multiMedias->FirstChildElement("ofd:MultiMedia");
|
||||
if (NULL != multiMedia)
|
||||
{
|
||||
const char* attr = multiMedia->Attribute("ID");
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (NULL == attr || 0 != _stricmp(resId.c_str(), attr))
|
||||
#else
|
||||
if (NULL == attr || 0 != strcasecmp(resId.c_str(), attr))
|
||||
#endif
|
||||
{
|
||||
tinyxml2::XMLElement* p = multiMedia->NextSiblingElement("ofd:MultiMedia");
|
||||
while (NULL != p)
|
||||
{
|
||||
const char* attr = p->Attribute("ID");
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (NULL != attr && 0 == _stricmp(resId.c_str(), attr))
|
||||
#else
|
||||
if (NULL != attr && 0 == strcasecmp(resId.c_str(), attr))
|
||||
#endif
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
p = p->NextSiblingElement("ofd:MultiMedia");
|
||||
}
|
||||
|
||||
multiMedia = p;
|
||||
}
|
||||
|
||||
if (NULL != multiMedia)
|
||||
{
|
||||
tinyxml2::XMLElement* mediaFile = multiMedia->FirstChildElement("ofd:MediaFile");
|
||||
if (NULL != mediaFile)
|
||||
{
|
||||
imgName = mediaFile->GetText();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (imgName.empty())
|
||||
{
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
char img_name[128];
|
||||
sprintf(img_name, "Doc_0/Res/%s", imgName.c_str());
|
||||
ret = ReadJpeg(img_name, NULL, xScale, yScale, imgType, imgOrigin, image);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGResult HGOfdReaderImpl::ReadXml(const char* name, std::string& content)
|
||||
{
|
||||
struct zip_stat st;
|
||||
zip_stat_init(&st);
|
||||
zip_stat(m_zip, name, ZIP_FL_NOCASE, &st);
|
||||
|
||||
zip_int64_t size = st.size;
|
||||
if (0 == size)
|
||||
{
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
zip_file* file = zip_fopen(m_zip, name, ZIP_FL_NOCASE);
|
||||
if (NULL == file)
|
||||
{
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
char* s = (char*)malloc((size_t)size + 1);
|
||||
if (NULL == s)
|
||||
{
|
||||
zip_fclose(file);
|
||||
return HGBASE_ERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
zip_int64_t did_read = zip_fread(file, s, size);
|
||||
if (did_read != size)
|
||||
{
|
||||
free(s);
|
||||
zip_fclose(file);
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
s[size] = 0;
|
||||
content = s;
|
||||
|
||||
free(s);
|
||||
zip_fclose(file);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGOfdReaderImpl::ReadJpeg(const char* name, HGJpegLoadInfo* info, HGFloat xScale, HGFloat yScale, HGUInt imgType, HGUInt imgOrigin, HGImage* image)
|
||||
{
|
||||
struct zip_stat st;
|
||||
zip_stat_init(&st);
|
||||
zip_stat(m_zip, name, ZIP_FL_NOCASE, &st);
|
||||
|
||||
zip_int64_t size = st.size;
|
||||
if (0 == size)
|
||||
{
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
zip_file* file = zip_fopen(m_zip, name, ZIP_FL_NOCASE);
|
||||
if (NULL == file)
|
||||
{
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
unsigned char* content = (unsigned char*)malloc((size_t)size);
|
||||
if (NULL == content)
|
||||
{
|
||||
zip_fclose(file);
|
||||
return HGBASE_ERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
zip_int64_t did_read = zip_fread(file, content, size);
|
||||
if (did_read != size)
|
||||
{
|
||||
free(content);
|
||||
zip_fclose(file);
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
HGBuffer buffer = NULL;
|
||||
HGBase_CreateBufferWithData(content, (size_t)size, &buffer);
|
||||
HGResult ret = HGImgFmt_LoadJpegImageFromBuffer(buffer, info, imgType, imgOrigin, image);
|
||||
HGBase_DestroyBuffer(buffer);
|
||||
|
||||
free(content);
|
||||
zip_fclose(file);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
HGOfdImageWriterImpl::HGOfdImageWriterImpl()
|
||||
{
|
||||
m_zip = NULL;
|
||||
m_curImgIndex = 0;
|
||||
}
|
||||
|
||||
HGOfdImageWriterImpl::~HGOfdImageWriterImpl()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HGResult HGOfdImageWriterImpl::Open(const HGChar* fileName)
|
||||
{
|
||||
if (NULL != m_zip)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
int error = 0;
|
||||
m_zip = zip_open(StdStringToUtf8(fileName).c_str(), ZIP_CREATE | ZIP_TRUNCATE, &error);
|
||||
if (NULL == m_zip)
|
||||
{
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "HGOfdImageWriterImpl::Open: zip_open fail, %s", fileName);
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
}
|
||||
|
||||
zip_add_dir(m_zip, "Doc_0");
|
||||
zip_add_dir(m_zip, "Doc_0/Pages");
|
||||
zip_add_dir(m_zip, "Doc_0/Res");
|
||||
|
||||
HGResult ret = AddOfdXml();
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
zip_close(m_zip);
|
||||
m_zip = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = AddPublicResXml();
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
zip_close(m_zip);
|
||||
m_zip = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGResult HGOfdImageWriterImpl::Close()
|
||||
{
|
||||
if (NULL == m_zip)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
AddDocXml();
|
||||
AddDocResXml();
|
||||
|
||||
zip_close(m_zip);
|
||||
m_zip = NULL;
|
||||
|
||||
// 清理临时文件
|
||||
std::list<std::string>::const_iterator iter;
|
||||
for (iter = m_tmpFiles.begin(); iter != m_tmpFiles.end(); ++iter)
|
||||
{
|
||||
HGBase_DeleteFile(iter->c_str());
|
||||
}
|
||||
|
||||
m_tmpFiles.clear();
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGOfdImageWriterImpl::SaveJpegImage(HGImage image, const HGJpegSaveInfo* info)
|
||||
{
|
||||
HGChar name[128];
|
||||
sprintf(name, "Doc_0/Res/image_%u.jpg", m_curImgIndex);
|
||||
HGResult ret = AddJpegImageFile(image, info, name);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGUInt xDpi, yDpi;
|
||||
HGBase_GetImageDpi(image, &xDpi, &yDpi);
|
||||
if (NULL != info)
|
||||
{
|
||||
if (HGIMGFMT_JPEGDENUNIT_INCH == info->densityUnit)
|
||||
{
|
||||
xDpi = info->xDensity;
|
||||
yDpi = info->yDensity;
|
||||
}
|
||||
else if (HGIMGFMT_JPEGDENUNIT_CENTIMETER == info->densityUnit)
|
||||
{
|
||||
xDpi = (uint32_t)((double)info->xDensity / 0.393700787 + 0.5);
|
||||
yDpi = (uint32_t)((double)info->yDensity / 0.393700787 + 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
HGImageInfo imgInfo;
|
||||
HGBase_GetImageInfo(image, &imgInfo);
|
||||
HGFloat physicalWidth = 25.4f * (HGFloat)imgInfo.width / (HGFloat)xDpi;
|
||||
HGFloat physicalHeight = 25.4f * (HGFloat)imgInfo.height / (HGFloat)yDpi;
|
||||
|
||||
AddContentXmlFile(m_curImgIndex, physicalWidth, physicalHeight);
|
||||
++m_curImgIndex;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGOfdImageWriterImpl::AddOfdXml()
|
||||
{
|
||||
tinyxml2::XMLDocument xmlDoc;
|
||||
|
||||
HGChar uuid[128];
|
||||
HGBase_GetUuid(uuid, 128);
|
||||
|
||||
time_t tm = time(NULL);
|
||||
struct tm *local_tm = localtime(&tm);
|
||||
char local_tm_str[256];
|
||||
strftime(local_tm_str, 256, "%c", local_tm);
|
||||
|
||||
tinyxml2::XMLElement *root = xmlDoc.NewElement("ofd:OFD");
|
||||
root->SetAttribute("xmlns:ofd", "http://www.ofdspec.org/2016");
|
||||
root->SetAttribute("DocType", "OFD");
|
||||
root->SetAttribute("Version", "1.0");
|
||||
xmlDoc.InsertEndChild(root);
|
||||
|
||||
tinyxml2::XMLElement* docBody = xmlDoc.NewElement("ofd:DocBody");
|
||||
root->InsertEndChild(docBody);
|
||||
|
||||
tinyxml2::XMLElement* docRoot = xmlDoc.NewElement("ofd:DocRoot");
|
||||
docRoot->SetText("Doc_0/Document.xml");
|
||||
docBody->InsertEndChild(docRoot);
|
||||
|
||||
tinyxml2::XMLElement* docInfo = xmlDoc.NewElement("ofd:DocInfo");
|
||||
docBody->InsertEndChild(docInfo);
|
||||
|
||||
tinyxml2::XMLElement* docId = xmlDoc.NewElement("ofd:DocID");
|
||||
docId->SetText(uuid);
|
||||
docInfo->InsertEndChild(docId);
|
||||
|
||||
tinyxml2::XMLElement* creationDate = xmlDoc.NewElement("ofd:CreationDate");
|
||||
creationDate->SetText(local_tm_str);
|
||||
docInfo->InsertEndChild(creationDate);
|
||||
|
||||
tinyxml2::XMLElement* modDate = xmlDoc.NewElement("ofd:ModDate");
|
||||
modDate->SetText(local_tm_str);
|
||||
docInfo->InsertEndChild(modDate);
|
||||
|
||||
tinyxml2::XMLElement* creator = xmlDoc.NewElement("ofd:Creator");
|
||||
creator->SetText("ofd");
|
||||
docInfo->InsertEndChild(creator);
|
||||
|
||||
tinyxml2::XMLElement* createVersion = xmlDoc.NewElement("ofd:CreatorVersion");
|
||||
createVersion->SetText("1.0.0");
|
||||
docInfo->InsertEndChild(createVersion);
|
||||
|
||||
return AddXmlFile(xmlDoc, "OFD.xml");
|
||||
}
|
||||
|
||||
HGResult HGOfdImageWriterImpl::AddDocXml()
|
||||
{
|
||||
tinyxml2::XMLDocument xmlDoc;
|
||||
|
||||
tinyxml2::XMLElement* root = xmlDoc.NewElement("ofd:Document");
|
||||
root->SetAttribute("xmlns:ofd", "http://www.ofdspec.org/2016");
|
||||
xmlDoc.InsertEndChild(root);
|
||||
|
||||
tinyxml2::XMLElement* commonData = xmlDoc.NewElement("ofd:CommonData");
|
||||
root->InsertEndChild(commonData);
|
||||
|
||||
tinyxml2::XMLElement* maxUnitID = xmlDoc.NewElement("ofd:MaxUnitID");
|
||||
HGChar maxId[24];
|
||||
sprintf(maxId, "%u", m_curImgIndex * 10 + 2);
|
||||
maxUnitID->SetText(maxId);
|
||||
commonData->InsertEndChild(maxUnitID);
|
||||
|
||||
tinyxml2::XMLElement* pageArea = xmlDoc.NewElement("ofd:PageArea");
|
||||
commonData->InsertEndChild(pageArea);
|
||||
|
||||
tinyxml2::XMLElement* publicRes = xmlDoc.NewElement("ofd:PublicRes");
|
||||
publicRes->SetText("PublicRes.xml");
|
||||
commonData->InsertEndChild(publicRes);
|
||||
|
||||
tinyxml2::XMLElement* documentRes = xmlDoc.NewElement("ofd:DocumentRes");
|
||||
documentRes->SetText("DocumentRes.xml");
|
||||
commonData->InsertEndChild(documentRes);
|
||||
|
||||
tinyxml2::XMLElement* physicalBox = xmlDoc.NewElement("ofd:PhysicalBox");
|
||||
char physicalBoxText[512];
|
||||
sprintf(physicalBoxText, "0.000000 0.000000 %f %f", A4page_page_PhysicalBox_Width,
|
||||
A4page_page_PhysicalBox_Height);
|
||||
physicalBox->SetText(physicalBoxText);
|
||||
pageArea->InsertEndChild(physicalBox);
|
||||
|
||||
tinyxml2::XMLElement* pages = xmlDoc.NewElement("ofd:Pages");
|
||||
root->InsertEndChild(pages);
|
||||
|
||||
for (HGUInt i = 0; i < m_curImgIndex; ++i)
|
||||
{
|
||||
tinyxml2::XMLElement* page = xmlDoc.NewElement("ofd:Page");
|
||||
|
||||
HGChar id[24];
|
||||
sprintf(id, "%u", i * 10 + 1);
|
||||
page->SetAttribute("ID", id);
|
||||
|
||||
HGChar loc[128];
|
||||
sprintf(loc, "Pages/Page_%u/Content.xml", i);
|
||||
page->SetAttribute("BaseLoc", loc);
|
||||
|
||||
pages->InsertEndChild(page);
|
||||
}
|
||||
|
||||
return AddXmlFile(xmlDoc, "Doc_0/Document.xml");
|
||||
}
|
||||
|
||||
HGResult HGOfdImageWriterImpl::AddDocResXml()
|
||||
{
|
||||
tinyxml2::XMLDocument xmlDoc;
|
||||
|
||||
tinyxml2::XMLElement* root = xmlDoc.NewElement("ofd:Res");
|
||||
root->SetAttribute("xmlns:ofd", "http://www.ofdspec.org/2016");
|
||||
root->SetAttribute("BaseLoc", "Res");
|
||||
xmlDoc.InsertEndChild(root);
|
||||
|
||||
tinyxml2::XMLElement* multiMedias = xmlDoc.NewElement("ofd:MultiMedias");
|
||||
root->InsertEndChild(multiMedias);
|
||||
|
||||
for (HGUInt i = 0; i < m_curImgIndex; ++i)
|
||||
{
|
||||
tinyxml2::XMLElement* multiMedia = xmlDoc.NewElement("ofd:MultiMedia");
|
||||
multiMedia->SetAttribute("Type", "Image");
|
||||
HGChar id[24];
|
||||
sprintf(id, "%u", i * 10 + 2);
|
||||
multiMedia->SetAttribute("ID", id);
|
||||
multiMedias->InsertEndChild(multiMedia);
|
||||
|
||||
tinyxml2::XMLElement* mediaFile = xmlDoc.NewElement("ofd:MediaFile");
|
||||
HGChar loc[128];
|
||||
sprintf(loc, "image_%u.jpg", i);
|
||||
mediaFile->SetText(loc);
|
||||
multiMedia->InsertEndChild(mediaFile);
|
||||
}
|
||||
|
||||
return AddXmlFile(xmlDoc, "Doc_0/DocumentRes.xml");
|
||||
}
|
||||
|
||||
HGResult HGOfdImageWriterImpl::AddPublicResXml()
|
||||
{
|
||||
tinyxml2::XMLDocument xmlDoc;
|
||||
|
||||
tinyxml2::XMLElement* root = xmlDoc.NewElement("ofd:Res");
|
||||
root->SetAttribute("xmlns:ofd", "http://www.ofdspec.org/2016");
|
||||
root->SetAttribute("BaseLoc", "Res");
|
||||
xmlDoc.InsertEndChild(root);
|
||||
|
||||
tinyxml2::XMLElement* fonts = xmlDoc.NewElement("ofd:Fonts");
|
||||
root->InsertEndChild(fonts);
|
||||
|
||||
return AddXmlFile(xmlDoc, "Doc_0/PublicRes.xml");
|
||||
}
|
||||
|
||||
HGResult HGOfdImageWriterImpl::AddXmlFile(tinyxml2::XMLDocument& xmlDoc, const HGChar* name)
|
||||
{
|
||||
HGChar tmpName[256];
|
||||
HGBase_GetTmpFileName(NULL, tmpName, 256);
|
||||
if (tinyxml2::XML_SUCCESS != xmlDoc.SaveFile(tmpName))
|
||||
{
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
zip_source_t* s = zip_source_file(m_zip, tmpName, 0, 0);
|
||||
if (NULL == s)
|
||||
{
|
||||
HGBase_DeleteFile(tmpName);
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
zip_int64_t ret = zip_file_add(m_zip, name, s, ZIP_FL_ENC_UTF_8 | ZIP_FL_OVERWRITE);
|
||||
if (ret < 0)
|
||||
{
|
||||
zip_source_free(s);
|
||||
HGBase_DeleteFile(tmpName);
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
m_tmpFiles.push_back(tmpName);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGOfdImageWriterImpl::AddJpegImageFile(HGImage image, const HGJpegSaveInfo* info, const HGChar* name)
|
||||
{
|
||||
HGChar tmpName[256];
|
||||
HGBase_GetTmpFileName(NULL, tmpName, 256);
|
||||
HGResult ret = HGImgFmt_SaveJpegImage(image, info, tmpName);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
zip_source_t* s = zip_source_file(m_zip, tmpName, 0, 0);
|
||||
if (NULL == s)
|
||||
{
|
||||
HGBase_DeleteFile(tmpName);
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
zip_int64_t rc = zip_file_add(m_zip, name, s, ZIP_FL_OVERWRITE);
|
||||
if (rc < 0)
|
||||
{
|
||||
zip_source_free(s);
|
||||
HGBase_DeleteFile(tmpName);
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
m_tmpFiles.push_back(tmpName);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGOfdImageWriterImpl::AddContentXmlFile(HGUInt index, HGFloat physicalWidth, HGFloat physicalHeight)
|
||||
{
|
||||
HGChar dir[128];
|
||||
sprintf(dir, "Doc_0/Pages/Page_%u", index);
|
||||
zip_add_dir(m_zip, dir);
|
||||
|
||||
tinyxml2::XMLDocument xmlDoc;
|
||||
|
||||
tinyxml2::XMLElement* root = xmlDoc.NewElement("ofd:Page");
|
||||
root->SetAttribute("xmlns:ofd", "http://www.ofdspec.org/2016");
|
||||
xmlDoc.InsertEndChild(root);
|
||||
|
||||
tinyxml2::XMLElement* area = xmlDoc.NewElement("ofd:Area");
|
||||
root->InsertEndChild(area);
|
||||
|
||||
tinyxml2::XMLElement* physicalBox = xmlDoc.NewElement("ofd:PhysicalBox");
|
||||
char physicalBoxText[512];
|
||||
sprintf(physicalBoxText, "0.000000 0.000000 %f %f", physicalWidth, physicalHeight);
|
||||
physicalBox->SetText(physicalBoxText);
|
||||
area->InsertEndChild(physicalBox);
|
||||
|
||||
tinyxml2::XMLElement* content = xmlDoc.NewElement("ofd:Content");
|
||||
root->InsertEndChild(content);
|
||||
|
||||
tinyxml2::XMLElement* layer = xmlDoc.NewElement("ofd:Layer");
|
||||
HGChar layerId[24];
|
||||
sprintf(layerId, "%u", index * 10 + 3);
|
||||
layer->SetAttribute("ID", layerId);
|
||||
layer->SetAttribute("Type", "Background");
|
||||
content->InsertEndChild(layer);
|
||||
|
||||
tinyxml2::XMLElement* imgObject = xmlDoc.NewElement("ofd:ImageObject");
|
||||
HGChar imgObjectId[24];
|
||||
sprintf(imgObjectId, "%u", index * 10 + 4);
|
||||
imgObject->SetAttribute("ID", imgObjectId);
|
||||
char boundaryText[512];
|
||||
sprintf(boundaryText, "0.000000 0.000000 %f %f", physicalWidth, physicalHeight);
|
||||
imgObject->SetAttribute("Boundary", boundaryText);
|
||||
HGChar imgObjectResId[24];
|
||||
sprintf(imgObjectResId, "%u", index * 10 + 2);
|
||||
imgObject->SetAttribute("ResourceID", imgObjectResId);
|
||||
char ctmText[512];
|
||||
sprintf(ctmText, "%f 0 0 %f 0 0", physicalWidth, physicalHeight);
|
||||
imgObject->SetAttribute("CTM", ctmText);
|
||||
layer->InsertEndChild(imgObject);
|
||||
|
||||
HGChar name[256];
|
||||
sprintf(name, "%s/Content.xml", dir);
|
||||
return AddXmlFile(xmlDoc, name);
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef __HGOFDIMPL_HPP__
|
||||
#define __HGOFDIMPL_HPP__
|
||||
|
||||
#include "HGOfd.h"
|
||||
extern "C"
|
||||
{
|
||||
#include "zip.h"
|
||||
};
|
||||
#include "tinyxml2.h"
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
class HGOfdReaderImpl
|
||||
{
|
||||
public:
|
||||
HGOfdReaderImpl();
|
||||
~HGOfdReaderImpl();
|
||||
|
||||
HGResult Open(const HGChar* fileName);
|
||||
HGResult Close();
|
||||
HGResult GetPageCount(HGUInt* count);
|
||||
HGResult GetPageInfo(HGUInt page, HGOfdPageInfo* info);
|
||||
HGResult LoadImage(HGUInt page, HGFloat xScale, HGFloat yScale,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image);
|
||||
|
||||
private:
|
||||
HGResult ReadXml(const char *name, std::string &content);
|
||||
HGResult ReadJpeg(const char* name, HGJpegLoadInfo *info, HGFloat xScale, HGFloat yScale, HGUInt imgType, HGUInt imgOrigin, HGImage* image);
|
||||
|
||||
private:
|
||||
zip* m_zip;
|
||||
std::vector<std::string> m_contentNames;
|
||||
};
|
||||
|
||||
class HGOfdImageWriterImpl
|
||||
{
|
||||
public:
|
||||
HGOfdImageWriterImpl();
|
||||
~HGOfdImageWriterImpl();
|
||||
|
||||
HGResult Open(const HGChar* fileName);
|
||||
HGResult Close();
|
||||
HGResult SaveJpegImage(HGImage image, const HGJpegSaveInfo* info);
|
||||
|
||||
private:
|
||||
HGResult AddOfdXml();
|
||||
HGResult AddDocXml();
|
||||
HGResult AddDocResXml();
|
||||
HGResult AddPublicResXml();
|
||||
HGResult AddXmlFile(tinyxml2::XMLDocument &xmlDoc, const HGChar *name);
|
||||
HGResult AddJpegImageFile(HGImage image, const HGJpegSaveInfo* info, const HGChar* name);
|
||||
HGResult AddContentXmlFile(HGUInt index, HGFloat physicalWidth, HGFloat physicalHeight);
|
||||
|
||||
private:
|
||||
zip* m_zip;
|
||||
std::list<std::string> m_tmpFiles;
|
||||
HGUInt m_curImgIndex;
|
||||
};
|
||||
|
||||
#endif /* __HGOFDIMPL_HPP__ */
|
|
@ -0,0 +1,173 @@
|
|||
#include "HGPdf.h"
|
||||
#include "HGPdfImpl.hpp"
|
||||
|
||||
HGResult HGAPI HGImgFmt_CheckPdfFile(const HGChar* fileName, HGBool* isPdf)
|
||||
{
|
||||
if (NULL == fileName || NULL == isPdf)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGPdfReader reader = NULL;
|
||||
HGResult ret = HGImgFmt_OpenPdfReader(fileName, &reader);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
*isPdf = HGTRUE;
|
||||
HGImgFmt_ClosePdfReader(reader);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_OpenPdfReader(const HGChar* fileName, HGPdfReader* reader)
|
||||
{
|
||||
if (NULL == reader)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGPdfReaderImpl* pdfReaderImpl = new HGPdfReaderImpl;
|
||||
HGResult ret = pdfReaderImpl->Open(fileName);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
delete pdfReaderImpl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
*reader = (HGPdfReader)pdfReaderImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_ClosePdfReader(HGPdfReader reader)
|
||||
{
|
||||
if (NULL == reader)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGPdfReaderImpl* pdfReaderImpl = (HGPdfReaderImpl*)reader;
|
||||
HGResult ret = pdfReaderImpl->Close();
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
delete pdfReaderImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_GetPdfPageCount(HGPdfReader reader, HGUInt* count)
|
||||
{
|
||||
if (NULL == reader)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGPdfReaderImpl* pdfReaderImpl = (HGPdfReaderImpl*)reader;
|
||||
return pdfReaderImpl->GetPageCount(count);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_GetPdfPageInfo(HGPdfReader reader, HGUInt page, HGPdfPageInfo* info)
|
||||
{
|
||||
if (NULL == reader)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGPdfReaderImpl* pdfReaderImpl = (HGPdfReaderImpl*)reader;
|
||||
return pdfReaderImpl->GetPageInfo(page, info);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_LoadImageFromPdfReader(HGPdfReader reader, HGUInt page, HGFloat xScale, HGFloat yScale,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image)
|
||||
{
|
||||
if (NULL == reader)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGPdfReaderImpl* pdfReaderImpl = (HGPdfReaderImpl*)reader;
|
||||
return pdfReaderImpl->LoadImage(page, xScale, yScale, imgType, imgOrigin, image);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_LoadPdfImage(const HGChar* fileName, HGPdfPageInfo* info, HGUInt imgType, HGUInt imgOrigin, HGImage* image)
|
||||
{
|
||||
HGPdfReader reader = NULL;
|
||||
HGResult ret = HGImgFmt_OpenPdfReader(fileName, &reader);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (HGBASE_ERR_OK == ret && NULL != info)
|
||||
ret = HGImgFmt_GetPdfPageInfo(reader, 0, info);
|
||||
|
||||
if (HGBASE_ERR_OK == ret && NULL != image)
|
||||
ret = HGImgFmt_LoadImageFromPdfReader(reader, 0, 1.0f, 1.0f, imgType, imgOrigin, image);
|
||||
|
||||
HGImgFmt_ClosePdfReader(reader);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_OpenPdfImageWriter(const HGChar* fileName, HGPdfImageWriter* writer)
|
||||
{
|
||||
if (NULL == writer)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGPdfImageWriterImpl* pdfImageWriterImpl = new HGPdfImageWriterImpl;
|
||||
HGResult ret = pdfImageWriterImpl->Open(fileName);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
delete pdfImageWriterImpl;
|
||||
return ret;
|
||||
}
|
||||
|
||||
*writer = (HGPdfImageWriter)pdfImageWriterImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_ClosePdfImageWriter(HGPdfImageWriter writer)
|
||||
{
|
||||
if (NULL == writer)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGPdfImageWriterImpl* pdfImageWriterImpl = (HGPdfImageWriterImpl*)writer;
|
||||
HGResult ret = pdfImageWriterImpl->Close();
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
delete pdfImageWriterImpl;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_SaveJpegImageToPdfImageWriter(HGPdfImageWriter writer, HGImage image, const HGJpegSaveInfo* info)
|
||||
{
|
||||
if (NULL == writer)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGPdfImageWriterImpl* pdfImageWriterImpl = (HGPdfImageWriterImpl*)writer;
|
||||
return pdfImageWriterImpl->SaveJpegImage(image, info);
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_SavePdfJpegImage(HGImage image, const HGJpegSaveInfo* info, const HGChar* fileName)
|
||||
{
|
||||
HGPdfImageWriter writer = NULL;
|
||||
HGResult ret = HGImgFmt_OpenPdfImageWriter(fileName, &writer);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = HGImgFmt_SaveJpegImageToPdfImageWriter(writer, image, info);
|
||||
HGImgFmt_ClosePdfImageWriter(writer);
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef __HGPDF_H__
|
||||
#define __HGPDF_H__
|
||||
|
||||
#include "../base/HGDef.h"
|
||||
#include "../base/HGBaseErr.h"
|
||||
#include "HGImgFmtErr.h"
|
||||
#include "../base/HGImage.h"
|
||||
#include "HGJpeg.h"
|
||||
|
||||
HG_DECLARE_HANDLE(HGPdfReader);
|
||||
HG_DECLARE_HANDLE(HGPdfImageWriter);
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGUInt width;
|
||||
HGUInt height;
|
||||
HGUInt bpp;
|
||||
}HGPdfPageInfo;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_CheckPdfFile(const HGChar* fileName, HGBool* isPdf);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_OpenPdfReader(const HGChar* fileName, HGPdfReader* reader);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_ClosePdfReader(HGPdfReader reader);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_GetPdfPageCount(HGPdfReader reader, HGUInt* count);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_GetPdfPageInfo(HGPdfReader reader, HGUInt page, HGPdfPageInfo *info);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_LoadImageFromPdfReader(HGPdfReader reader, HGUInt page, HGFloat xScale, HGFloat yScale,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_LoadPdfImage(const HGChar* fileName, HGPdfPageInfo *info, HGUInt imgType, HGUInt imgOrigin, HGImage* image);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_OpenPdfImageWriter(const HGChar* fileName, HGPdfImageWriter* writer);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_ClosePdfImageWriter(HGPdfImageWriter writer);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_SaveJpegImageToPdfImageWriter(HGPdfImageWriter writer, HGImage image, const HGJpegSaveInfo* info);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_SavePdfJpegImage(HGImage image, const HGJpegSaveInfo* info, const HGChar* fileName);
|
||||
|
||||
#endif /* __HGPDF_H__ */
|
|
@ -0,0 +1,890 @@
|
|||
#include "HGPdfImpl.hpp"
|
||||
#include "../base/HGInc.h"
|
||||
#include "../base/HGUtility.h"
|
||||
#include "../base/HGInfo.h"
|
||||
#include "HGString.h"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
HGPdfReaderImpl::HGPdfReaderImpl()
|
||||
{
|
||||
m_dll = NULL;
|
||||
m_pContext = NULL;
|
||||
m_pDoc = NULL;
|
||||
}
|
||||
|
||||
HGPdfReaderImpl::~HGPdfReaderImpl()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HGResult HGPdfReaderImpl::Open(const HGChar* fileName)
|
||||
{
|
||||
if (NULL != m_pDoc)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
if (NULL == fileName)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (0 != _access(fileName, 0))
|
||||
#else
|
||||
if (0 != access(fileName, 0))
|
||||
#endif
|
||||
{
|
||||
return HGBASE_ERR_FILENOTEXIST;
|
||||
}
|
||||
|
||||
HGBool isPdfFile = HGFALSE;
|
||||
FILE* file = fopen(fileName, "r");
|
||||
if (NULL != file)
|
||||
{
|
||||
HGByte data[4];
|
||||
size_t len = fread(data, 1, 4, file);
|
||||
if (4 == len && 0 == memcmp(data, "%PDF", 4))
|
||||
{
|
||||
isPdfFile = HGTRUE;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
}
|
||||
else
|
||||
{
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
}
|
||||
|
||||
if (!isPdfFile)
|
||||
{
|
||||
return HGBASE_ERR_FILEERROR;
|
||||
}
|
||||
|
||||
assert(NULL == m_dll);
|
||||
|
||||
HGChar moduleName[256];
|
||||
HGBase_GetModuleName((void *)HGImgFmt_OpenPdfReader, moduleName, 256);
|
||||
HGChar dllPath[256];
|
||||
HGBase_GetFilePath(moduleName, dllPath, 256);
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
strcat(dllPath, "libmupdf.dll");
|
||||
#else
|
||||
strcat(dllPath, "libmupdf.so");
|
||||
#endif
|
||||
HGResult ret = HGBase_CreateDll(dllPath, &m_dll);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
fz_context* pContext = fz_new_context(NULL, NULL, FZ_STORE_DEFAULT);
|
||||
if (NULL == pContext)
|
||||
{
|
||||
HGBase_DestroyDll(m_dll);
|
||||
m_dll = NULL;
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
ret = HGIMGFMT_ERR_FAIL;
|
||||
fz_try(pContext)
|
||||
{
|
||||
fz_register_document_handlers(pContext);
|
||||
fz_document* pDoc = fz_open_document(pContext, StdStringToUtf8(fileName).c_str());
|
||||
|
||||
m_pContext = pContext;
|
||||
m_pDoc = pDoc;
|
||||
ret = HGBASE_ERR_OK;
|
||||
}
|
||||
fz_catch(pContext)
|
||||
{
|
||||
fz_drop_context(pContext);
|
||||
pContext = NULL;
|
||||
HGBase_DestroyDll(m_dll);
|
||||
m_dll = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGResult HGPdfReaderImpl::Close()
|
||||
{
|
||||
if (NULL == m_pDoc)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
fz_drop_document(m_pContext, m_pDoc);
|
||||
m_pDoc = NULL;
|
||||
fz_drop_context(m_pContext);
|
||||
m_pContext = NULL;
|
||||
HGBase_DestroyDll(m_dll);
|
||||
m_dll = NULL;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGPdfReaderImpl::GetPageCount(HGUInt* count)
|
||||
{
|
||||
if (NULL == m_pDoc)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
if (NULL == count)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGResult ret = HGIMGFMT_ERR_FAIL;
|
||||
fz_try(m_pContext)
|
||||
{
|
||||
*count = (uint32_t)fz_count_pages(m_pContext, m_pDoc);
|
||||
ret = HGBASE_ERR_OK;
|
||||
}
|
||||
fz_catch(m_pContext)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGResult HGPdfReaderImpl::GetPageInfo(HGUInt page, HGPdfPageInfo* info)
|
||||
{
|
||||
if (NULL == m_pDoc)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
if (NULL == info)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGResult ret = HGIMGFMT_ERR_FAIL;
|
||||
fz_page* fzpage = NULL;
|
||||
|
||||
fz_try(m_pContext)
|
||||
{
|
||||
fzpage = fz_load_page(m_pContext, m_pDoc, (int)page);
|
||||
pdf_page* page = pdf_page_from_fz_page(m_pContext, fzpage);
|
||||
if (NULL != page)
|
||||
{
|
||||
fz_rect pdfRect = pdf_bound_page(m_pContext, page);
|
||||
info->width = ceil(pdfRect.x1);
|
||||
info->height = ceil(pdfRect.y1);
|
||||
info->bpp = 24;
|
||||
ret = HGBASE_ERR_OK;
|
||||
}
|
||||
}
|
||||
fz_catch(m_pContext)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (NULL != fzpage)
|
||||
fz_drop_page(m_pContext, fzpage);
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGResult HGPdfReaderImpl::LoadImage(HGUInt page, HGFloat xScale, HGFloat yScale,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image)
|
||||
{
|
||||
if (NULL == m_pDoc)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
if (0 != imgOrigin && HGBASE_IMGORIGIN_TOP != imgOrigin && HGBASE_IMGORIGIN_BOTTOM != imgOrigin)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (NULL == image)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGResult ret = HGIMGFMT_ERR_FAIL;
|
||||
fz_pixmap* pix = NULL;
|
||||
|
||||
fz_try(m_pContext)
|
||||
{
|
||||
fz_matrix ctm = fz_scale(xScale, yScale);
|
||||
pix = fz_new_pixmap_from_page_number(m_pContext, m_pDoc, (int)page,
|
||||
ctm, fz_device_rgb(m_pContext), 0);
|
||||
|
||||
int width = fz_pixmap_width(m_pContext, pix);
|
||||
int height = fz_pixmap_height(m_pContext, pix);
|
||||
|
||||
if (0 == imgType)
|
||||
imgType = HGBASE_IMGTYPE_RGB;
|
||||
|
||||
if (imgOrigin == 0)
|
||||
imgOrigin = HGBASE_IMGORIGIN_TOP;
|
||||
|
||||
HGImage image2 = NULL;
|
||||
HGImageInfo imgInfo = { (uint32_t)width, (uint32_t)height, HGBASE_IMGTYPE_RGB, (uint32_t)pix->stride, HGBASE_IMGORIGIN_TOP };
|
||||
if (HGBASE_ERR_OK == HGBase_CreateImageWithData(pix->samples, &imgInfo, &image2))
|
||||
{
|
||||
ret = HGBase_CloneImage(image2, imgType, imgOrigin, image);
|
||||
HGBase_DestroyImage(image2);
|
||||
}
|
||||
|
||||
}
|
||||
fz_catch(m_pContext)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if (NULL != pix)
|
||||
fz_drop_pixmap(m_pContext, pix);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fz_context* HGPdfReaderImpl::fz_new_context_imp(const fz_alloc_context* alloc, const fz_locks_context* locks, size_t max_store, const char* version)
|
||||
{
|
||||
typedef fz_context* (*Func)(const fz_alloc_context*, const fz_locks_context*, size_t, const char*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_new_context_imp", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return func(alloc, locks, max_store, version);
|
||||
}
|
||||
|
||||
void HGPdfReaderImpl::fz_register_document_handlers(fz_context* ctx)
|
||||
{
|
||||
typedef void (*Func)(fz_context*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_register_document_handlers", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
func(ctx);
|
||||
}
|
||||
|
||||
fz_document* HGPdfReaderImpl::fz_open_document(fz_context* ctx, const char* filename)
|
||||
{
|
||||
typedef fz_document* (*Func)(fz_context*, const char*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_open_document", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return func(ctx, filename);
|
||||
}
|
||||
|
||||
void HGPdfReaderImpl::fz_drop_context(fz_context* ctx)
|
||||
{
|
||||
typedef void (*Func)(fz_context*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_drop_context", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
func(ctx);
|
||||
}
|
||||
|
||||
void HGPdfReaderImpl::fz_drop_document(fz_context* ctx, fz_document* doc)
|
||||
{
|
||||
typedef void (*Func)(fz_context*, fz_document*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_drop_document", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
func(ctx, doc);
|
||||
}
|
||||
|
||||
int HGPdfReaderImpl::fz_count_pages(fz_context* ctx, fz_document* doc)
|
||||
{
|
||||
typedef int (*Func)(fz_context*, fz_document*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_count_pages", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return func(ctx, doc);
|
||||
}
|
||||
|
||||
fz_page* HGPdfReaderImpl::fz_load_page(fz_context* ctx, fz_document* doc, int number)
|
||||
{
|
||||
typedef fz_page* (*Func)(fz_context*, fz_document* doc, int);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_load_page", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return func(ctx, doc, number);
|
||||
}
|
||||
|
||||
pdf_page* HGPdfReaderImpl::pdf_page_from_fz_page(fz_context* ctx, fz_page* ptr)
|
||||
{
|
||||
typedef pdf_page* (*Func)(fz_context*, fz_page*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "pdf_page_from_fz_page", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return func(ctx, ptr);
|
||||
}
|
||||
|
||||
fz_rect HGPdfReaderImpl::pdf_bound_page(fz_context* ctx, pdf_page* page)
|
||||
{
|
||||
typedef fz_rect (*Func)(fz_context*, pdf_page*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "pdf_bound_page", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
fz_rect rect = {0, 0, 0, 0};
|
||||
return rect;
|
||||
}
|
||||
|
||||
return func(ctx, page);
|
||||
}
|
||||
|
||||
void HGPdfReaderImpl::fz_drop_page(fz_context* ctx, fz_page* page)
|
||||
{
|
||||
typedef void (*Func)(fz_context*, fz_page*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_drop_page", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
func(ctx, page);
|
||||
}
|
||||
|
||||
fz_matrix HGPdfReaderImpl::fz_scale(float sx, float sy)
|
||||
{
|
||||
typedef fz_matrix (*Func)(float, float);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_scale", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
fz_matrix matrix = { 0, 0, 0, 0, 0, 0 };
|
||||
return matrix;
|
||||
}
|
||||
|
||||
return func(sx, sy);
|
||||
}
|
||||
|
||||
fz_pixmap* HGPdfReaderImpl::fz_new_pixmap_from_page_number(fz_context* ctx, fz_document* doc, int number, fz_matrix ctm, fz_colorspace* cs, int alpha)
|
||||
{
|
||||
typedef fz_pixmap* (*Func)(fz_context*, fz_document*, int, fz_matrix, fz_colorspace*, int);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_new_pixmap_from_page_number", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return func(ctx, doc, number, ctm, cs, alpha);
|
||||
}
|
||||
|
||||
fz_colorspace* HGPdfReaderImpl::fz_device_rgb(fz_context* ctx)
|
||||
{
|
||||
typedef fz_colorspace* (*Func)(fz_context*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_device_rgb", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return func(ctx);
|
||||
}
|
||||
|
||||
int HGPdfReaderImpl::fz_pixmap_width(fz_context* ctx, const fz_pixmap* pix)
|
||||
{
|
||||
typedef int (*Func)(fz_context*, const fz_pixmap*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_pixmap_width", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return func(ctx, pix);
|
||||
}
|
||||
|
||||
int HGPdfReaderImpl::fz_pixmap_height(fz_context* ctx, const fz_pixmap* pix)
|
||||
{
|
||||
typedef int (*Func)(fz_context*, const fz_pixmap*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_pixmap_height", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return func(ctx, pix);
|
||||
}
|
||||
|
||||
void HGPdfReaderImpl::fz_drop_pixmap(fz_context* ctx, fz_pixmap* pix)
|
||||
{
|
||||
typedef void (*Func)(fz_context*, fz_pixmap*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_drop_pixmap", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
func(ctx, pix);
|
||||
}
|
||||
|
||||
fz_jmp_buf* HGPdfReaderImpl::fz_push_try(fz_context* ctx)
|
||||
{
|
||||
typedef fz_jmp_buf* (*Func)(fz_context*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_push_try", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return func(ctx);
|
||||
}
|
||||
|
||||
int HGPdfReaderImpl::fz_do_try(fz_context* ctx)
|
||||
{
|
||||
typedef int (*Func)(fz_context*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_do_try", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return func(ctx);
|
||||
}
|
||||
|
||||
int HGPdfReaderImpl::fz_do_catch(fz_context* ctx)
|
||||
{
|
||||
typedef int (*Func)(fz_context*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "fz_do_catch", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return func(ctx);
|
||||
}
|
||||
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
static WCHAR* GetUnicodeStr(const char* text)
|
||||
{
|
||||
int len = ::MultiByteToWideChar(CP_ACP, 0, text, -1, NULL, 0);
|
||||
WCHAR* pUnicode = new WCHAR[len];
|
||||
::MultiByteToWideChar(CP_ACP, 0, text, -1, pUnicode, len);
|
||||
return pUnicode;
|
||||
}
|
||||
static uint32_t GetUnicodeStrLen(const WCHAR* pUnicode)
|
||||
{
|
||||
return (uint32_t)wcslen(pUnicode);
|
||||
}
|
||||
#else
|
||||
static uint16_t* GetUnicodeStr(const char* text)
|
||||
{
|
||||
if (0 == *text)
|
||||
{
|
||||
uint16_t* pUnicode = new uint16_t[1];
|
||||
*pUnicode = 0;
|
||||
return pUnicode;
|
||||
}
|
||||
|
||||
uint16_t* pUnicode = new uint16_t[strlen(text) + 2];
|
||||
memset(pUnicode, 0, sizeof(uint16_t) * (strlen(text) + 2));
|
||||
|
||||
iconv_t cd = iconv_open("UNICODE//IGNORE", "UTF-8");
|
||||
if ((iconv_t)-1 != cd)
|
||||
{
|
||||
char* inbuf = (char*)text;
|
||||
size_t inbytes = strlen(text);
|
||||
char* outbuf = (char*)pUnicode;
|
||||
size_t outsize = sizeof(uint16_t) * (strlen(text) + 1);
|
||||
|
||||
iconv(cd, &inbuf, &inbytes, &outbuf, &outsize);
|
||||
iconv_close(cd);
|
||||
}
|
||||
|
||||
return pUnicode;
|
||||
}
|
||||
static uint32_t GetUnicodeStrLen(const uint16_t* pUnicode)
|
||||
{
|
||||
uint32_t i = 0;
|
||||
while (0 != pUnicode[i])
|
||||
{
|
||||
++i;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
#endif
|
||||
|
||||
HGPdfImageWriterImpl::HGPdfImageWriterImpl()
|
||||
{
|
||||
m_dll = NULL;
|
||||
m_pPdf = NULL;
|
||||
}
|
||||
|
||||
HGPdfImageWriterImpl::~HGPdfImageWriterImpl()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HGResult HGPdfImageWriterImpl::Open(const HGChar* fileName)
|
||||
{
|
||||
if (NULL != m_pPdf)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
if (NULL == fileName)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
assert(NULL == m_dll);
|
||||
|
||||
HGChar moduleName[256];
|
||||
HGBase_GetModuleName((void*)HGImgFmt_OpenPdfImageWriter, moduleName, 256);
|
||||
HGChar dllPath[256];
|
||||
HGBase_GetFilePath(moduleName, dllPath, 256);
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
strcat(dllPath, "pdflib.dll");
|
||||
#else
|
||||
strcat(dllPath, "libpdf.so");
|
||||
#endif
|
||||
HGResult ret = HGBase_CreateDll(dllPath, &m_dll);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
PDF* p = PDF_new();
|
||||
if (NULL == p)
|
||||
{
|
||||
HGBase_DestroyDll(m_dll);
|
||||
m_dll = NULL;
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
WCHAR* pUnicode = GetUnicodeStr(fileName);
|
||||
#else
|
||||
uint16_t* pUnicode = GetUnicodeStr(fileName);
|
||||
#endif
|
||||
|
||||
PDF_TRY(p)
|
||||
{
|
||||
PDF_set_parameter(p, "compatibility", "1.4");
|
||||
PDF_set_parameter(p, "errorpolicy", "return");
|
||||
PDF_set_parameter(p, "hypertextencoding", "host");
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (-1 == PDF_begin_document(p, (const char*)pUnicode, (int)(GetUnicodeStrLen(pUnicode) * sizeof(WCHAR)), ""))
|
||||
#else
|
||||
if (-1 == PDF_begin_document(p, (const char*)pUnicode, (int)(GetUnicodeStrLen(pUnicode) * sizeof(uint16_t)), ""))
|
||||
#endif
|
||||
{
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "HGPdfImageWriterImpl::Open: PDF_begin_document fail, %s", fileName);
|
||||
|
||||
delete[] pUnicode;
|
||||
PDF_delete(p);
|
||||
HGBase_DestroyDll(m_dll);
|
||||
m_dll = NULL;
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
}
|
||||
}
|
||||
PDF_CATCH(p)
|
||||
{
|
||||
delete[] pUnicode;
|
||||
PDF_delete(p);
|
||||
HGBase_DestroyDll(m_dll);
|
||||
m_dll = NULL;
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
delete[] pUnicode;
|
||||
m_pPdf = p;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGPdfImageWriterImpl::Close()
|
||||
{
|
||||
if (NULL == m_pPdf)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
PDF_TRY(m_pPdf)
|
||||
{
|
||||
PDF_end_document(m_pPdf, "");
|
||||
}
|
||||
PDF_CATCH(m_pPdf)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PDF_delete(m_pPdf);
|
||||
m_pPdf = NULL;
|
||||
HGBase_DestroyDll(m_dll);
|
||||
m_dll = NULL;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGPdfImageWriterImpl::SaveJpegImage(HGImage image, const HGJpegSaveInfo* info)
|
||||
{
|
||||
if (NULL == m_pPdf)
|
||||
{
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
if (NULL == image)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGBuffer buffer = NULL;
|
||||
HGResult ret = HGImgFmt_SaveJpegImageToBuffer(image, info, &buffer);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGByte* imgBuf = NULL;
|
||||
HGBase_GetBufferData(buffer, &imgBuf);
|
||||
HGUSize size = 0;
|
||||
HGBase_GetBufferSize(buffer, &size);
|
||||
|
||||
PDF_TRY(m_pPdf)
|
||||
{
|
||||
PDF_create_pvf(m_pPdf, "virtual_file", 0, imgBuf, size, "");
|
||||
}
|
||||
PDF_CATCH(m_pPdf)
|
||||
{
|
||||
HGBase_DestroyBuffer(buffer);
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
int img = PDF_load_image(m_pPdf, "auto", "virtual_file", 0, "page 1");
|
||||
if (-1 != img)
|
||||
{
|
||||
PDF_begin_page_ext(m_pPdf, 0.0, 0.0, "");
|
||||
PDF_fit_image(m_pPdf, img, 0.0, 0.0, "adjustpage");
|
||||
PDF_end_page_ext(m_pPdf, "");
|
||||
PDF_close_image(m_pPdf, img);
|
||||
}
|
||||
|
||||
PDF_delete_pvf(m_pPdf, "virtual_file", 0);
|
||||
|
||||
HGBase_DestroyBuffer(buffer);
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
PDF* HGPdfImageWriterImpl::PDF_new(void)
|
||||
{
|
||||
typedef PDF* (PDFLIB_CALL *Func)();
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "PDF_new", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return func();
|
||||
}
|
||||
|
||||
void HGPdfImageWriterImpl::PDF_set_parameter(PDF* p, const char* key, const char* value)
|
||||
{
|
||||
typedef void (PDFLIB_CALL* Func)(PDF*, const char*, const char*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "PDF_set_parameter", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
func(p, key, value);
|
||||
}
|
||||
|
||||
int HGPdfImageWriterImpl::PDF_begin_document(PDF* p, const char* filename, int len, const char* optlist)
|
||||
{
|
||||
typedef int (PDFLIB_CALL* Func)(PDF*, const char*, int, const char*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "PDF_begin_document", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return func(p, filename, len, optlist);
|
||||
}
|
||||
|
||||
void HGPdfImageWriterImpl::PDF_delete(PDF* p)
|
||||
{
|
||||
typedef void (PDFLIB_CALL* Func)(PDF*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "PDF_delete", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
func(p);
|
||||
}
|
||||
|
||||
void HGPdfImageWriterImpl::PDF_end_document(PDF* p, const char* optlist)
|
||||
{
|
||||
typedef void (PDFLIB_CALL* Func)(PDF*, const char*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "PDF_end_document", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
func(p, optlist);
|
||||
}
|
||||
|
||||
void HGPdfImageWriterImpl::PDF_create_pvf(PDF* p, const char* filename, int len, const void* data, size_t size, const char* optlist)
|
||||
{
|
||||
typedef void (PDFLIB_CALL* Func)(PDF*, const char*, int, const void*, size_t, const char*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "PDF_create_pvf", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
func(p, filename, len, data, size, optlist);
|
||||
}
|
||||
|
||||
int HGPdfImageWriterImpl::PDF_load_image(PDF* p, const char* imagetype, const char* filename, int len, const char* optlist)
|
||||
{
|
||||
typedef int (PDFLIB_CALL* Func)(PDF*, const char*, const char*, int, const char*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "PDF_load_image", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return func(p, imagetype, filename, len, optlist);
|
||||
}
|
||||
|
||||
void HGPdfImageWriterImpl::PDF_begin_page_ext(PDF* p, double width, double height, const char* optlist)
|
||||
{
|
||||
typedef void (PDFLIB_CALL* Func)(PDF*, double, double, const char*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "PDF_begin_page_ext", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
func(p, width, height, optlist);
|
||||
}
|
||||
|
||||
void HGPdfImageWriterImpl::PDF_fit_image(PDF* p, int image, double x, double y, const char* optlist)
|
||||
{
|
||||
typedef void (PDFLIB_CALL* Func)(PDF*, int, double, double, const char*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "PDF_fit_image", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
func(p, image, x, y, optlist);
|
||||
}
|
||||
|
||||
void HGPdfImageWriterImpl::PDF_end_page_ext(PDF* p, const char* optlist)
|
||||
{
|
||||
typedef void (PDFLIB_CALL* Func)(PDF*, const char*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "PDF_end_page_ext", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
func(p, optlist);
|
||||
}
|
||||
|
||||
void HGPdfImageWriterImpl::PDF_close_image(PDF* p, int image)
|
||||
{
|
||||
typedef void (PDFLIB_CALL* Func)(PDF*, int);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "PDF_close_image", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
func(p, image);
|
||||
}
|
||||
|
||||
int HGPdfImageWriterImpl::PDF_delete_pvf(PDF* p, const char* filename, int len)
|
||||
{
|
||||
typedef int (PDFLIB_CALL* Func)(PDF*, const char*, int);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "PDF_delete_pvf", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return func(p, filename, len);
|
||||
}
|
||||
|
||||
pdf_jmpbuf* HGPdfImageWriterImpl::pdf_jbuf(PDF* p)
|
||||
{
|
||||
typedef pdf_jmpbuf* (PDFLIB_CALL* Func)(PDF*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "pdf_jbuf", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return func(p);
|
||||
}
|
||||
|
||||
int HGPdfImageWriterImpl::pdf_catch(PDF* p)
|
||||
{
|
||||
typedef int (PDFLIB_CALL* Func)(PDF*);
|
||||
Func func = NULL;
|
||||
HGBase_GetDllProcAddress(m_dll, "pdf_catch", (HGPointer*)&func);
|
||||
if (NULL == func)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return func(p);
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
#ifndef __HGPDFIMPL_HPP__
|
||||
#define __HGPDFIMPL_HPP__
|
||||
|
||||
#include "HGPdf.h"
|
||||
#include "../base/HGDll.h"
|
||||
#include "mupdf/pdf.h"
|
||||
#include "mupdf/fitz.h"
|
||||
#include "pdflib.h"
|
||||
|
||||
class HGPdfReaderImpl
|
||||
{
|
||||
public:
|
||||
HGPdfReaderImpl();
|
||||
~HGPdfReaderImpl();
|
||||
|
||||
HGResult Open(const HGChar* fileName);
|
||||
HGResult Close();
|
||||
HGResult GetPageCount(HGUInt* count);
|
||||
HGResult GetPageInfo(HGUInt page, HGPdfPageInfo* info);
|
||||
HGResult LoadImage(HGUInt page, HGFloat xScale, HGFloat yScale,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image);
|
||||
|
||||
private:
|
||||
fz_context* fz_new_context_imp(const fz_alloc_context* alloc, const fz_locks_context* locks, size_t max_store, const char* version);
|
||||
void fz_register_document_handlers(fz_context* ctx);
|
||||
fz_document* fz_open_document(fz_context* ctx, const char* filename);
|
||||
void fz_drop_context(fz_context* ctx);
|
||||
void fz_drop_document(fz_context* ctx, fz_document* doc);
|
||||
int fz_count_pages(fz_context* ctx, fz_document* doc);
|
||||
fz_page* fz_load_page(fz_context* ctx, fz_document* doc, int number);
|
||||
pdf_page* pdf_page_from_fz_page(fz_context* ctx, fz_page* ptr);
|
||||
fz_rect pdf_bound_page(fz_context* ctx, pdf_page* page);
|
||||
void fz_drop_page(fz_context* ctx, fz_page* page);
|
||||
fz_matrix fz_scale(float sx, float sy);
|
||||
fz_pixmap* fz_new_pixmap_from_page_number(fz_context* ctx, fz_document* doc, int number, fz_matrix ctm, fz_colorspace* cs, int alpha);
|
||||
fz_colorspace* fz_device_rgb(fz_context* ctx);
|
||||
int fz_pixmap_width(fz_context* ctx, const fz_pixmap* pix);
|
||||
int fz_pixmap_height(fz_context* ctx, const fz_pixmap* pix);
|
||||
void fz_drop_pixmap(fz_context* ctx, fz_pixmap* pix);
|
||||
fz_jmp_buf* fz_push_try(fz_context* ctx);
|
||||
int fz_do_try(fz_context* ctx);
|
||||
int fz_do_catch(fz_context* ctx);
|
||||
|
||||
private:
|
||||
HGDll m_dll;
|
||||
fz_context* m_pContext;
|
||||
fz_document* m_pDoc;
|
||||
};
|
||||
|
||||
class HGPdfImageWriterImpl
|
||||
{
|
||||
public:
|
||||
HGPdfImageWriterImpl();
|
||||
~HGPdfImageWriterImpl();
|
||||
|
||||
HGResult Open(const HGChar* fileName);
|
||||
HGResult Close();
|
||||
HGResult SaveJpegImage(HGImage image, const HGJpegSaveInfo* info);
|
||||
|
||||
private:
|
||||
PDF* PDF_new(void);
|
||||
void PDF_set_parameter(PDF* p, const char* key, const char* value);
|
||||
int PDF_begin_document(PDF* p, const char* filename, int len, const char* optlist);
|
||||
void PDF_delete(PDF* p);
|
||||
void PDF_end_document(PDF* p, const char* optlist);
|
||||
void PDF_create_pvf(PDF* p, const char* filename, int len, const void* data, size_t size, const char* optlist);
|
||||
int PDF_load_image(PDF* p, const char* imagetype, const char* filename, int len, const char* optlist);
|
||||
void PDF_begin_page_ext(PDF* p, double width, double height, const char* optlist);
|
||||
void PDF_fit_image(PDF* p, int image, double x, double y, const char* optlist);
|
||||
void PDF_end_page_ext(PDF* p, const char* optlist);
|
||||
void PDF_close_image(PDF* p, int image);
|
||||
int PDF_delete_pvf(PDF* p, const char* filename, int len);
|
||||
pdf_jmpbuf* pdf_jbuf(PDF* p);
|
||||
int pdf_catch(PDF* p);
|
||||
|
||||
private:
|
||||
HGDll m_dll;
|
||||
PDF* m_pPdf;
|
||||
};
|
||||
|
||||
#endif /* __HGPDFIMPL_HPP__ */
|
|
@ -0,0 +1,462 @@
|
|||
#include "HGPng.h"
|
||||
#include "../base/HGInc.h"
|
||||
#include "../base/HGInfo.h"
|
||||
#include "png.h"
|
||||
#include "pngstruct.h"
|
||||
#include "pnginfo.h"
|
||||
#include "pngpriv.h"
|
||||
|
||||
HGResult HGAPI HGImgFmt_CheckPngFile(const HGChar* fileName, HGBool* isPng)
|
||||
{
|
||||
if (NULL == fileName || NULL == isPng)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
HGPngLoadInfo info;
|
||||
HGResult ret = HGImgFmt_LoadPngImage(fileName, &info, 0, 0, NULL);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
*isPng = HGTRUE;
|
||||
return ret;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_LoadPngImage(const HGChar* fileName, HGPngLoadInfo* info,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image)
|
||||
{
|
||||
if (NULL == fileName)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (NULL == image)
|
||||
{
|
||||
if (0 != imgType || 0 != imgOrigin)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 != imgType && HGBASE_IMGTYPE_BINARY != imgType && HGBASE_IMGTYPE_GRAY != imgType
|
||||
&& HGBASE_IMGTYPE_BGR != imgType && HGBASE_IMGTYPE_RGB != imgType
|
||||
&& HGBASE_IMGTYPE_BGRA != imgType && HGBASE_IMGTYPE_RGBA != imgType)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (0 != imgOrigin && HGBASE_IMGORIGIN_TOP != imgOrigin && HGBASE_IMGORIGIN_BOTTOM != imgOrigin)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
if (0 != _access(fileName, 0))
|
||||
#else
|
||||
if (0 != access(fileName, 0))
|
||||
#endif
|
||||
{
|
||||
return HGBASE_ERR_FILENOTEXIST;
|
||||
}
|
||||
|
||||
FILE* file = fopen(fileName, "rb");
|
||||
if (NULL == file)
|
||||
{
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
}
|
||||
|
||||
png_byte buf[8] = { 0 };
|
||||
if (fread(buf, 1, 8, file) != 8)
|
||||
{
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGBASE_ERR_FAIL;
|
||||
}
|
||||
|
||||
if (0 != png_sig_cmp(buf, 0, 8))
|
||||
{
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGBASE_ERR_FILEERROR;
|
||||
}
|
||||
|
||||
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (NULL == png_ptr)
|
||||
{
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (NULL == info_ptr)
|
||||
{
|
||||
png_destroy_read_struct(&png_ptr, NULL, NULL);
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
uint8_t* buffer = NULL;
|
||||
uint8_t** rowPointers = NULL;
|
||||
HGImage image2 = NULL;
|
||||
|
||||
int jmpResult = setjmp(png_jmpbuf(png_ptr));
|
||||
if (0 != jmpResult)
|
||||
{
|
||||
HGBase_DestroyImage(image2);
|
||||
image2 = NULL;
|
||||
free(rowPointers);
|
||||
rowPointers = NULL;
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return (HGResult)jmpResult;
|
||||
}
|
||||
|
||||
#if defined(HG_CMP_MSC)
|
||||
_fseeki64(file, 0, SEEK_SET);
|
||||
#else
|
||||
fseeko64(file, 0, SEEK_SET);
|
||||
#endif
|
||||
png_init_io(png_ptr, file);
|
||||
png_read_info(png_ptr, info_ptr);
|
||||
|
||||
if (NULL != info)
|
||||
{
|
||||
info->width = info_ptr->width;
|
||||
info->height = info_ptr->height;
|
||||
info->bitDepth = info_ptr->bit_depth;
|
||||
info->colorType = info_ptr->color_type;
|
||||
info->channels = info_ptr->channels;
|
||||
info->filterType = info_ptr->filter_type;
|
||||
info->InterlaceType = info_ptr->interlace_type;
|
||||
info->compressionType = info_ptr->compression_type;
|
||||
info->pixelDepth = info_ptr->pixel_depth;
|
||||
info->physUnitType = info_ptr->phys_unit_type;
|
||||
info->xPixelsPerUnit = info_ptr->x_pixels_per_unit;
|
||||
info->yPixelsPerUnit = info_ptr->y_pixels_per_unit;
|
||||
}
|
||||
|
||||
if (NULL != image)
|
||||
{
|
||||
png_set_scale_16(png_ptr);
|
||||
png_set_expand(png_ptr);
|
||||
|
||||
png_set_interlace_handling(png_ptr);
|
||||
png_read_update_info(png_ptr, info_ptr);
|
||||
|
||||
buffer = (uint8_t*)malloc((uintptr_t)info_ptr->rowbytes * (uintptr_t)info_ptr->height);
|
||||
if (NULL == buffer)
|
||||
{
|
||||
longjmp(png_jmpbuf(png_ptr), (int)HGBASE_ERR_OUTOFMEMORY);
|
||||
}
|
||||
|
||||
rowPointers = (uint8_t**)malloc(info_ptr->height * sizeof(png_bytep));
|
||||
if (NULL == rowPointers)
|
||||
{
|
||||
longjmp(png_jmpbuf(png_ptr), (int)HGBASE_ERR_OUTOFMEMORY);
|
||||
}
|
||||
|
||||
//#pragma omp parallel for
|
||||
for (png_int_32 i = 0; i < (png_int_32)info_ptr->height; ++i)
|
||||
{
|
||||
rowPointers[i] = buffer + (uintptr_t)i * (uintptr_t)info_ptr->rowbytes;
|
||||
}
|
||||
|
||||
png_read_image(png_ptr, rowPointers);
|
||||
png_read_end(png_ptr, info_ptr);
|
||||
|
||||
if (0 == imgType)
|
||||
{
|
||||
imgType = HGBASE_IMGTYPE_RGB;
|
||||
if (PNG_COLOR_TYPE_GRAY_ALPHA == info_ptr->color_type || PNG_COLOR_TYPE_RGB_ALPHA == info_ptr->color_type)
|
||||
{
|
||||
imgType = HGBASE_IMGTYPE_RGBA;
|
||||
}
|
||||
else if (PNG_COLOR_TYPE_GRAY == info_ptr->color_type)
|
||||
{
|
||||
imgType = HGBASE_IMGTYPE_GRAY;
|
||||
}
|
||||
}
|
||||
|
||||
if (imgOrigin == 0)
|
||||
{
|
||||
imgOrigin = HGBASE_IMGORIGIN_TOP;
|
||||
}
|
||||
|
||||
HGResult ret = HGBase_CreateImage(info_ptr->width, info_ptr->height, HGBASE_IMGTYPE_RGBA, HGBASE_IMGORIGIN_TOP, &image2);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
longjmp(png_jmpbuf(png_ptr), (int)ret);
|
||||
}
|
||||
|
||||
if (PNG_RESOLUTION_METER == info_ptr->phys_unit_type)
|
||||
{
|
||||
uint32_t xDpi = (uint32_t)((double)info_ptr->x_pixels_per_unit / 39.3700787 + 0.5);
|
||||
uint32_t yDpi = (uint32_t)((double)info_ptr->y_pixels_per_unit / 39.3700787 + 0.5);
|
||||
HGBase_SetImageDpi(image2, xDpi, yDpi);
|
||||
}
|
||||
|
||||
uint8_t* data;
|
||||
HGBase_GetImageData(image2, &data);
|
||||
HGImageInfo imgInfo;
|
||||
HGBase_GetImageInfo(image2, &imgInfo);
|
||||
|
||||
if (PNG_COLOR_TYPE_GRAY == info_ptr->color_type)
|
||||
{
|
||||
//#pragma omp parallel for
|
||||
for (png_int_32 i = 0; i < (png_int_32)info_ptr->height; i++)
|
||||
{
|
||||
uint8_t* pEx = rowPointers[i];
|
||||
uint8_t* pExEnd = pEx + info_ptr->width;
|
||||
uint8_t* pDestEx = data + (HGSize)i * (HGSize)imgInfo.widthStep;
|
||||
|
||||
while (pEx < pExEnd)
|
||||
{
|
||||
uint8_t v = *pEx;
|
||||
*((uint32_t*)pDestEx) = (v & 0x000000FF) | ((v << 8) & 0x0000FF00) | ((v << 16) & 0x00FF0000) | 0xFF000000;
|
||||
|
||||
++pEx;
|
||||
pDestEx += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (PNG_COLOR_TYPE_RGB == info_ptr->color_type)
|
||||
{
|
||||
//#pragma omp parallel for
|
||||
for (png_int_32 i = 0; i < (png_int_32)info_ptr->height; i++)
|
||||
{
|
||||
uint8_t* pEx = rowPointers[i];
|
||||
uint8_t* pExEnd = pEx + info_ptr->width * 3;
|
||||
uint8_t* pDestEx = data + (HGSize)i * (HGSize)imgInfo.widthStep;
|
||||
|
||||
while (pEx < pExEnd)
|
||||
{
|
||||
uint8_t r = pEx[0];
|
||||
uint8_t g = pEx[1];
|
||||
uint8_t b = pEx[2];
|
||||
*((uint32_t*)pDestEx) = (r & 0x000000FF) | ((g << 8) & 0x0000FF00) | ((b << 16) & 0x00FF0000) | 0xFF000000;
|
||||
|
||||
pEx += 3;
|
||||
pDestEx += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (PNG_COLOR_TYPE_GRAY_ALPHA == info_ptr->color_type)
|
||||
{
|
||||
//#pragma omp parallel for
|
||||
for (png_int_32 i = 0; i < (png_int_32)info_ptr->height; i++)
|
||||
{
|
||||
uint8_t* pEx = rowPointers[i];
|
||||
uint8_t* pExEnd = pEx + info_ptr->width * 2;
|
||||
uint8_t* pDestEx = data + (HGSize)i * (HGSize)imgInfo.widthStep;
|
||||
|
||||
while (pEx < pExEnd)
|
||||
{
|
||||
uint8_t v = pEx[0];
|
||||
uint8_t alpha = pEx[1];
|
||||
*((uint32_t*)pDestEx) = (v & 0x000000FF) | ((v << 8) & 0x0000FF00) | ((v << 16) & 0x00FF0000) | ((alpha << 24) & 0xFF000000);
|
||||
|
||||
pEx += 2;
|
||||
pDestEx += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(PNG_COLOR_TYPE_RGB_ALPHA == info_ptr->color_type);
|
||||
|
||||
//#pragma omp parallel for
|
||||
for (png_int_32 i = 0; i < (png_int_32)info_ptr->height; i++)
|
||||
{
|
||||
uint8_t* pEx = rowPointers[i];
|
||||
uint8_t* pDestEx = data + (HGSize)i * (HGSize)imgInfo.widthStep;
|
||||
memcpy(pDestEx, pEx, info_ptr->width * 4);
|
||||
}
|
||||
}
|
||||
|
||||
ret = HGBase_CloneImage(image2, imgType, imgOrigin, image);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
longjmp(png_jmpbuf(png_ptr), (int)ret);
|
||||
}
|
||||
}
|
||||
|
||||
HGBase_DestroyImage(image2);
|
||||
image2 = NULL;
|
||||
free(rowPointers);
|
||||
rowPointers = NULL;
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
||||
|
||||
HGResult HGAPI HGImgFmt_SavePngImage(HGImage image, const HGPngSaveInfo* info, const HGChar* fileName)
|
||||
{
|
||||
if (NULL == image || NULL == fileName)
|
||||
{
|
||||
return HGBASE_ERR_INVALIDARG;
|
||||
}
|
||||
|
||||
if (NULL != info)
|
||||
{
|
||||
// 判断合法性
|
||||
}
|
||||
|
||||
FILE* file = fopen(fileName, "wb");
|
||||
if (NULL == file)
|
||||
{
|
||||
HGBase_WriteInfo(HGBASE_INFOTYPE_ERROR, "HGImgFmt_SavePngImage: fopen fail, %s errno=%d", fileName, errno);
|
||||
return HGBASE_ERR_ACCESSDENIED;
|
||||
}
|
||||
|
||||
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (NULL == png_ptr)
|
||||
{
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
png_infop info_ptr = png_create_info_struct(png_ptr);
|
||||
if (NULL == info_ptr)
|
||||
{
|
||||
png_destroy_write_struct(&png_ptr, NULL);
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGIMGFMT_ERR_FAIL;
|
||||
}
|
||||
|
||||
uint8_t** rowPointers = NULL;
|
||||
|
||||
HGImage image2 = NULL;
|
||||
HGImageRoi roi;
|
||||
HGBase_GetImageROI(image, &roi);
|
||||
|
||||
int jmpResult = setjmp(png_jmpbuf(png_ptr));
|
||||
if (0 != jmpResult)
|
||||
{
|
||||
HGBase_SetImageROI(image, &roi);
|
||||
HGBase_DestroyImage(image2);
|
||||
image2 = NULL;
|
||||
free(rowPointers);
|
||||
rowPointers = NULL;
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return (HGResult)jmpResult;
|
||||
}
|
||||
|
||||
png_init_io(png_ptr, file);
|
||||
|
||||
HGBase_ResetImageROI(image);
|
||||
HGImageInfo imgInfo;
|
||||
HGBase_GetImageInfo(image, &imgInfo);
|
||||
if (HGBASE_IMGTYPE_BGR == imgInfo.type)
|
||||
{
|
||||
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_RGB, HGBASE_IMGORIGIN_TOP, &image2);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
longjmp(png_jmpbuf(png_ptr), (int)ret);
|
||||
}
|
||||
}
|
||||
else if (HGBASE_IMGTYPE_BGRA == imgInfo.type)
|
||||
{
|
||||
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_RGBA, HGBASE_IMGORIGIN_TOP, &image2);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
longjmp(png_jmpbuf(png_ptr), (int)ret);
|
||||
}
|
||||
}
|
||||
else if (HGBASE_IMGTYPE_BINARY == imgInfo.type)
|
||||
{
|
||||
HGResult ret = HGBase_CloneImage(image, HGBASE_IMGTYPE_GRAY, HGBASE_IMGORIGIN_TOP, &image2);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
longjmp(png_jmpbuf(png_ptr), (int)ret);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HGResult ret = HGBase_CloneImage(image, imgInfo.type, HGBASE_IMGORIGIN_TOP, &image2);
|
||||
if (HGBASE_ERR_OK != ret)
|
||||
{
|
||||
longjmp(png_jmpbuf(png_ptr), (int)ret);
|
||||
}
|
||||
}
|
||||
|
||||
HGBase_GetImageInfo(image2, &imgInfo);
|
||||
uint32_t width = imgInfo.width;
|
||||
uint32_t height = imgInfo.height;
|
||||
uint32_t widthStep = imgInfo.widthStep;
|
||||
uint32_t type = imgInfo.type;
|
||||
uint32_t origin = imgInfo.origin;
|
||||
|
||||
uint8_t* data;
|
||||
HGBase_GetImageData(image2, &data);
|
||||
|
||||
int color_type = -1;
|
||||
if (HGBASE_IMGTYPE_GRAY == type)
|
||||
color_type = PNG_COLOR_TYPE_GRAY;
|
||||
else if (HGBASE_IMGTYPE_RGB == type)
|
||||
color_type = PNG_COLOR_TYPE_RGB;
|
||||
else if (HGBASE_IMGTYPE_RGBA == type)
|
||||
color_type = PNG_COLOR_TYPE_RGB_ALPHA;
|
||||
assert(-1 != color_type);
|
||||
|
||||
png_set_IHDR(png_ptr, info_ptr, width, height, 8, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
|
||||
|
||||
if (NULL != info)
|
||||
{
|
||||
info_ptr->phys_unit_type = info->physUnitType;
|
||||
info_ptr->x_pixels_per_unit = info->xPixelsPerUnit;
|
||||
info_ptr->y_pixels_per_unit = info->yPixelsPerUnit;
|
||||
info_ptr->valid |= PNG_INFO_pHYs;
|
||||
}
|
||||
else
|
||||
{
|
||||
HGUInt xDpi, yDpi;
|
||||
HGBase_GetImageDpi(image2, &xDpi, &yDpi);
|
||||
info_ptr->phys_unit_type = PNG_RESOLUTION_METER;
|
||||
info_ptr->x_pixels_per_unit = (uint32_t)((double)xDpi * 39.3700787 + 0.5);
|
||||
info_ptr->y_pixels_per_unit = (uint32_t)((double)yDpi * 39.3700787 + 0.5);
|
||||
info_ptr->valid |= PNG_INFO_pHYs;
|
||||
}
|
||||
|
||||
png_write_info(png_ptr, info_ptr);
|
||||
|
||||
rowPointers = (uint8_t**)malloc(height * sizeof(png_bytep));
|
||||
if (NULL == rowPointers)
|
||||
{
|
||||
longjmp(png_jmpbuf(png_ptr), (int)HGBASE_ERR_OUTOFMEMORY);
|
||||
}
|
||||
|
||||
//#pragma omp parallel for
|
||||
for (int32_t i = 0; i < (int32_t)height; ++i)
|
||||
{
|
||||
rowPointers[i] = data + (HGSize)i * (HGSize)widthStep;
|
||||
}
|
||||
|
||||
png_write_image(png_ptr, rowPointers);
|
||||
png_write_end(png_ptr, info_ptr);
|
||||
|
||||
HGBase_SetImageROI(image, &roi);
|
||||
HGBase_DestroyImage(image2);
|
||||
image2 = NULL;
|
||||
free(rowPointers);
|
||||
rowPointers = NULL;
|
||||
png_destroy_write_struct(&png_ptr, &info_ptr);
|
||||
fclose(file);
|
||||
file = NULL;
|
||||
return HGBASE_ERR_OK;
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
#ifndef __HGPNG_H__
|
||||
#define __HGPNG_H__
|
||||
|
||||
#include "../base/HGDef.h"
|
||||
#include "../base/HGBaseErr.h"
|
||||
#include "HGImgFmtErr.h"
|
||||
#include "../base/HGImage.h"
|
||||
|
||||
/* */
|
||||
#define HGIMGFMT_PNGCLRTYPE_GRAY 0L
|
||||
#define HGIMGFMT_PNGCLRTYPE_PALETTE (1L | 2L)
|
||||
#define HGIMGFMT_PNGCLRTYPE_RGB 2L
|
||||
#define HGIMGFMT_PNGCLRTYPE_RGB_ALPHA (2L | 4L)
|
||||
#define HGIMGFMT_PNGCLRTYPE_GRAY_ALPHA 4L
|
||||
|
||||
/* */
|
||||
#define HGIMGFMT_PNGFILTERTYPE_BASE 0L
|
||||
/* */
|
||||
#define HGIMGFMT_PNGINTERLACE_NONE 0L
|
||||
#define HGIMGFMT_PNGINTERLACE_ADAM7 1L
|
||||
#define HGIMGFMT_PNGINTERLACE_LAST 2L
|
||||
/* */
|
||||
#define HGIMGFMT_PNGCOMPTYPE_BASE 0L
|
||||
|
||||
/* 分辨率单位 */
|
||||
#define HGIMGFMT_PNGPHYSUNIT_UNKNOWN 0L
|
||||
#define HGIMGFMT_PNGPHYSUNIT_METER 1L
|
||||
#define HGIMGFMT_PNGPHYSUNIT_LAST 2L
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGUInt width; /* 图像宽 */
|
||||
HGUInt height; /* 图像高 */
|
||||
HGByte bitDepth; /* 每通道的比特数 */
|
||||
HGByte colorType; /* 色彩类型, 见HGIMGFMT_PNGCLRTYPE_* */
|
||||
HGByte channels; /* 通道数 */
|
||||
HGByte filterType; /* 见HGIMGFMT_PNGFILTERTYPE_* */
|
||||
HGByte InterlaceType; /* 见HGIMGFMT_PNGINTERLACE_* */
|
||||
HGByte compressionType; /* 见HGIMGFMT_PNGCOMPTYPE_* */
|
||||
HGByte pixelDepth; /* 每像素的比特数 */
|
||||
HGByte physUnitType; /* 分辨率单位, 见HGIMGFMT_PNGPHYSUNIT_* */
|
||||
HGUInt xPixelsPerUnit; /* 分辨率x */
|
||||
HGUInt yPixelsPerUnit; /* 分辨率y */
|
||||
}HGPngLoadInfo;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGByte physUnitType; /* 分辨率单位, 见HGIMGFMT_PNGPHYSUNIT_* */
|
||||
HGUInt xPixelsPerUnit; /* 分辨率x */
|
||||
HGUInt yPixelsPerUnit; /* 分辨率y */
|
||||
}HGPngSaveInfo;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_CheckPngFile(const HGChar* fileName, HGBool* isPng);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_LoadPngImage(const HGChar* fileName, HGPngLoadInfo* info,
|
||||
HGUInt imgType, HGUInt imgOrigin, HGImage* image);
|
||||
|
||||
HGEXPORT HGResult HGAPI HGImgFmt_SavePngImage(HGImage image, const HGPngSaveInfo* info, const HGChar* fileName);
|
||||
|
||||
#endif /* __HGPNG_H__ */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue