BetterJPEG LIBRARY API

BJPEG04.dll


First step in using the library is the initialization of the library:

STDAPI InitBJPEGLibrary(char* strName, char* strKey) - initializes the library.

strName - registration name,
strKey - registration key.

It is possible to use the library for evaluation purpose within 30-days period using "Evaluation" as a registration name and "DMGCOLLGDIIEJD" as a registration key.


Example of the library initialization / termination code:

HMODULE m_HM;

CJPEGlib::CJPEGlib(HMODULE* pHM)
{
	*pHM = m_HM = LoadLibrary("BJPEG04.dll");

	typedef HRESULT(__stdcall *FPT_P)(char*, char*);
	FPT_P FP_P;
	if (m_HM)
	{
		FP_P = (FPT_P)GetProcAddress(m_HM,"InitBJPEGLibrary");
		if (FP_P)
			if ((FP_P)("Evaluation", "DMGCOLLGDIIEJD") != S_OK)
			{
				//
			}
	}

}

CJPEGlib::~CJPEGlib()
{
	if (m_HM) FreeLibrary(m_HM);
}

Next step is creation of an object supporting IBJPEG interface (BJPEG object). This object represents a single jpeg image. All further work with the image is performed via IBJPEG interface of the corresponding object. Multiple instances of such objects can be created if work on several images at the same time is required.

STDAPI CreateBJPEGObject(IBJPEG** ppObject) - creates a BJPEG object with IBJPEG interface.

ppObject - pointer to a variable that receives a pointer to the object.


Example of object creation / destruction code:

HMODULE m_JPEGlib;

IBJPEG* m_pJPG;

CImage::CImage()
{
	m_pJPG = NULL;
	
	typedef HRESULT(__stdcall *FPT_P)(IBJPEG**);
	FPT_P FP_P;
	if (m_JPEGlib)
	{
		FP_P = (FPT_P)GetProcAddress(m_JPEGlib,"CreateBJPEGObject");
		if (FP_P)
			if ((FP_P)(&m_pJPG) != S_OK)
			{
				///
			}
	}
}

CImage::~CImage()
{
	if (m_pJPG) m_pJPG->Release();
}

IBJPEG INTERFACE METHODS


BOOL ReadCoefficients(LPCSTR szFileName) - reads JPEG file into memory.

szFileName - full path to the JPEG file.

returns TRUE in case of success.

Usually this is the first method called for a JPEG file. Can be called many times on the BJPEG object - call it each time you need to load a new image into memory.


void ReleaseImage() - finishes work with the currently loaded image, releases memory.

Not required before ReadCoefficients.


BOOL IsLoaded()

returns TRUE if image is loaded (should return TRUE after successful call to ReadCoefficients up until ReleaseImage).


int GetWidth()
int GetHeight()

return picture dimensions in pixels.

After manipulations on the image, such as rotation, crop, etc. these methods return updated dimensions (correct).


int GetMCUWidth()
int GetMCUHeight()

return MCU (minimum coded unit) dimensions for current image in pixels.

MCUs can have 8x8, 8x16, 16x8, and 16x16 dimensions. After rotation this method returns updated dimensions.


BOOL GetBitmap(BYTE* pBits, int iBMPRowSize) - decodes the jpeg image into an external bitmap buffer.

pBits - pointer to an external bitmap buffer,
iBMPRowSize - row size of the target bitmap.

returns TRUE in case of success.

In current implementation dimensions of the bitmap should be multiple of corresponding MCU dimension (image dimensions should be rounded up to next multiple of MCU dimension). Output is in BGR "upside down" sequence. Grayscale jpegs are converted to BGR as well.


Sample code:

BOOL CImage::CreateBitmap()
{
	// Round up the bitmap dimensions to IMCU boundary
	int iBitmapWidth = round_up(m_pJPG->GetWidth(), m_pJPG->GetMCUWidth());
	int iBitmapHeight = round_up(m_pJPG->GetHeight(), m_pJPG->GetMCUHeight());

	// Fill in bitmap info
	m_iBMPRowSize = iBitmapWidth * 3;
	m_bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
	m_bmi.bmiHeader.biCompression = BI_RGB;
	m_bmi.bmiHeader.biBitCount = 24;
	m_bmi.bmiHeader.biPlanes = 1;
	m_bmi.bmiHeader.biWidth = iBitmapWidth;
	m_bmi.bmiHeader.biHeight = iBitmapHeight;
	m_bmi.bmiHeader.biSizeImage = m_iBMPRowSize * iBitmapHeight;
	m_bmi.bmiHeader.biXPelsPerMeter = 0;
	m_bmi.bmiHeader.biYPelsPerMeter = 0;
	m_bmi.bmiHeader.biClrUsed = 0;
	m_bmi.bmiHeader.biClrImportant = 0;

	// Create new bitmap
	if (!(m_hBitmap = CreateDIBSection(NULL, &m_bmi, DIB_RGB_COLORS, (PVOID*)&m_pBits, NULL, 0))) return FALSE;

	m_pJPG->GetBitmap(m_pBits, m_iBMPRowSize, iBitmapHeight);

	return TRUE;
}

long round_up (long a, long b)
// Compute a rounded up to next multiple of b, ie, ceil(a/b)*b
// Assumes a >= 0, b > 0
{
	a += b - 1L;
	return a - (a % b);
}

In many cases decoding of the bitmap is not required, lossless operations can be performed on jpeg coefficients, without having to decode.


BOOL Save(LPCSTR szFileName, save_params* pParams) - saves changed JPEG image to file.

szFileName - full path to the target file (if blank, the file is saved with the original name),
pParams - pointer to save_params structure.

returns TRUE in case of success.

