?? jpeg.htm
字號:
<HTML>
<HEAD>
<TITLE> Compiling the IJG JPEG library with BC55</TITLE>
<META NAME="Author" CONTENT="Harold Howe">
</HEAD>
<BODY>
<CENTER>
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH="640">
<TR>
<TD>
<H2>
Compiling the IJG JPEG library with BC55
</H2>
<P>
The Independent JPEG Group (IJG) provides a free and open source code library for
compressing and decompressing JPEG images. The library is written in C, and is
designed to be portable between many compilers and platforms.
</P>
<P>
The IJG library is designed to be compiled from the command line with make. The
library includes several makefiles for various compilers and platforms, although
it does not provide a makefile for BC55, the free C++ command line compiler
from Borland. The purpose of this article is to provide a makefile that will
work with BC55, to list what changes have to be made in order to compile the
JPEG source code, and to provide an example program that shows how to link with
the JPEG library once you have compiled it.
</P>
<P>
Before you get started with the IJG JPEG library, you need to download the
source. You can download the IJG library from <a HREF="download/jpegsr6.zip">here.</a>
Extract the contents of the zip file to a convenient location, such as <TT>c:\jpeg</TT>.
</P>
<P>
<TABLE WIDTH="75%">
<TR>
<TD VALIGN="top">
<IMG SRC="images/exclamation.gif" ALT="Note" BORDER=0 HSPACE="0" ALIGN="top" width="32" height="48">
</TD>
<TD valign="top">
<b>Note:</b>
<hr size = 1>
<P>
If you use C++Builder, and if you use the pascal based VCL, then I suggest that you rely on the <TT>TJPEGImage</TT> class to handle
JPEG images in your programs. It is easier to use than working with the JPEG library directly. <TT>TJPEGImage</TT> is actually a wrapper
for the free IJG JPEG library. See the faq on <a HREF="faq89.htm">JPEG images</a> for an example of how to use
<TT>TJPEGImage</TT>.
</P>
<P>
On the other hand, you should use the IJG JPEG library if you are using the free
command line compiler from Borland instead of using C++Builder. You might also
want to use the IJG library if you are writing a pure C/C++ app, or if you need
the added flexibility that the IJG library affords.
</P>
<hr size = 1>
</TD>
</TR>
</TABLE>
<UL>
<LI><A HREF="#introduction" >Introduction to the IJG library</A>
<LI><A HREF="#makefile" >The JPEG library makefile</A>
<LI><A HREF="#code" >Changing the IJG source code so it will compile with BC55</A>
<LI><A HREF="#build" >Compiling the JPEG library</A>
<LI><A HREF="#example" >Using the compiled JPEG library in a project</A>
<LI><A HREF="#notes" >Notes</A>
<LI><A HREF="#downloads" >Downloads</A>
</UL>
<BR>
<H3>
<A NAME="introduction">Introduction to the IJG library</A>
</H3>
<P>
When you unzip the JPEG library, you should see a host of C files, header files, sample makefiles, and some DOC files. Before you attempt
to use the library, you should browse through the DOC files, especially <TT>libjpeg.doc</TT>. These DOC files explain how the JPEG library
is structured, and how you perform a compression or decompression step. I am not going to cover how the library works,
because the DOC files already explain that, and they explain it better than I could. Instead, I am going to discuss how to compile the
library, and specifically, how to compile the library with BC55. For more information on JPEG compression principles, visit the following
FAQs and websites:
</P>
<UL>
<LI><A HREF="http://www.faqs.org/faqs/jpeg-faq/">JPEG FAQ</A>
<LI><A HREF="http://www.faqs.org/faqs/compression-faq/">comp.compression FAQ</A>
<LI><A HREF="http://www.ijg.org/">IJG website</A>
<LI><A HREF="http://www.borland.com/bcppbuilder/freecompiler/">Download the free BC55 compiler</A>
</UL>
<BR>
<H3>
<A NAME="makefile">The JPEG library makefile</A>
</H3>
<P>
The JPEG library contains makefiles for several compilers and platforms. The makefiles are named using the format <TT>makefile.XXX</TT>
where XXX is the platform that you are targeting. Some of the names include <TT>makefile.ansi</TT>, <TT>makefile.unix</TT>,
<TT>makefile.vc</TT>, and <TT>makefile.bcc</TT>. Two of the more interesting ones are <TT>makefile.ansi</TT> and <TT>makefile.bcc</TT>.
<TT>makefile.bcc</TT> works with older versions of Borland C++ for DOS and OS/2. Despite the fact that the makefile is for an older
version of Borland C++, it still serves as a good starting ground for BC55. <TT>makefile.ansi</TT> is a generic makefile that serves as a
good starting point for almost any platform.
</P>
<P>
Using the older <TT>makefile.bcc</TT> as a starting point, I have created a makefile called <TT>makefile.bc55</TT> that works with the
free BC55 C++ compiler from Borland. You can download the makefile <a HREF="download/bc55jpeg.zip">here</a>.
</P>
<P>
The makefile for the JPEG library does several things. It compiles the JPEG source code into a library called <TT>libjpeg.lib</TT> (or
<TT>libjpeg.a</TT> depending on your OS and compiler). The makefile also compiles a compression example and a decompression example.
These examples link with the JPEG library that was built from the source. Lastly, the makefile also contains targets for cleaning up
intermediate files and for running the example programs.
</P>
<P>
Let's take a quick look at some of these targets in the makefile:
</P>
<PRE>
all: libjpeg.lib cjpeg.exe djpeg.exe jpegtran.exe wrjpgcom.exe rdjpgcom.exe
libjpeg.lib: $(LIBOBJECTS)
cjpeg.exe: $(COBJECTS) $(JPEGLIB)
djpeg.exe: $(DOBJECTS) $(JPEGLIB)
jpegtran.exe: $(TROBJECTS) $(JPEGLIB)
rdjpgcom.exe: rdjpgcom.c
wrjpgcom.exe: wrjpgcom.c
jconfig.h: jconfig.doc jconfig.bc55
clean:
test: cjpeg.exe djpeg.exe jpegtran.exe
</pre>
<P>
The <TT>all</TT> target specifies what happens by default when you do a make. The default targets are the JPEG static library
(<TT>libjpeg.lib</TT>), the compression and decompression examples (<TT>cjpeg.exe</TT> and <TT>djpeg.exe</TT>), and the utility programs.
The <TT>clean</TT> target deletes intermediate files, such as OBJs, and the <TT>test</TT> target exercises <TT>cjpeg.exe</TT> and
<TT>djpeg.exe</TT>.
</p>
<P>
<TABLE WIDTH="75%">
<TR>
<TD VALIGN="top">
<IMG SRC="images/exclamation.gif" ALT="Note" BORDER=0 HSPACE="0" ALIGN="top" width="32" height="48">
</TD>
<TD valign="top">
<b>Note:</b>
<hr size = 1>
Beware that the clean target also deletes the LIB file and the sample EXEs. If you only want the clean
target to delete OBJs, then you will need to edit the makefile.
<hr size = 1>
</TD>
</TR>
</TABLE>
<P>
The <TT>jconfig.h</TT> target is an interesting item. <TT>jconfig.h</TT> is an important header file for the JPEG library. It determines
various platform specific issues. This header file helps the JPEG library achieve its cross platform status. To support various
platforms, the JPEG library provides several versions of <TT>jconfig.h</TT> (<TT>jconfig.mac</TT>, <TT>jconfig.vc</TT>,
<TT>jconfig.bcc</TT>, etc). The makefile actually determines which configuration to use by copying the correct <TT>jconfig.xxx</TT> file
to <TT>jconfig.h</TT>. In order to support BC55, we have to supply a BC55 friendly version of <TT>jconfig.h</TT>. We'll look at this in
the next step.
</p>
<P>
That's all I'm going to say about the JPEG library makefile for BC55. You may want to sift through the makefile that I provide,
<a HREF="download/bc55jpeg.zip">makefile.bc55</a>, to learn more about how it works.
</P>
<BR>
<H3>
<A NAME="code">Changing the IJG source code so it will compile with BC55</A>
</H3>
For the most part, the JPEG source compiles fine with BC55. However, you do need to change two header files in order to compile the
library cleanly. The two files are <TT>jpeglib.h</TT>, and <TT>jmorecfg.h</TT>. You also need to provide a BC55 friendly version of
<TT>jconfig.h</TT>. You can download the modified files <a HREF="download/bc55jpeg.zip">here</a>
(along with the makefile).
<P>
The changes to <TT>jpeglib.h</TT> and <TT>jmorecfg.h</TT> are listed below. If you don't understand what these changes are doing, don't
worry about it. As long as you use the modified <a HREF="download/bc55jpeg.zip">header files</a> from my FTP site,
you will be fine.
</P>
<pre>
<font color="navy">/******************* Changes to jpeglib.h **************************/</font>
<font color="green">#ifndef JPEGLIB_H</font>
<font color="green">#define JPEGLIB_H</font>
<font color="navy">/* HJH modification: added extern "C" { when __cplusplus detected */</font>
<font color="green">#ifdef __cplusplus</font>
<b>extern</b> <font color="blue">"C"</font> <b>{</b>
<font color="green">#endif</font>
<b>...</b>
<font color="navy">/* near bottom of the file */</font>
<font color="navy">/* HJH modification: add closing } for extern "C" { */</font>
<font color="green">#ifdef __cplusplus</font>
<b>}</b>
<font color="green">#endif</font>
<font color="green">#endif <font color="navy">/* JPEGLIB_H */</font></font>
<font color="navy">/******************* Changes to jmorecfg.h **************************/</font>
<font color="navy">/* jmorecfg.h line 160 */</font>
<font color="navy">/* X11/xmd.h correctly defines INT32 */</font>
<font color="navy">/* HJH modification: jmorecfg.h already contained a test for XMD_H and xmd.h
My change adds a test for _BASETSD_H_ because the windows header file
basestd.h already defines INT32 */</font>
<font color="green">#if !defined(XMD_H) && !defined(_BASETSD_H_)</font>
<b>typedef</b> <b>long</b> INT32<b>;</b>
<font color="green">#endif</font>
<font color="navy">/* jmorecfg.h line 220 */</font>
<font color="navy">/* HJH modification: several of the windows header files already define FAR
because of this, the code below was changed so that it only tinkers with
the FAR define if FAR is still undefined */</font>
<font color="green">#ifndef FAR</font>
<font color="green">#ifdef NEED_FAR_POINTERS</font>
<font color="green">#define FAR far</font>
<font color="green">#else</font>
<font color="green">#define FAR</font>
<font color="green">#endif</font>
<font color="green">#endif</font>
</pre>
<P>
The first change was to <TT>jpeglib.h</TT>. This is the main header file that client programs include in order
to use the library. The change is to add an <TT>extern "C"</TT> wrapper around the entire header file. The reason for doing this is
that the JPEG library is written in C, but you may want to use the library from a C++ file. Without the <TT>extern "C"</TT>, you might
see unresolved external linker errors when trying to make JPEG calls from a C++ file.
</P>
<P>
The second change is to <TT>jmorecfg.h</TT>. This header file plays a crucial role in making the JPEG library cross platform. I had to
make two changes to <TT>jmorecfg.h</TT>, and both were because the Windows header files from Microsoft already declare a type or a define
that <TT>jmorecfg.h</TT> also defines. My modifications prevent <TT>jmorecfg.h</TT> from clashing with the Microsoft headers.
</P>
<P>
The last file that you have to modify is <TT>jconfig.h</TT>. Actually, you don't modify <TT>jconfig.h</TT>, rather, you provide a BC55
compatible version of <TT>jconfig.h</TT> called <TT>jconfig.bc55</TT>. To create a BC55 compatible version of <TT>jconfig.h</TT>, I
started with <TT>jconfig.bcc</TT>, which is tailored with Borland C++ for DOS in mind. This file works as is, except for the
following addition that I had to make:
</P>
<pre>
<font color="navy">/* HJH Note: Here is one key addition that I had to make. The jpeg library uses
* a type called boolean. It defines boolean here. However, RPCNDR.H
* yet another Microsoft header, also defines boolean. The ifndef
* ensures that we don't attempt to redefine boolean if rpcndr.h has
* already defined it. Note that we use unsigned char instead of int
* like jmorecfg.h does, because we want to match what's in the SDK
* header. See jconfig.vc for more info, it does the same thing. */</font>
<font color="green">#ifndef __RPCNDR_H__ <font color="navy">/* don't conflict if rpcndr.h already read */</font></font>
<b>typedef</b> <b>unsigned</b> <b>char</b> boolean<b>;</b>
<font color="green">#endif</font>
<font color="green">#define HAVE_BOOLEAN <font color="navy">/* prevent jmorecfg.h from redefining it */</font></font>
</pre>
<P>
The JPEG library defines and uses a type called <TT>boolean</TT>. The <TT>typedef</TT> occurs in <TT>jmorecfg.h</TT>. Unfortunately, one
of the Microsoft headers, <TT>rpcndr.h</TT>, also defines the <TT>boolean</TT> type. Furthermore, the Microsoft headers define
<TT>boolean</TT> differently than the JPEG library defines it. My solution was to make sure that we define <TT>boolean</TT> the same way
that the Microsoft header does, and we only define it if the Microsoft header has not already done so. Next, we define the
<TT>HAVE_BOOLEAN</TT> constant, which tells <TT>jmorecfg.h</TT> not to define the <TT>boolean</TT> type.
</P>
<P>
<TABLE WIDTH="75%">
<TR>
<TD VALIGN="top">
<IMG SRC="images/exclamation.gif" ALT="Note" BORDER=0 HSPACE="0" ALIGN="top" width="32" height="48">
</TD>
<TD valign="top">
<b>Note:</b>
<hr size = 1>
<P>
I discovered this issue regarding <TT>rpcndr.h</TT> and <TT>boolean</TT> from the configuration file for Microsoft Visual C++,
<TT>jconfig.vc</TT>. MSVC and Borland C++ provide essentially the same set of Microsoft SDK header files. Users of MSVC suffer from the
same <TT>typedef</TT> clashes that Borland C++ users suffer from.
</P>
<hr size = 1>
</TD>
</TR>
</TABLE>
<P>
Those are the only source code changes that have to be made in order to compile the JPEG library. Its nice to see that we don't have to
muck around in the C files in order to get the library to compile. Although it is disheartening when you consider that most of our
changes were to work around type clashes with the Microsoft header files.
</P>
<BR>
<H3>
<A NAME="build">Compiling the JPEG library</A>
</H3>
<P>
To compile the JPEG library, simply download <a HREF="download/bc55jpeg.zip"><TT>makefile.bc55</TT></a> and the
changes to the JPEG header files, unzip them over the existing files from the JPEG library, and run <TT>make.exe</TT> from the command
line. Make sure that you pass it the BC55 compatible makefile, <TT>makefile.bc55</TT>.
</P>
<PRE>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -