00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 #ifndef XMS_SUPPORTED
00035 #define XMS_SUPPORTED  1
00036 #endif
00037 #ifndef EMS_SUPPORTED
00038 #define EMS_SUPPORTED  1
00039 #endif
00040 
00041 
00042 #define JPEG_INTERNALS
00043 #include "jinclude.h"
00044 #include "jpeglib.h"
00045 #include "jmemsys.h"            
00046 
00047 #ifndef HAVE_STDLIB_H           
00048 extern void * malloc JPP((size_t size));
00049 extern void free JPP((void *ptr));
00050 extern char * getenv JPP((const char * name));
00051 #endif
00052 
00053 #ifdef NEED_FAR_POINTERS
00054 
00055 #ifdef __TURBOC__
00056 
00057 #include <alloc.h>              
00058 #define far_malloc(x)   farmalloc(x)
00059 #define far_free(x)     farfree(x)
00060 #else
00061 
00062 #include <malloc.h>             
00063 #define far_malloc(x)   _fmalloc(x)
00064 #define far_free(x)     _ffree(x)
00065 #endif
00066 
00067 #else 
00068 
00069 #define far_malloc(x)   malloc(x)
00070 #define far_free(x)     free(x)
00071 
00072 #endif 
00073 
00074 #ifdef DONT_USE_B_MODE          
00075 #define READ_BINARY     "r"
00076 #else
00077 #define READ_BINARY     "rb"
00078 #endif
00079 
00080 #ifndef USE_MSDOS_MEMMGR        
00081   You forgot to define USE_MSDOS_MEMMGR in jconfig.h. 
00082 #endif
00083 
00084 #if MAX_ALLOC_CHUNK >= 65535L   
00085   MAX_ALLOC_CHUNK should be less than 64K. 
00086 #endif
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 typedef void far * XMSDRIVER;   
00098 typedef struct {                
00099         unsigned short ax, dx, bx;
00100         void far * ds_si;
00101       } XMScontext;
00102 typedef struct {                
00103         unsigned short ax, dx, bx;
00104         void far * ds_si;
00105       } EMScontext;
00106 
00107 extern short far jdos_open JPP((short far * handle, char far * filename));
00108 extern short far jdos_close JPP((short handle));
00109 extern short far jdos_seek JPP((short handle, long offset));
00110 extern short far jdos_read JPP((short handle, void far * buffer,
00111                                 unsigned short count));
00112 extern short far jdos_write JPP((short handle, void far * buffer,
00113                                  unsigned short count));
00114 extern void far jxms_getdriver JPP((XMSDRIVER far *));
00115 extern void far jxms_calldriver JPP((XMSDRIVER, XMScontext far *));
00116 extern short far jems_available JPP((void));
00117 extern void far jems_calldriver JPP((EMScontext far *));
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 static int next_file_num;       
00126 
00127 LOCAL(void)
00128 select_file_name (char * fname)
00129 {
00130   const char * env;
00131   char * ptr;
00132   FILE * tfile;
00133 
00134   
00135   for (;;) {
00136     
00137 
00138 
00139     if ((env = (const char *) getenv("TMP")) == NULL)
00140       if ((env = (const char *) getenv("TEMP")) == NULL)
00141         env = ".";
00142     if (*env == '\0')           
00143       env = ".";
00144     ptr = fname;                
00145     while (*env != '\0')
00146       *ptr++ = *env++;
00147     if (ptr[-1] != '\\' && ptr[-1] != '/')
00148       *ptr++ = '\\';            
00149     
00150     next_file_num++;            
00151     sprintf(ptr, "JPG%03d.TMP", next_file_num);
00152     
00153     if ((tfile = fopen(fname, READ_BINARY)) == NULL)
00154       break;
00155     fclose(tfile);              
00156   }
00157 }
00158 
00159 
00160 
00161 
00162 
00163 
00164 
00165 GLOBAL(void *)
00166 jpeg_get_small (j_common_ptr cinfo, size_t sizeofobject)
00167 {
00168   return (void *) malloc(sizeofobject);
00169 }
00170 
00171 GLOBAL(void)
00172 jpeg_free_small (j_common_ptr cinfo, void * object, size_t sizeofobject)
00173 {
00174   free(object);
00175 }
00176 
00177 
00178 
00179 
00180 
00181 
00182 GLOBAL(void FAR *)
00183 jpeg_get_large (j_common_ptr cinfo, size_t sizeofobject)
00184 {
00185   return (void FAR *) far_malloc(sizeofobject);
00186 }
00187 
00188 GLOBAL(void)
00189 jpeg_free_large (j_common_ptr cinfo, void FAR * object, size_t sizeofobject)
00190 {
00191   far_free(object);
00192 }
00193 
00194 
00195 
00196 
00197 
00198 
00199 
00200 
00201 
00202 
00203 #ifndef DEFAULT_MAX_MEM         
00204 #define DEFAULT_MAX_MEM         300000L 
00205 #endif
00206 
00207 GLOBAL(long)
00208 jpeg_mem_available (j_common_ptr cinfo, long min_bytes_needed,
00209                     long max_bytes_needed, long already_allocated)
00210 {
00211   return cinfo->mem->max_memory_to_use - already_allocated;
00212 }
00213 
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221 
00222 
00223 
00224 
00225 
00226 
00227 
00228 
00229 
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 
00238 
00239 
00240 
00241 
00242 METHODDEF(void)
00243 read_file_store (j_common_ptr cinfo, backing_store_ptr info,
00244                  void FAR * buffer_address,
00245                  long file_offset, long byte_count)
00246 {
00247   if (jdos_seek(info->handle.file_handle, file_offset))
00248     ERREXIT(cinfo, JERR_TFILE_SEEK);
00249   
00250   if (byte_count > 65535L)      
00251     ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
00252   if (jdos_read(info->handle.file_handle, buffer_address,
00253                 (unsigned short) byte_count))
00254     ERREXIT(cinfo, JERR_TFILE_READ);
00255 }
00256 
00257 
00258 METHODDEF(void)
00259 write_file_store (j_common_ptr cinfo, backing_store_ptr info,
00260                   void FAR * buffer_address,
00261                   long file_offset, long byte_count)
00262 {
00263   if (jdos_seek(info->handle.file_handle, file_offset))
00264     ERREXIT(cinfo, JERR_TFILE_SEEK);
00265   
00266   if (byte_count > 65535L)      
00267     ERREXIT(cinfo, JERR_BAD_ALLOC_CHUNK);
00268   if (jdos_write(info->handle.file_handle, buffer_address,
00269                  (unsigned short) byte_count))
00270     ERREXIT(cinfo, JERR_TFILE_WRITE);
00271 }
00272 
00273 
00274 METHODDEF(void)
00275 close_file_store (j_common_ptr cinfo, backing_store_ptr info)
00276 {
00277   jdos_close(info->handle.file_handle); 
00278   remove(info->temp_name);      
00279 
00280 
00281 
00282 
00283   TRACEMSS(cinfo, 1, JTRC_TFILE_CLOSE, info->temp_name);
00284 }
00285 
00286 
00287 LOCAL(boolean)
00288 open_file_store (j_common_ptr cinfo, backing_store_ptr info,
00289                  long total_bytes_needed)
00290 {
00291   short handle;
00292 
00293   select_file_name(info->temp_name);
00294   if (jdos_open((short far *) & handle, (char far *) info->temp_name)) {
00295     
00296     ERREXITS(cinfo, JERR_TFILE_CREATE, info->temp_name);
00297     return FALSE;
00298   }
00299   info->handle.file_handle = handle;
00300   info->read_backing_store = read_file_store;
00301   info->write_backing_store = write_file_store;
00302   info->close_backing_store = close_file_store;
00303   TRACEMSS(cinfo, 1, JTRC_TFILE_OPEN, info->temp_name);
00304   return TRUE;                  
00305 }
00306 
00307 
00308 
00309 
00310 
00311 
00312 #if XMS_SUPPORTED
00313 
00314 static XMSDRIVER xms_driver;    
00315 
00316 typedef union {                 
00317         long offset;
00318         void far * ptr;
00319       } XMSPTR;
00320 
00321 typedef struct {                
00322         long length;
00323         XMSH src_handle;
00324         XMSPTR src;
00325         XMSH dst_handle;
00326         XMSPTR dst;
00327       } XMSspec;
00328 
00329 #define ODD(X)  (((X) & 1L) != 0)
00330 
00331 
00332 METHODDEF(void)
00333 read_xms_store (j_common_ptr cinfo, backing_store_ptr info,
00334                 void FAR * buffer_address,
00335                 long file_offset, long byte_count)
00336 {
00337   XMScontext ctx;
00338   XMSspec spec;
00339   char endbuffer[2];
00340 
00341   
00342 
00343 
00344 
00345   spec.length = byte_count & (~ 1L);
00346   spec.src_handle = info->handle.xms_handle;
00347   spec.src.offset = file_offset;
00348   spec.dst_handle = 0;
00349   spec.dst.ptr = buffer_address;
00350   
00351   ctx.ds_si = (void far *) & spec;
00352   ctx.ax = 0x0b00;              
00353   jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
00354   if (ctx.ax != 1)
00355     ERREXIT(cinfo, JERR_XMS_READ);
00356 
00357   if (ODD(byte_count)) {
00358     read_xms_store(cinfo, info, (void FAR *) endbuffer,
00359                    file_offset + byte_count - 1L, 2L);
00360     ((char FAR *) buffer_address)[byte_count - 1L] = endbuffer[0];
00361   }
00362 }
00363 
00364 
00365 METHODDEF(void)
00366 write_xms_store (j_common_ptr cinfo, backing_store_ptr info,
00367                  void FAR * buffer_address,
00368                  long file_offset, long byte_count)
00369 {
00370   XMScontext ctx;
00371   XMSspec spec;
00372   char endbuffer[2];
00373 
00374   
00375 
00376 
00377 
00378   spec.length = byte_count & (~ 1L);
00379   spec.src_handle = 0;
00380   spec.src.ptr = buffer_address;
00381   spec.dst_handle = info->handle.xms_handle;
00382   spec.dst.offset = file_offset;
00383 
00384   ctx.ds_si = (void far *) & spec;
00385   ctx.ax = 0x0b00;              
00386   jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
00387   if (ctx.ax != 1)
00388     ERREXIT(cinfo, JERR_XMS_WRITE);
00389 
00390   if (ODD(byte_count)) {
00391     read_xms_store(cinfo, info, (void FAR *) endbuffer,
00392                    file_offset + byte_count - 1L, 2L);
00393     endbuffer[0] = ((char FAR *) buffer_address)[byte_count - 1L];
00394     write_xms_store(cinfo, info, (void FAR *) endbuffer,
00395                     file_offset + byte_count - 1L, 2L);
00396   }
00397 }
00398 
00399 
00400 METHODDEF(void)
00401 close_xms_store (j_common_ptr cinfo, backing_store_ptr info)
00402 {
00403   XMScontext ctx;
00404 
00405   ctx.dx = info->handle.xms_handle;
00406   ctx.ax = 0x0a00;
00407   jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
00408   TRACEMS1(cinfo, 1, JTRC_XMS_CLOSE, info->handle.xms_handle);
00409   
00410 }
00411 
00412 
00413 LOCAL(boolean)
00414 open_xms_store (j_common_ptr cinfo, backing_store_ptr info,
00415                 long total_bytes_needed)
00416 {
00417   XMScontext ctx;
00418 
00419   
00420   jxms_getdriver((XMSDRIVER far *) & xms_driver);
00421   if (xms_driver == NULL)
00422     return FALSE;               
00423 
00424   
00425   ctx.ax = 0x0000;
00426   jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
00427   if (ctx.ax < (unsigned short) 0x0200)
00428     return FALSE;
00429 
00430   
00431   ctx.dx = (unsigned short) ((total_bytes_needed + 1023L) >> 10);
00432   ctx.ax = 0x0900;
00433   jxms_calldriver(xms_driver, (XMScontext far *) & ctx);
00434   if (ctx.ax != 1)
00435     return FALSE;
00436 
00437   
00438   info->handle.xms_handle = ctx.dx;
00439   info->read_backing_store = read_xms_store;
00440   info->write_backing_store = write_xms_store;
00441   info->close_backing_store = close_xms_store;
00442   TRACEMS1(cinfo, 1, JTRC_XMS_OPEN, ctx.dx);
00443   return TRUE;                  
00444 }
00445 
00446 #endif 
00447 
00448 
00449 
00450 
00451 
00452 
00453 #if EMS_SUPPORTED
00454 
00455 
00456 
00457 
00458 
00459 
00460 
00461 
00462 
00463 
00464 typedef void far * EMSPTR;
00465 
00466 typedef union {                 
00467         long length;            
00468         char bytes[18];         
00469       } EMSspec;
00470 
00471 
00472 #define FIELD_AT(spec,offset,type)  (*((type *) &(spec.bytes[offset])))
00473 #define SRC_TYPE(spec)          FIELD_AT(spec,4,char)
00474 #define SRC_HANDLE(spec)        FIELD_AT(spec,5,EMSH)
00475 #define SRC_OFFSET(spec)        FIELD_AT(spec,7,unsigned short)
00476 #define SRC_PAGE(spec)          FIELD_AT(spec,9,unsigned short)
00477 #define SRC_PTR(spec)           FIELD_AT(spec,7,EMSPTR)
00478 #define DST_TYPE(spec)          FIELD_AT(spec,11,char)
00479 #define DST_HANDLE(spec)        FIELD_AT(spec,12,EMSH)
00480 #define DST_OFFSET(spec)        FIELD_AT(spec,14,unsigned short)
00481 #define DST_PAGE(spec)          FIELD_AT(spec,16,unsigned short)
00482 #define DST_PTR(spec)           FIELD_AT(spec,14,EMSPTR)
00483 
00484 #define EMSPAGESIZE     16384L  
00485 
00486 #define HIBYTE(W)  (((W) >> 8) & 0xFF)
00487 #define LOBYTE(W)  ((W) & 0xFF)
00488 
00489 
00490 METHODDEF(void)
00491 read_ems_store (j_common_ptr cinfo, backing_store_ptr info,
00492                 void FAR * buffer_address,
00493                 long file_offset, long byte_count)
00494 {
00495   EMScontext ctx;
00496   EMSspec spec;
00497 
00498   spec.length = byte_count;
00499   SRC_TYPE(spec) = 1;
00500   SRC_HANDLE(spec) = info->handle.ems_handle;
00501   SRC_PAGE(spec)   = (unsigned short) (file_offset / EMSPAGESIZE);
00502   SRC_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
00503   DST_TYPE(spec) = 0;
00504   DST_HANDLE(spec) = 0;
00505   DST_PTR(spec)    = buffer_address;
00506   
00507   ctx.ds_si = (void far *) & spec;
00508   ctx.ax = 0x5700;              
00509   jems_calldriver((EMScontext far *) & ctx);
00510   if (HIBYTE(ctx.ax) != 0)
00511     ERREXIT(cinfo, JERR_EMS_READ);
00512 }
00513 
00514 
00515 METHODDEF(void)
00516 write_ems_store (j_common_ptr cinfo, backing_store_ptr info,
00517                  void FAR * buffer_address,
00518                  long file_offset, long byte_count)
00519 {
00520   EMScontext ctx;
00521   EMSspec spec;
00522 
00523   spec.length = byte_count;
00524   SRC_TYPE(spec) = 0;
00525   SRC_HANDLE(spec) = 0;
00526   SRC_PTR(spec)    = buffer_address;
00527   DST_TYPE(spec) = 1;
00528   DST_HANDLE(spec) = info->handle.ems_handle;
00529   DST_PAGE(spec)   = (unsigned short) (file_offset / EMSPAGESIZE);
00530   DST_OFFSET(spec) = (unsigned short) (file_offset % EMSPAGESIZE);
00531   
00532   ctx.ds_si = (void far *) & spec;
00533   ctx.ax = 0x5700;              
00534   jems_calldriver((EMScontext far *) & ctx);
00535   if (HIBYTE(ctx.ax) != 0)
00536     ERREXIT(cinfo, JERR_EMS_WRITE);
00537 }
00538 
00539 
00540 METHODDEF(void)
00541 close_ems_store (j_common_ptr cinfo, backing_store_ptr info)
00542 {
00543   EMScontext ctx;
00544 
00545   ctx.ax = 0x4500;
00546   ctx.dx = info->handle.ems_handle;
00547   jems_calldriver((EMScontext far *) & ctx);
00548   TRACEMS1(cinfo, 1, JTRC_EMS_CLOSE, info->handle.ems_handle);
00549   
00550 }
00551 
00552 
00553 LOCAL(boolean)
00554 open_ems_store (j_common_ptr cinfo, backing_store_ptr info,
00555                 long total_bytes_needed)
00556 {
00557   EMScontext ctx;
00558 
00559   
00560   if (! jems_available())
00561     return FALSE;
00562 
00563   
00564   ctx.ax = 0x4000;
00565   jems_calldriver((EMScontext far *) & ctx);
00566   if (HIBYTE(ctx.ax) != 0)
00567     return FALSE;
00568 
00569   
00570   ctx.ax = 0x4600;
00571   jems_calldriver((EMScontext far *) & ctx);
00572   if (HIBYTE(ctx.ax) != 0 || LOBYTE(ctx.ax) < 0x40)
00573     return FALSE;
00574 
00575   
00576   ctx.ax = 0x4300;
00577   ctx.bx = (unsigned short) ((total_bytes_needed + EMSPAGESIZE-1L) / EMSPAGESIZE);
00578   jems_calldriver((EMScontext far *) & ctx);
00579   if (HIBYTE(ctx.ax) != 0)
00580     return FALSE;
00581 
00582   
00583   info->handle.ems_handle = ctx.dx;
00584   info->read_backing_store = read_ems_store;
00585   info->write_backing_store = write_ems_store;
00586   info->close_backing_store = close_ems_store;
00587   TRACEMS1(cinfo, 1, JTRC_EMS_OPEN, ctx.dx);
00588   return TRUE;                  
00589 }
00590 
00591 #endif 
00592 
00593 
00594 
00595 
00596 
00597 
00598 GLOBAL(void)
00599 jpeg_open_backing_store (j_common_ptr cinfo, backing_store_ptr info,
00600                          long total_bytes_needed)
00601 {
00602   
00603 #if XMS_SUPPORTED
00604   if (open_xms_store(cinfo, info, total_bytes_needed))
00605     return;
00606 #endif
00607 #if EMS_SUPPORTED
00608   if (open_ems_store(cinfo, info, total_bytes_needed))
00609     return;
00610 #endif
00611   if (open_file_store(cinfo, info, total_bytes_needed))
00612     return;
00613   ERREXITS(cinfo, JERR_TFILE_CREATE, "");
00614 }
00615 
00616 
00617 
00618 
00619 
00620 
00621 
00622 GLOBAL(long)
00623 jpeg_mem_init (j_common_ptr cinfo)
00624 {
00625   next_file_num = 0;            
00626   return DEFAULT_MAX_MEM;       
00627 }
00628 
00629 GLOBAL(void)
00630 jpeg_mem_term (j_common_ptr cinfo)
00631 {
00632   
00633 
00634 
00635 #ifdef NEED_FHEAPMIN
00636   _fheapmin();
00637 #endif
00638 }