struct save_params
{
  BOOL bRetainOriginalTime // retain original file date / time
  BOOL bOptimizeHuffman    // optimize Huffman tables (smaller size without loss in quality)
  BOOL bSaveComments       // don't discard comments (metadata)
  BOOL bSaveEXIF           // don't discard EXIF

  // Thumbnail
  int iGenerateEXIFThumb   // EXIF thumbnail refresh mode (see enum)
  int iEXIFThumbSize       // max thumbnail dimension in pixels

  // Bitmap
  BYTE* pBits   // if not NULL, the bitmap is compared to JPEG coefficients and all the 
                // changed coefficients get recompressed on DCT level rather than on MCU
                // which results in minimal possible recompression (can be used for red-eye
                // removal, text imprint, paste, watermark, frames, etc without full
                // recompression). The bitmap provided should match the current state of
                // the image - if the image has been rotated, the bitmap should have
                // corresponding orientation, if the image has been cropped, the bitmap
                // should have corresponding dimensions, etc. Calling Save method does
                // not change coefficients in memory, it only saves changes to file.
                // pBits can be NULL if bitmap is not required (rotation, flip, crop)

  int iBitmapHeight   // bitmap height,
  int iBitmapRowSize  // bitmap row size

  // Statistics (returned values)
  int iMCUsChanged    // number of MCUs changed
  int iDCTsChanged    // number of DCTs changed
};

enum {
  eThumbNever               // remove EXIF thumbnail
  eThumbKeepExisting        // keep existing EXIF thumbnail
  eThumbRegenerateExisting  // refresh EXIF thumbnail (if exists)
};

BOOL Crop(int iLeft, int iTop, int iRight, int iBottom) - performs lossless crop.

returns TRUE in case of success.


BOOL FlipH() - flips horizontally (lossless).

returns TRUE in case of success.


BOOL FlipV() - flips vertically (lossless).

returns TRUE in case of success.


BOOL RotateLeft() - rotates clockwise (lossless).

returns TRUE in case of success.


BOOL RotateRight() - rotates counter-clockwise (lossless).

returns TRUE in case of success.


BOOL Undo() - undoes previous operation (rotation, flip, crop).

returns TRUE in case of success.

Undo buffer is not limited.


BOOL CreatePreview(LPCSTR szFileName, BYTE* pBits, int iThumbWidth, int iThumbHeight, int iBitmapWidth, BYTE iR, BYTE iG, BYTE iB, int* piImageWidth, int* piImageHeight) - generates a quick scaled down preview.

szFileName - file name,
pBits - pointer to an external bitmap buffer (no need to round up to whole MCUs),
iThumbWidth, iThumbHeight - preview bitmap dimensions,
iBitmapWidth - bitmap width (can be >= iThumbWidth*3),
iR, iG, iB - background color,
piImageWidth, piImageHeight - pointers to variables that receive original picture dimensions (not scaled down).

returns TRUE in case of success.

This method is used by BetterJPEG to generate thumbnails for the folder browser pane.

CreatePreview is an independent method that does not require calling ReadCoefficients and ReleaseImage. CreatePreview can be called on any BJPEG object without affecting the state of the object.


LPCSTR Format(LPCSTR szFormat, BOOL bUseFileTime, LCID iLocale, LPCSTR szDateFormat, LPCSTR szTimeFormat) - returns formatted EXIF parameters string.

szFormat - format string, can contain text and the following parameters:

Mask   Parameter   Output example
%c Comment Fred's Dog
%C Copyright sign ©
%d Date (in format defined in preferences) May 04, 2004
%e Exposure time 1/61s
%f F-number F2.6
%i ISO speed ratings ISO100
%L Focal length in 35mm film equivalent 38mm
%l Focal length 7.9mm
%M Make NIKON
%m Model E4500
%t Time (in format defined in preferences) 12:52
%V Source file name (the name with which the file was open) DSCN0475
%v Source file name and extension DSCN0475.jpg
%W Destination file name (the name under which the file was last saved) dog2
%w Destination file name and extension dog2.jpg
%% Percent sign %

bUseFileTime - use file time if no EXIF is present,

iLocale - locale (for correct date / time format),

szDateFormat - date format string can contain the following parameters:

Element Meaning
d Day of month as digits with no leading zero for single-digit days.
dd Day of month as digits with leading zero for single-digit days.
ddd Day of week as a three-letter abbreviation.
dddd Day of week as its full name.
M Month as digits with no leading zero for single-digit months.
MM Month as digits with leading zero for single-digit months.
MMM Month as a three-letter abbreviation.
MMMM Month as its full name.
y Year as last two digits, but with no leading zero for years less than 10.
yy Year as last two digits, but with leading zero for years less than 10.
yyyy Year represented by full four digits.


szTimeFormat - time format string:

Element Meaning
h Hours with no leading zero for single-digit hours; 12-hour clock.
hh Hours with leading zero for single-digit hours; 12-hour clock.
H Hours with no leading zero for single-digit hours; 24-hour clock.
HH Hours with leading zero for single-digit hours; 24-hour clock.
m Minutes with no leading zero for single-digit minutes.
mm Minutes with leading zero for single-digit minutes.
s Seconds with no leading zero for single-digit seconds.
ss Seconds with leading zero for single-digit seconds.
t One character time-marker string, such as A or P.
tt Multicharacter time-marker string, such as AM or PM.


USHORT GetOrientation() - gets EXIF image orientation flag.

returns EXIF image orientation flag.


void SetOrientation(USHORT iOrientation) - sets EXIF image orientation flag.

iOrientation - EXIF image orientation flag.



BetterJPEG library is based in part on the work of the Independent JPEG Group.