00001
00020 #include "mfcpch.h"
00021 #ifdef __MSW32__
00022 #include <io.h>
00023 #else
00024 #include <unistd.h>
00025 #endif
00026 #include <fcntl.h>
00027 #include <sys/types.h>
00028 #include <sys/stat.h>
00029 #include <string.h>
00030 #include "scanutils.h"
00031 #include "stderr.h"
00032 #include "fileerr.h"
00033 #include "imgerrs.h"
00034 #include "memry.h"
00035 #include "imgs.h"
00036 #include "imgbmp.h"
00037 #include "imgtiff.h"
00038 #include "imgio.h"
00039
00040 #define DEFAULTIMAGETYPE "tif" //default to im files
00041
00046 typedef struct
00047 {
00048 const char *string;
00049 IMAGE_OPENER opener;
00050 IMAGE_READER reader;
00051 IMAGE_WRITER writer;
00052 } IMAGETYPE;
00053
00055 static IMAGETYPE imagetypes[] = { {
00056 "TIF",
00057 open_tif_image,
00058 read_tif_image,
00059 write_moto_tif
00060 },
00061 {
00062 "itf",
00063 open_tif_image,
00064 read_tif_image,
00065 write_inverse_tif
00066 },
00067 {
00068 "tif",
00069 open_tif_image,
00070 read_tif_image,
00071 write_intel_tif
00072 },
00073 {
00074 "bmp",
00075 open_bmp_image,
00076 read_bmp_image,
00077 write_bmp_image
00078 },
00079 };
00080
00081 #define MAXIMAGETYPES (sizeof(imagetypes)/sizeof(IMAGETYPE))
00082
00087 static INT8 name_to_image_type(
00088 const char *name
00089 ) {
00090 const char *nametype;
00091 INT8 type;
00092
00093 nametype = strrchr (name, '.');
00094 if (nametype != NULL)
00095 nametype++;
00096 else
00097 nametype = DEFAULTIMAGETYPE;
00098
00099
00100 for (type = 0;
00101 type < MAXIMAGETYPES && strcmp (imagetypes[type].string, nametype); type++);
00102 if (type >= MAXIMAGETYPES) {
00103
00104 BADIMAGETYPE.error ("name_to_image_type", LOG, name);
00105 return -1;
00106 }
00107 return type;
00108 }
00109
00110
00117 INT8 IMAGE::read_header(
00118 const char *name
00119 ) {
00120 INT8 type;
00121
00122 destroy();
00123
00124 type = name_to_image_type (name);
00125 if (type < 0 || imagetypes[type].opener == NULL) {
00126 CANTREADIMAGETYPE.error ("IMAGE::read_header", LOG, name);
00127 return -1;
00128 }
00129 #ifdef __UNIX__
00130 if ((fd = open (name, O_RDONLY)) < 0)
00131 #endif
00132 #if defined (__MSW32__) || defined (__MAC__)
00133 if ((fd = open (name, O_RDONLY | O_BINARY)) < 0)
00134 #endif
00135 {
00136 CANTOPENFILE.error ("IMAGE::read_header", LOG, name);
00137 return -1;
00138 }
00139 lineskip =
00140 (*imagetypes[type].opener) (fd, &xsize, &ysize, &bpp, &photo_interp,
00141 &res);
00142 if (lineskip == -1) {
00143
00144 bpp = 0;
00145 close(fd);
00146 fd = -1;
00147 return -1;
00148 }
00149 if (res <= 0)
00150 res = image_default_resolution;
00151
00152
00153
00154 xdim = COMPUTE_IMAGE_XDIM (xsize, bpp);
00155 bps = bpp == 24 ? 8 : bpp;
00156 bytespp = (bpp + 7) / 8;
00157
00158 reader = imagetypes[type].reader;
00159 return 0;
00160 }
00161
00162
00174 INT8 IMAGE::read(
00175 INT32 buflines
00176 ) {
00177 INT32 row;
00178 BOOL8 failed;
00179
00180 if (fd < 0 || image != NULL)
00181 IMAGEUNDEFINED.error ("IMAGE::read", ABORT, NULL);
00182
00183 if (buflines <= 0 || buflines > ysize || reader == NULL)
00184 buflines = ysize;
00185 bufheight = buflines;
00186 image =
00187 (UINT8 *) alloc_big_mem ((size_t) (xdim * bufheight * sizeof (UINT8)));
00188 if (image == NULL) {
00189 MEMORY_OUT.error ("IMAGE::read", LOG, NULL);
00190 destroy();
00191 return -1;
00192 }
00193 captured = FALSE;
00194 ymax = ysize;
00195 ymin = ysize - buflines;
00196 if (reader != NULL && lineskip < 0)
00197 failed = (*reader) (fd, image, xsize, ysize, bpp, xdim) < 0;
00198 else {
00199 if (lineskip == 0)
00200 failed =::read (fd, (char *) image,
00201 (size_t) (xdim * bufheight)) != xdim * bufheight;
00202 else {
00203 for (failed = FALSE, row = 0; row < bufheight && !failed; row++) {
00204 failed =::read (fd, (char *) image + row * xdim,
00205 (size_t) xdim) != xdim;
00206 failed |= lseek (fd, lineskip, SEEK_CUR) < 0;
00207 }
00208 }
00209 }
00210 if (failed) {
00211 READFAILED.error ("IMAGE::read", LOG, NULL);
00212 destroy();
00213 return -1;
00214 }
00215 if (ymin <= 0) {
00216 close(fd);
00217 fd = -1;
00218 }
00219 return 0;
00220 }
00221
00222
00226 INT8 IMAGE::bufread(
00227 INT32 y
00228 ) {
00229 INT32 readtop;
00230 INT32 linestoread;
00231 INT32 row;
00232 BOOL8 failed;
00233
00234
00235 if (y + bufheight / 2 >= ymin) {
00236
00237 readtop = y + bufheight / 2 - ymin + 1;
00238
00239 copy_sub_image (this, 0, ymin, xsize, readtop, this,
00240 0, ymax - readtop, TRUE);
00241 }
00242 else
00243 readtop = 0;
00244 ymax = y + bufheight / 2;
00245 ymin = ymax - bufheight;
00246 if (ymin < 0)
00247 ymin = 0;
00248 linestoread = ymax - ymin - readtop;
00249 if (lineskip == 0)
00250 failed =::read (fd, (char *) (image + xdim * readtop),
00251 (size_t) (xdim * linestoread)) != xdim * linestoread;
00252 else {
00253 for (failed = FALSE, row = 0; row < linestoread && !failed; row++) {
00254 failed =::read (fd, (char *) (image + (readtop + row) * xdim),
00255 (size_t) xdim) != xdim;
00256 failed |= lseek (fd, lineskip, SEEK_CUR) < 0;
00257 }
00258 }
00259 if (failed) {
00260 READFAILED.error ("IMAGE::bufread", LOG, NULL);
00261 return -1;
00262 }
00263 if (ymin <= 0) {
00264 close(fd);
00265 fd = -1;
00266 }
00267 return 0;
00268 }
00269
00270
00274 INT8 IMAGE::write(
00275 const char *name
00276 ) {
00277 INT8 type;
00278
00279 if (bpp == 0 || image == NULL || bufheight != ysize)
00280 IMAGEUNDEFINED.error ("IMAGE::write", ABORT, NULL);
00281 if (fd >= 0) {
00282 close(fd);
00283 fd = -1;
00284 }
00285
00286 type = name_to_image_type (name);
00287 if (type < 0 || imagetypes[type].writer == NULL) {
00288 CANTWRITEIMAGETYPE.error ("IMAGE::write", LOG, name);
00289 return -1;
00290 }
00291 #ifdef __UNIX__
00292 if ((fd = creat (name, 0666)) < 0)
00293 #endif
00294 #ifdef __MSW32__
00295 if ((fd = open (name, _O_CREAT | _O_WRONLY | _O_BINARY, _S_IWRITE)) < 0)
00296 #endif
00297 #ifdef __MAC__
00298 if ((fd = creat (name, O_WRONLY | O_BINARY)) < 0)
00299 #endif
00300 {
00301 CANTCREATEFILE.error ("IMAGE::write", LOG, name);
00302 return -1;
00303 }
00304 if (res <= 0)
00305 res = image_default_resolution;
00306 if ((*imagetypes[type].writer) (fd, image, xsize, ysize, bpp, photo_interp,
00307 res) < 0) {
00308
00309
00310 WRITEFAILED.error ("IMAGE::write", LOG, name);
00311 close(fd);
00312 fd = -1;
00313 return -1;
00314 }
00315 return 0;
00316 }