00001
#include "jpegSize.h"
00002
00003
#include <stdio.h>
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #define NEXTBYTE() getc(infile)
00019
00020
00021
00022
00023
00024
00025
00026 #define M_SOF0 0xC0
00027 #define M_SOF1 0xC1
00028 #define M_SOF2 0xC2
00029 #define M_SOF3 0xC3
00030 #define M_SOF5 0xC5
00031 #define M_SOF6 0xC6
00032 #define M_SOF7 0xC7
00033 #define M_SOF9 0xC9
00034 #define M_SOF10 0xCA
00035 #define M_SOF11 0xCB
00036 #define M_SOF13 0xCD
00037 #define M_SOF14 0xCE
00038 #define M_SOF15 0xCF
00039 #define M_SOI 0xD8
00040 #define M_EOI 0xD9
00041 #define M_SOS 0xDA
00042 #define M_APP0 0xE0
00043 #define M_APP12 0xEC
00044 #define M_COM 0xFE
00045
00046
#ifdef DONT_USE_B_MODE
00047
#define READ_BINARY "r"
00048
#else
00049
#ifdef VMS
00050
#define READ_BINARY "rb", "ctx=stm"
00051
#else
00052 #define READ_BINARY "rb"
00053
#endif
00054
#endif
00055
00056 FILE *
infile;
00057
00058
bool process_SOFn (
int& width,
int& height);
00059
bool skip_variable ();
00060
bool read_1_byte (
int* res);
00061
bool read_2_bytes (
unsigned int* res);
00062
bool first_marker (
int* res);
00063
bool next_marker (
int* res);
00064
00065 bool getJPEGSize(
const char* filename,
int& width,
int& height )
00066 {
00067
00068
if ((
infile = fopen(filename,
READ_BINARY)) == NULL)
00069
return false;
00070
00071
00072
00073
int marker;
00074
00075
00076
if (!
first_marker(&marker))
00077 {
00078 fclose(
infile);
00079
return false;
00080 }
00081
00082
00083
for (;;)
00084 {
00085
if(!
next_marker(&marker))
00086 {
00087 fclose(
infile);
00088
return false;
00089 }
00090
00091
switch (marker)
00092 {
00093
00094
00095
00096
case M_SOF0:
00097
case M_SOF1:
00098
case M_SOF2:
00099
case M_SOF3:
00100
case M_SOF5:
00101
case M_SOF6:
00102
case M_SOF7:
00103
case M_SOF9:
00104
case M_SOF10:
00105
case M_SOF11:
00106
case M_SOF13:
00107
case M_SOF14:
00108
case M_SOF15:
00109
if(!
process_SOFn(
width,
height))
00110 {
00111 fclose(
infile);
00112
return false;
00113 }
00114
else
00115 {
00116 fclose(
infile);
00117
return true;
00118 }
00119
case M_SOS:
00120 {
00121 fclose(
infile);
00122
return false;
00123 }
00124
case M_EOI:
00125 {
00126 fclose(
infile);
00127
return false;
00128 }
00129
default:
00130
skip_variable();
00131
break;
00132 }
00133 }
00134
00135
00136
00137
return false;
00138
00139 }
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 bool first_marker (
int* res)
00150 {
00151
int c1, c2;
00152 c1 =
NEXTBYTE();
00153 c2 =
NEXTBYTE();
00154
if (c1 != 0xFF || c2 !=
M_SOI)
00155
return false;
00156
else
00157 {
00158 *res = c2;
00159
return true;
00160 }
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 bool next_marker (
int* res)
00173 {
00174
int c;
00175
int discarded_bytes = 0;
00176
00177
00178
if(!
read_1_byte(&c))
00179
return false;
00180
while (c != 0xFF)
00181 {
00182 discarded_bytes++;
00183
if(!
read_1_byte(&c))
00184
return false;
00185 }
00186
00187
00188
00189
do
00190 {
00191
if(!
read_1_byte(&c))
00192
return false;
00193 }
while (c == 0xFF);
00194
00195
00196
00197 *res = c;
00198
return true;
00199 }
00200
00201
00202 bool read_1_byte (
int* res)
00203 {
00204
int c =
NEXTBYTE();
00205
if (c == EOF)
00206
return false;
00207
else
00208 {
00209 *res = c;
00210
return true;
00211 }
00212 }
00213
00214
00215
00216 bool read_2_bytes (
unsigned int* res)
00217 {
00218
int c1, c2;
00219 c1 =
NEXTBYTE();
00220
if (c1 == EOF)
00221
return false;
00222 c2 =
NEXTBYTE();
00223
if (c2 == EOF)
00224
return false;
00225 *res = (((
unsigned int) c1) << 8) + ((
unsigned int) c2);
00226
return true;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 bool skip_variable ()
00238
00239 {
00240
unsigned int length;
00241
00242
00243
if(!
read_2_bytes(&length))
00244
return false;
00245
00246
if (length < 2)
00247
return false;
00248 length -= 2;
00249
00250
while (length > 0)
00251 {
00252
int tmp;
00253
if(!
read_1_byte(&tmp))
00254
return false;
00255 length--;
00256 }
00257
return false;
00258 }
00259
00260
00261 bool process_SOFn (
int& width,
int& height)
00262 {
00263
unsigned int length;
00264
unsigned int image_height, image_width;
00265
int data_precision;
00266
00267
if(!
read_2_bytes(&length) ||
00268 !
read_1_byte(&data_precision) ||
00269 !
read_2_bytes(&image_height) ||
00270 !
read_2_bytes(&image_width) )
00271
return false;
00272
00273
width = (
int) image_width;
00274
height = (
int) image_height;
00275
return true;
00276 }