uemf_endian.c revision 3454db7714cfb1d4b86a7aeae6f33ca5672ea4b0
/**
@file uemf_endian.c
@brief Functions for converting EMF records between Big Endian and Little Endian byte orders.
EMF files use Little Endian order.
On a Big Endian machine the data must be converted to/from Little Endian when it is writen to/read from a file.
On a Little Endian machine no conversion is required, but it is good to be able to test the routines on either platform.
When "torev" is true these routines convert from the native byte order to the reverse.
When "torev" is false these routines convert from the reverse byte order to the native.
Routines that do not use that variable swap byte order, and the way in which they do so does not depend
on the native byte order.
The only function here which should be called directly is U_emf_endian(), and then,except for testing purposes, only on a BE machine.
Many variables are initialized to zero even though they will always be set because
some versions of gcc give spurious "may be used uninitialized" warnings otherwise.
*/
/*
File: uemf_endian.c
Version: 0.0.16
Date: 27-MAR-2014
Author: David Mathog, Biology Division, Caltech
email: mathog@caltech.edu
Copyright: 2014 David Mathog and California Institute of Technology (Caltech)
*/
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "uemf.h"
#include "uemf_endian.h"
// hide almost everuything in here from Doxygen
//! \cond
/* **********************************************************************************************
These functions convert standard objects used in the EMR records.
*********************************************************************************************** */
}
}
/* Note: U_swap4 is also used by uwmf_endian.c, in cases where the 32 bit data is not aligned on a 4 byte boundary */
}
}
/**
U_COLORREF and U_RGBQUAD do NOT need to be swapped, they are always stored in memory in the proper order.
*/
/**
\brief Convert rect and rectl objects from Upper Left and Lower Right corner points.
\param rect U_RECTL object
\param count number to convert
*/
void rectl_swap(
unsigned int count
){
}
/**
\brief Convert a U_SIZEL object.
\param sz U_SizeL object
\param count number to convert
*/
void sizel_swap(
unsigned int count
){
}
/**
\brief Convert a U_POINTL object
\param pt U_POINTL object
\param count number to convert
*/
void pointl_swap(
unsigned int count
){
}
/**
\brief Convert a U_POINT16 object
\param pt U_POINT16 object
\param count number to convert
*/
void point16_swap(
unsigned int count
){
}
/**
\brief Convert a U_TRIVERTEX object.
\param tv U_TRIVERTEX object.
\param count number to convert
*/
void trivertex_swap(
unsigned int count
){
}
}
/**
\brief Convert a U_GRADIENT3 object.
\param tv U_GRADIENT3 object.
\param count number to convert
*/
void gradient3_swap(
unsigned int count
){
}
/**
\brief Convert a U_GRADIENT4 object.
\param tv U_GRADIENT4 object.
\param count number to convert
*/
void gradient4_swap(
unsigned int count
){
}
/**
\brief Convert a U_LOGBRUSH object.
\param lb U_LOGBRUSH object.
*/
void logbrush_swap(
){
// ordered bytes: lbColor
}
/**
\brief Convert a U_XFORM object.
\param xform U_XFORM object
*/
void xform_swap(
){
}
/**
\brief Convert a U_CIEXYZTRIPLE object
\param cie3 U_CIEXYZTRIPLE object
*/
void ciexyztriple_swap(
){
}
/**
\brief Convert a U_LOGCOLORSPACEA object.
\param lcsa U_LOGCOLORSPACEA object
*/
void logcolorspacea_swap(
){
// ordered bytes: lcsGammaRGB
// ordered bytes: lcsFilename
}
/**
\brief Convert a U_LOGCOLORSPACEW object.
\param lcsa U_LOGCOLORSPACEW object
*/
void logcolorspacew_swap(
){
// ordered bytes: lcsGammaRGB
// UTF-16LE, already in order: lcsFilename
}
/**
\brief Convert a U_LOGFONT object.
\param lf U_LOGFONT object
*/
void logfont_swap(
){
// ordered bytes: lfItalic lfUnderline lfStrikeOut lfCharSet lfOutPrecision lfClipPrecision lfQuality lfPitchAndFamily
// UTF16-LE, already in order
}
/**
\brief Convert a U_LOGFONT_PANOSE object.
\return U_LOGFONT_PANOSE object
*/
void logfont_panose_swap(
){
// UTF-16LE, already in order: elfFullName
// UTF-16LE, already in order: elfStyle
// ordered bytes: elfVendorId
// ordered bytes: elfPanose
}
/**
\brief Convert a U_BITMAPINFOHEADER object.
\param Bmi U_BITMAPINFOHEADER object
*/
void bitmapinfoheader_swap(
){
U_swap4(&(Bmi->biCompression),6); // biCompression biSizeImage biXPelsPerMeter biYPelsPerMeter biClrUsed biClrImportant
}
/**
\brief Convert a Pointer to a U_BITMAPINFO object.
\param Bmi Pointer to a U_BITMAPINFO object
*/
void bitmapinfo_swap(
){
// ordered bytes: bmiColors
}
/**
\brief Convert a pointer to a U_EXTLOGPEN object.
\param elp PU_EXTLOGPEN object
*/
void extlogpen_swap(
int torev
){
int count=0;
// ordered bytes: elpColor
if(torev){
}
if(!torev){
}
}
/**
\brief Convert a U_LOGPEN object.
\param lp U_LOGPEN object
*/
void logpen_swap(
){
// ordered bytes: lopnColor
}
/**
\brief Convert a pointer to a U_LOGPALETTE object.
\param lp Pointer to a U_LOGPALETTE object.
*/
void logpalette_swap(
){
// ordered bytes: palPalEntry[]
}
/**
\brief Convert a U_RGNDATAHEADER object.
\param rdh U_RGNDATAHEADER object
*/
void rgndataheader_swap(
){
}
/**
\brief Convert a pointer to a U_RGNDATA object.
\param rgd pointer to a U_RGNDATA object.
*/
void rgndata_swap(
){
}
/**
\brief Convert a U_COLORADJUSTMENT object.
\param ca U_COLORADJUSTMENT object.
*/
void coloradjustment_swap(
){
U_swap2(ca,12); // caSize caFlags caIlluminantIndex caRedGamma caGreenGamma caBlueGamma caReferenceBlack caReferenceWhite caContrast caBrightness caColorfulness caRedGreenTint
}
/**
\brief Convert a pointer to a U_PIXELFORMATDESCRIPTOR object.
\param pfd pointer to a U_PIXELFORMATDESCRIPTOR object.
*/
){
// ordered bytes: iPixelType cColorBits cRedBits cRedShift cGreenBits cGreenShift cBlueBits cBlueShift cAlphaBits cAlphaShift cAccumBits cAccumRedBits cAccumGreenBits cAccumBlueBits cAccumAlphaBits cDepthBits cStencilBits cAuxBuffers iLayerType bReserved
}
/**
\brief Convert a Pointer to a U_EMRTEXT record
\param pemt Pointer to a U_EMRTEXT record
\param record Pointer to the start of the record which contains this U_EMRTEXT
\param torev 1 for native to reversed, 0 for reversed to native
*/
void emrtext_swap(
char *record,
int torev
){
int off;
if(torev){
}
if(!torev){
}
if(!(fOptions & U_ETO_NO_RECT)){
}
if(torev){
}
// ordered bytes OR UTF16-LE: the string at offString
if(!torev){
}
}
/* **********************************************************************************************
These functions contain shared code used by various U_EMR*_swap functions. These should NEVER be called
by end user code and to further that end prototypes are NOT provided and they are hidden from Doxygen.
These all have this form:
void core1_swap(char *record, int torev){
but some do not actually use torev.
*********************************************************************************************** */
// all core*_swap call this, U_EMRSETMARGN_swap and some others all it directly
// numbered as core5 to be consistent with uemf.c, but must appear before the others as there is no prototype
}
// Functions with the same form starting with U_EMRPOLYBEZIER_swap
int count=0;
if(torev){
}
if(!torev){
}
}
// Functions with the same form starting with U_EMRPOLYPOLYLINE_swap
int count=0;
int nPolys=0;
if(torev){
}
if(!torev){
}
pointl_swap((PU_POINT)(record + sizeof(U_EMRPOLYPOLYLINE) - 4 + sizeof(uint32_t)* nPolys), count); // paptl[]
}
// Functions with the same form starting with U_EMRSETMAPMODE_swap
}
// Functions taking a single U_RECT or U_RECTL, starting with U_EMRELLIPSE_swap, also U_EMRFILLPATH_swap,
}
// Functions with the same form starting with U_EMRPOLYBEZIER16_swap
int count=0;
if(torev){
}
if(!torev){
}
}
// Records with the same form starting with U_EMRSETWINDOWEXTEX_swap, that is, all with two uint32_t values after the emr
}
// For U_EMREXTTEXTOUTA and U_EMREXTTEXTOUTW, type=0 for the first one
}
// Functions that take a rect and a pair of points, starting with U_EMRARC_swap
}
// Functions with the same form starting with U_EMRPOLYPOLYLINE16_swap
int count=0;
int nPolys=0;
if(torev){
}
if(!torev){
}
point16_swap((PU_POINT16)(record + sizeof(U_EMRPOLYPOLYLINE16) - 4 + sizeof(uint32_t)* nPolys), count); // apts[]
}
// Functions with the same form starting with U_EMRINVERTRGN_swap and U_EMRPAINTRGN_swap,
int roff=0;
int nextroff=0;
int limit=0;
roff = 0;
if(torev){
nextroff = 0;
}
if(!torev){
}
if(!torev){
}
// This one is a pain since each RGNDATA may be a different size, so it isn't possible to index through them.
if(torev){
}
else {
}
}
}
// common code for U_EMRCREATEMONOBRUSH_swap and U_EMRCREATEDIBPATTERNBRUSHPT_swap,
}
}
}
// common code for U_EMRALPHABLEND_swap and U_EMRTRANSPARENTBLT_swap,
}
// ordered bytes: Blend
// ordered bytes: crBkColorSrc
}
}
/* **********************************************************************************************
These are the core EMR functions, each creates a particular type of record.
All return these records via a char* pointer, which is NULL if the call failed.
They are listed in order by the corresponding U_EMR_* index number.
*********************************************************************************************** */
/**
All of the record level (hidden) functions have this form:
\brief Convert a pointer to a U_EMR_whatever record which has not been implemented.
\param record pointer to a buffer holding the EMR record
\param torev 1 for native to reversed, 0 for reversed to native
*/
printf("WARNING: could not convert data in record type that has not been implemented!\n");
}
// U_EMRHEADER 1
if(torev){
}
else {
}
if(torev){
}
else {
}
// UTF16-LE Description
){
if(torev){
}
else {
}
){
}
}
}
// U_EMRPOLYBEZIER 2
}
// U_EMRPOLYGON 3
}
// U_EMRPOLYLINE 4
}
// U_EMRPOLYBEZIERTO 5
}
// U_EMRPOLYLINETO 6
}
// U_EMRPOLYPOLYLINE 7
}
// U_EMRPOLYPOLYGON 8
}
// U_EMRSETWINDOWEXTEX 9
}
// U_EMRSETWINDOWORGEX 10
}
// U_EMRSETVIEWPORTEXTEX 11
}
// U_EMRSETVIEWPORTORGEX 12
}
// U_EMRSETBRUSHORGEX 13
}
// U_EMREOF 14
int off=0;
int cbPalEntries=0;
if(torev){
if(cbPalEntries){
}
}
if(!torev){
if(cbPalEntries){
}
}
}
// U_EMRSETPIXELV 15
// ordered bytes: crColor
}
// U_EMRSETMAPPERFLAGS 16
}
// U_EMRSETMAPMODE 17
}
// U_EMRSETBKMODE 18
}
// U_EMRSETPOLYFILLMODE 19
}
// U_EMRSETROP2 20
}
// U_EMRSETSTRETCHBLTMODE 21
}
// U_EMRSETTEXTALIGN 22
}
// U_EMRSETCOLORADJUSTMENT 23
}
// U_EMRSETTEXTCOLOR 24
// ordered bytes: crColor
}
// U_EMRSETBKCOLOR 25
// ordered bytes: crColor
}
// U_EMROFFSETCLIPRGN 26
}
// U_EMRMOVETOEX 27
}
// U_EMRSETMETARGN 28
}
// U_EMREXCLUDECLIPRECT 29
}
// U_EMRINTERSECTCLIPRECT 30
}
// U_EMRSCALEVIEWPORTEXTEX 31
}
// U_EMRSCALEWINDOWEXTEX 32
}
// U_EMRSAVEDC 33
}
// U_EMRRESTOREDC 34
}
// U_EMRSETWORLDTRANSFORM 35
}
// U_EMRMODIFYWORLDTRANSFORM 36
}
// U_EMRSELECTOBJECT 37
}
// U_EMRCREATEPEN 38
}
// U_EMRCREATEBRUSHINDIRECT 39
}
// U_EMRDELETEOBJECT 40
}
// U_EMRANGLEARC 41
}
// U_EMRELLIPSE 42
}
// U_EMRRECTANGLE 43
}
// U_EMRROUNDRECT 44
}
// U_EMRARC 45
}
// U_EMRCHORD 46
}
// U_EMRPIE 47
}
// U_EMRSELECTPALETTE 48
}
// U_EMRCREATEPALETTE 49
}
// U_EMRSETPALETTEENTRIES 50
// ordered bytes: aPalEntries[]
}
// U_EMRRESIZEPALETTE 51
}
// U_EMRREALIZEPALETTE 52
}
// U_EMREXTFLOODFILL 53
// ordered bytes: crColor
}
// U_EMRLINETO 54
}
// U_EMRARCTO 55
}
// U_EMRPOLYDRAW 56
int count=0;
if(torev){
}
if(!torev){
}
}
// U_EMRSETARCDIRECTION 57
}
// U_EMRSETMITERLIMIT 58
}
// U_EMRBEGINPATH 59
}
// U_EMRENDPATH 60
}
// U_EMRCLOSEFIGURE 61
}
// U_EMRFILLPATH 62
}
// U_EMRSTROKEANDFILLPATH 63
}
// U_EMRSTROKEPATH 64
}
// U_EMRFLATTENPATH 65
}
// U_EMRWIDENPATH 66
}
// U_EMRSELECTCLIPPATH 67
}
// U_EMRABORTPATH 68
}
// U_EMRUNDEF69 69
// U_EMRCOMMENT 70 Comment (any binary data, interpretation is program specific)
// program specific data, presumably byte ordered, otherwise, not portable
}
// U_EMRFILLRGN 71
int roff=0;
int nextroff=0;
int limit=0;
roff=0;
if(torev){
nextroff = 0;
}
if(!torev){
}
// This one is a pain since each RGNDATA may be a different size, so it isn't possible to index through them.
if(torev){
}
else {
}
}
}
// U_EMRFRAMERGN 72
int roff=0;
int nextroff=0;
int limit=0;
roff = 0;
if(torev){
nextroff = 0;
}
if(!torev){
}
// This one is a pain since each RGNDATA may be a different size, so it isn't possible to index through them.
if(torev){
}
else {
}
}
}
// U_EMRINVERTRGN 73
}
// U_EMRPAINTRGN 74
}
// U_EMREXTSELECTCLIPRGN 75
int roff=0;
int nextroff=0;
int limit=0;
if(torev){
}
if(!torev){
}
// This one is a pain since each RGNDATA may be a different size, so it isn't possible to index through them.
if(torev){
}
else {
}
}
}
// U_EMRBITBLT 76
}
// ordered bytes: crBkColorSrc
}
}
// U_EMRSTRETCHBLT 77
// ordered bytes: crBkColorSrc
}
}
}
// U_EMRMASKBLT 78
}
}
// ordered bytes: crBkColorSrc
}
}
}
// U_EMRPLGBLT 79
}
}
// ordered bytes: crBkColorSrc
}
}
}
// U_EMRSETDIBITSTODEVICE 80
}
U_swap4(&(pEmr->offBmiSrc),7); // offBmiSrc cbBmiSrc offBitsSrc cbBitsSrc iUsageSrc iStartScan cScans
}
}
// U_EMRSTRETCHDIBITS 81
}
}
}
// U_EMREXTCREATEFONTINDIRECTW_swap 82
if(torev){
}
else {
}
}
if(!torev){
}
else {
}
}
}
// U_EMREXTTEXTOUTA 83
}
// U_EMREXTTEXTOUTW 84
}
// U_EMRPOLYBEZIER16 85
/**
\brief Convert a pointer to a U_EMR_POLYBEZIER16 record.
\param record pointer to a buffer holding the EMR record
*/
}
// U_EMRPOLYGON16 86
}
// U_EMRPOLYLINE16 87
}
// U_EMRPOLYBEZIERTO16 88
}
// U_EMRPOLYLINETO16 89
/**
\brief Convert a pointer to a U_EMR_POLYLINETO16 record.
\param record pointer to a buffer holding the EMR record
*/
}
// U_EMRPOLYPOLYLINE16 90
}
// U_EMRPOLYPOLYGON16 91
}
// U_EMRPOLYDRAW16 92
int count=0;
if(torev){
}
if(!torev){
}
}
// U_EMRCREATEMONOBRUSH 93
}
// U_EMRCREATEDIBPATTERNBRUSHPT_swap 94
}
// U_EMREXTCREATEPEN 95
}
}
}
// U_EMRPOLYTEXTOUTA 96 NOT IMPLEMENTED, denigrated after Windows NT
// U_EMRPOLYTEXTOUTW 97 NOT IMPLEMENTED, denigrated after Windows NT
// U_EMRSETICMMODE 98
}
// U_EMRCREATECOLORSPACE 99
}
// U_EMRSETCOLORSPACE 100
}
// U_EMRDELETECOLORSPACE 101
}
// U_EMRGLSRECORD 102 Not implemented
// U_EMRGLSBOUNDEDRECORD 103 Not implemented
// U_EMRPIXELFORMAT 104
}
// U_EMRDRAWESCAPE 105 Not implemented
// U_EMREXTESCAPE 106 Not implemented
// U_EMRUNDEF107 107 Not implemented
// U_EMRSMALLTEXTOUT 108
int roff=0;
int fuOptions=0;
if(torev){
}
if(!torev){
}
if(!(fuOptions & U_ETO_NO_RECT)){
}
// ordered bytes or UTF16-LE TextString
}
// U_EMRFORCEUFIMAPPING 109 Not implemented
// U_EMRNAMEDESCAPE 110 Not implemented
// U_EMRCOLORCORRECTPALETTE 111 Not implemented
// U_EMRSETICMPROFILEA 112 Not implemented
// U_EMRSETICMPROFILEW 113 Not implemented
// U_EMRALPHABLEND 114
}
// U_EMRSETLAYOUT 115
}
// U_EMRTRANSPARENTBLT 116
}
// U_EMRUNDEF117 117 Not implemented
// U_EMRGRADIENTFILL 118
int nTriVert=0;
int nGradObj=0;
int ulMode=0;
if(torev){
}
if(!torev){
}
record += sizeof(U_EMRGRADIENTFILL);
if(nTriVert){
}
if(nGradObj){
if( ulMode == U_GRADIENT_FILL_TRIANGLE){
}
}
}
}
// U_EMRSETLINKEDUFIS 119 Not implemented
// U_EMRSETTEXTJUSTIFICATION120 Not implemented (denigrated)
// U_EMRCOLORMATCHTOTARGETW 121 Not implemented
// U_EMRCREATECOLORSPACEW 122
// ordered bytes: Data
}
//! \endcond
/**
\brief Convert an entire EMF in memory from Big Endian to Little Endian.
\return 0 on failure, 1 on success
\param contents pointer to the buffer holding the entire EMF in memory
\param length number of bytes in the buffer
\param torev 1 for native to reversed, 0 for reversed to native
Normally this would be called immediately before writing the data to a file
or immediately after reading the data from a file.
*/
char *record;
OK = 1;
off = 0;
recnum = 0;
while(OK){
return(0);
}
if(!torev){
}
switch (iType)
{
case U_EMR_EOF:
OK = 0; /* Exit triggered here */
break;
} //end of switch
recnum++;
} //end of while
return(1);
}
#ifdef __cplusplus
}
#endif