00001
00002
00003
00004
00005
00006
00007
00008
00014 #include "edtinc.h"
00015 #include "errno.h"
00016 #include "libdvu.h"
00017
00018
00019 #define DVUFATAL PDVLIB_MSG_FATAL
00020
00021 #ifndef WIN32
00022 #define DWORD unsigned int
00023 #define LONG int
00024 #define WORD unsigned short
00025 #define BYTE unsigned char
00026 #endif
00027
00028 #ifndef _rasterfile_h
00029
00030 struct rasterfile
00031 {
00032 int ras_magic;
00033 int ras_width;
00034 int ras_height;
00035 int ras_depth;
00036 int ras_length;
00037 int ras_type;
00038 int ras_maptype;
00039 int ras_maplength;
00040
00041 };
00042
00043 #define RAS_MAGIC 0x59a66a95
00044 #define RT_STANDARD 1
00045 #define RMT_EQUAL_RGB 1
00046 #define RMT_NONE 0
00047 #endif
00048
00049 static u_short *slookup = NULL ;
00050 static u_char *blookup = NULL ;
00051 static int *hist = NULL ;
00052
00053 static void free_cast_tbl();
00054 void dvu_perror(char *str);
00055
00056 extern int Pdv_debug;
00057
00058 static u_char *Cast_tbl = NULL;
00059 static u_char *create_cast_tbl();
00060
00061 static int write_sun_long (int l, FILE *fp)
00062 {
00063 char c;
00064
00065 c = ((l >> 24) & 0xff);
00066 if (putc (c, fp) == EOF) return (EOF);
00067 c = ((l >> 16) & 0xff);
00068 if (putc (c, fp) == EOF) return (EOF);
00069 c = ((l >> 8) & 0xff);
00070 if (putc (c, fp) == EOF) return (EOF);
00071 c = (l & 0xff);
00072 if (putc (c, fp) == EOF) return (EOF);
00073 return (0);
00074 }
00075
00094 static int i_am_big_endian()
00095 {
00096 static int magic = 0x33221100;
00097 static const char *is_big_endian = (const char *) &magic;
00098
00099 return *is_big_endian != 0;
00100 }
00101
00116 static void change_endian(long *lp, int n)
00117 {
00118 int bytes = 4 * n;
00119 char *cp = (char *) lp;
00120 int i;
00121
00122 for (i = 0; i < bytes; i += 4) {
00123 char tmp;
00124
00125 tmp = cp[0];
00126 cp[0] = cp[3];
00127 cp[3] = tmp;
00128
00129 tmp = cp[1];
00130 cp[1] = cp[2];
00131 cp[2] = tmp;
00132 }
00133 }
00134
00148 static int fwrite_sun_long(const void *buf, int size, int count, FILE *fp)
00149 {
00150 const long *ibuf = (const long *) buf;
00151 int numlongs = size * count / 4;
00152 int i;
00153
00154 for (i = 0; i < numlongs; i++)
00155 write_sun_long(ibuf[i], fp);
00156
00157 return count;
00158 }
00159
00172 static int fread_sun_long(void *buf, int size, int count, FILE *fp)
00173 {
00174 int numlongs = size * count / 4;
00175 size_t numread = fread(buf, size, count, fp);
00176
00177
00178 if (!i_am_big_endian())
00179 change_endian((long *) buf, numlongs);
00180
00181 return numread;
00182 }
00183
00196 int
00197 dvu_write_rasfile(char *fname, u_char *addr, int x_size, int y_size)
00198 {
00199 struct rasterfile ras;
00200 u_char colors[256];
00201 FILE *fp;
00202 int i;
00203 int rowsize ;
00204
00205 if ((fp = fopen(fname,"wb")) == NULL)
00206 {
00207 dvu_perror(fname) ;
00208 return(-1) ;
00209 }
00210
00211 rowsize = x_size ;
00212 if(rowsize & 1)
00213 {
00214 rowsize++ ;
00215 }
00216 ras.ras_magic = RAS_MAGIC;
00217 ras.ras_width = x_size;
00218 ras.ras_height = y_size;
00219 ras.ras_depth = 8;
00220 ras.ras_length = x_size * y_size;
00221 ras.ras_type = RT_STANDARD;
00222 ras.ras_maptype = RMT_EQUAL_RGB;
00223 ras.ras_maplength = 256 * 3;
00224
00225 write_sun_long(ras.ras_magic, fp) ;
00226 write_sun_long(ras.ras_width, fp) ;
00227 write_sun_long(ras.ras_height, fp) ;
00228 write_sun_long(ras.ras_depth, fp) ;
00229 write_sun_long(ras.ras_length, fp) ;
00230 write_sun_long(ras.ras_type, fp) ;
00231 write_sun_long(ras.ras_maptype, fp) ;
00232 write_sun_long(ras.ras_maplength, fp) ;
00233
00234
00235 for (i = 0; i < 256; i++)
00236 colors[i] = i;
00237 fwrite(colors, sizeof(colors), 1, fp);
00238 fwrite(colors, sizeof(colors), 1, fp);
00239 fwrite(colors, sizeof(colors), 1, fp);
00240
00241 if (Pdv_debug) printf("before write %d %d\n",x_size,y_size*3) ;
00242 for(i = 0; i < y_size ; i++)
00243 {
00244 fwrite(addr, rowsize, 1, fp);
00245 addr += x_size ;
00246 }
00247 fclose(fp);
00248 return(0) ;
00249 }
00250
00265 int
00266 dvu_write_rasfile16(char *fname, u_char *addr, int x_size, int y_size, int depth_bits)
00267
00268 {
00269 struct rasterfile ras;
00270 u_char colors[256];
00271 u_char *scanline;
00272 u_short *shortp;
00273 FILE *fp;
00274 int i, j;
00275 int rowsize ;
00276 int ret;
00277 int mask = 0;
00278
00279 for (i=0; i<depth_bits; i++)
00280 mask |= 1 << i;
00281
00282 if ((fp = fopen(fname,"wb")) == NULL)
00283 {
00284 dvu_perror(fname) ;
00285 return(-1) ;
00286 }
00287
00288 if (Cast_tbl == NULL)
00289 Cast_tbl = create_cast_tbl(depth_bits, 256);
00290
00291
00292 if (Pdv_debug) printf("writing rasterfile header to %s\n", fname);
00293 if (Pdv_debug) printf("x %d y %d addr %p name %s\n", x_size, y_size, addr, fname);
00294 rowsize = x_size ;
00295 if(rowsize & 1)
00296 {
00297 rowsize++ ;
00298 }
00299 ras.ras_magic = RAS_MAGIC;
00300 ras.ras_width = x_size;
00301 ras.ras_height = y_size;
00302 ras.ras_depth = 8;
00303 ras.ras_length = x_size * y_size;
00304 ras.ras_type = RT_STANDARD;
00305 ras.ras_maptype = RMT_EQUAL_RGB;
00306 ras.ras_maplength = 256 * 3;
00307
00308 scanline = (u_char *)malloc(x_size * sizeof(short));
00309
00310 if ((ret = fwrite_sun_long(&ras, sizeof(ras), 1, fp)) != 1)
00311 goto err_ret;
00312
00313 for (i = 0; i < 256; i++)
00314 colors[i] = i;
00315
00316 if (fwrite(colors, sizeof(colors), 1, fp) != 1)
00317 goto err_ret;
00318 if (fwrite(colors, sizeof(colors), 1, fp) != 1)
00319 goto err_ret;
00320 if (fwrite(colors, sizeof(colors), 1, fp) != 1)
00321 goto err_ret;
00322
00323
00324 shortp = (u_short *)addr;
00325 for(i=0; i<y_size ; i++)
00326 {
00327 for (j=0; j<x_size; j++)
00328 scanline[j] = Cast_tbl[(*shortp++) & mask];
00329 if ((ret = fwrite(scanline, rowsize, 1, fp)) != 1)
00330 goto err_ret;
00331 }
00332 fclose(fp);
00333 free(scanline);
00334 free_cast_tbl();
00335 return 0;
00336
00337 err_ret:
00338 ret = errno;
00339 fclose(fp);
00340 free(scanline);
00341 free_cast_tbl();
00342 return ret;
00343 }
00344
00345 int
00346 dvu_write_window(char *fname, dvu_window *w)
00347 {
00348 struct rasterfile ras;
00349 u_char colors[256];
00350 FILE *fp;
00351 int i;
00352 int rowsize ;
00353 int x_size ;
00354 int y_size ;
00355 int bytes ;
00356 dvu_window *tmpi = 0 ;
00357
00358 if ((fp = fopen(fname,"wb")) == NULL)
00359 {
00360 dvu_perror(fname) ;
00361 return(-1) ;
00362 }
00363
00364 bytes = (w->depth + 7) / 8 ;
00365 x_size = w->right - w->left + 1 ;
00366 y_size = w->bottom - w->top + 1 ;
00367
00368 if (bytes == 3)
00369 {
00370 if (Pdv_debug)
00371 printf("dvu_write_window does not yet support 24 bit images\n") ;
00372 return(-1) ;
00373 }
00374 if (bytes == 2)
00375 {
00376 tmpi = (dvu_window *)
00377 dvu_init_window(NULL, 0, 0, x_size, y_size, x_size, y_size, 8) ;
00378
00379 dvu_winscale(w, tmpi, 0, 255, 1) ;
00380 w = tmpi ;
00381 }
00382 rowsize = x_size ;
00383 if(rowsize & 1)
00384 {
00385 rowsize++ ;
00386 }
00387 ras.ras_magic = RAS_MAGIC;
00388 ras.ras_width = x_size;
00389 ras.ras_height = y_size;
00390 ras.ras_depth = 8;
00391 ras.ras_length = x_size * y_size;
00392 ras.ras_type = RT_STANDARD;
00393 ras.ras_maptype = RMT_EQUAL_RGB;
00394 ras.ras_maplength = 256 * 3;
00395
00396 fwrite_sun_long(&ras, sizeof(ras), 1, fp);
00397
00398 for (i = 0; i < 256; i++)
00399 colors[i] = i;
00400 fwrite(colors, sizeof(colors), 1, fp);
00401 fwrite(colors, sizeof(colors), 1, fp);
00402 fwrite(colors, sizeof(colors), 1, fp);
00403
00404 if (Pdv_debug) printf("before write %d %d\n",x_size,y_size*3) ;
00405 for(i = 0; i < y_size ; i++)
00406 {
00407 fwrite(&w->mat[i + w->top][w->left], rowsize, 1, fp);
00408 }
00409 fclose(fp);
00410 if (tmpi)
00411 {
00412 dvu_free_window(tmpi) ;
00413 free(tmpi->data) ;
00414 }
00415 return(0) ;
00416 }
00417
00418 dvu_window *
00419 dvu_read_window(char *fname)
00420 {
00421 struct rasterfile ras;
00422 FILE *fp;
00423 int i;
00424 int rowsize ;
00425 int x_size ;
00426 int y_size ;
00427 int depth ;
00428 int bytes ;
00429 size_t ret;
00430 dvu_window *s ;
00431
00432 if ((fp = fopen(fname,"r")) == NULL)
00433 {
00434 dvu_perror(fname) ;
00435 return(0) ;
00436 }
00437
00438 fread_sun_long(&ras, sizeof(ras), 1, fp);
00439 if (ras.ras_magic != RAS_MAGIC)
00440 {
00441 edt_msg(
00442 DVUFATAL,
00443 "%s not a sun raster file - exiting\n", fname);
00444 return(0) ;
00445 }
00446
00447 x_size = ras.ras_width ;
00448 y_size = ras.ras_height ;
00449 depth = ras.ras_depth ;
00450 bytes = (depth + 7) / 8 ;
00451
00452 rowsize = x_size * bytes ;
00453 if(rowsize & 1)
00454 {
00455 rowsize++ ;
00456 }
00457
00458 fseek(fp, ras.ras_maplength, 1) ;
00459
00460 s = (dvu_window *) dvu_init_window(NULL, 0, 0, x_size, y_size, rowsize, y_size, depth) ;
00461
00462 for(i = 0; i < y_size ; i++)
00463 {
00464 ret = fread(s->mat[i], rowsize, 1, fp) ;
00465 }
00466 fclose(fp);
00467 return(s) ;
00468 }
00469
00493 int
00494 dvu_write_image(char *fname, u_char *addr, int x_size, int y_size,int istride)
00495 {
00496 struct rasterfile ras;
00497 u_char colors[256];
00498 FILE *fp;
00499 int i;
00500 int rowsize ;
00501
00502 if ((fp = fopen(fname,"wb")) == NULL)
00503 {
00504 dvu_perror(fname) ;
00505 return(-1) ;
00506 }
00507
00508 rowsize = x_size ;
00509 if(rowsize & 1)
00510 {
00511 rowsize++ ;
00512 }
00513 ras.ras_magic = RAS_MAGIC;
00514 ras.ras_width = x_size;
00515 ras.ras_height = y_size;
00516 ras.ras_depth = 8;
00517 ras.ras_length = x_size * y_size;
00518 ras.ras_type = RT_STANDARD;
00519 ras.ras_maptype = RMT_EQUAL_RGB;
00520 ras.ras_maplength = 256 * 3;
00521
00522 fwrite_sun_long(&ras, sizeof(ras), 1, fp);
00523
00524 for (i = 0; i < 256; i++)
00525 colors[i] = i;
00526 fwrite(colors, sizeof(colors), 1, fp);
00527 fwrite(colors, sizeof(colors), 1, fp);
00528 fwrite(colors, sizeof(colors), 1, fp);
00529
00530 for(i = 0; i < y_size ; i++)
00531 {
00532 fwrite(addr, rowsize, 1, fp);
00533 addr += istride ;
00534 }
00535 fclose(fp);
00536 return(0) ;
00537 }
00538
00539
00552 int
00553 dvu_write_rasfile24(char *fname, u_char *addr, int x_size, int y_size)
00554 {
00555 struct rasterfile ras;
00556 FILE *fp;
00557 int rowsize ;
00558 int ret ;
00559
00560 if ((fp = fopen(fname,"wb")) == NULL)
00561 {
00562 dvu_perror(fname) ;
00563 return(-1) ;
00564 }
00565
00566 rowsize = x_size ;
00567 if(rowsize & 1)
00568 {
00569 rowsize++ ;
00570 }
00571 ras.ras_magic = RAS_MAGIC;
00572 ras.ras_width = x_size;
00573 ras.ras_height = y_size;
00574 ras.ras_depth = 24;
00575 ras.ras_length = x_size * y_size;
00576 ras.ras_type = RT_STANDARD;
00577 ras.ras_maptype = RMT_NONE ;
00578 ras.ras_maplength = 0 ;
00579
00580 fwrite_sun_long(&ras, sizeof(ras), 1, fp);
00581 if (Pdv_debug)
00582 printf("before write %d %d\n",x_size,y_size*3) ;
00583 ret = (int) fwrite(addr, x_size, y_size*3, fp);
00584 if(Pdv_debug)
00585 printf("done ret %d\n",ret) ;
00586 fclose(fp);
00587 return(0) ;
00588 }
00589
00618 int
00619 dvu_write_image24(char *fname, u_char *addr, int x_size, int y_size, int istride)
00620 {
00621 struct rasterfile ras;
00622 FILE *fp;
00623 int y ;
00624
00625 if ((fp = fopen(fname,"wb")) == NULL)
00626 {
00627 dvu_perror(fname) ;
00628 return(-1) ;
00629 }
00630
00631 ras.ras_magic = RAS_MAGIC;
00632 ras.ras_width = x_size;
00633 ras.ras_height = y_size;
00634 ras.ras_depth = 24;
00635 ras.ras_length = x_size * y_size;
00636 ras.ras_type = RT_STANDARD;
00637 ras.ras_maptype = RMT_NONE ;
00638 ras.ras_maplength = 0 ;
00639
00640 fwrite_sun_long(&ras, sizeof(ras), 1, fp);
00641 for(y = 0 ; y < y_size ; y++)
00642 {
00643 fwrite(addr, x_size*3, 1, fp);
00644 addr += istride*3 ;
00645 }
00646 fclose(fp);
00647 return(0) ;
00648 }
00649
00650
00651 static double wscale ;
00652 static int wmin ;
00653 static int wmax ;
00654 static u_char w2byte[4096] ;
00655
00656
00657 int
00658 dvu_wordscale(u_short *words, u_char *bytes, int count,
00659 int minbyte, int maxbyte, int doinit)
00660 {
00661 int i ;
00662 if (doinit)
00663 {
00664 wmin = words[0] ;
00665 wmax = words[0] ;
00666 for(i = 0 ; i < count ; i++)
00667 {
00668 if (words[i] < wmin) wmin = words[i] ;
00669 if (words[i] > wmax) wmax = words[i] ;
00670 }
00671 if (wmax == wmin)
00672 {
00673 if (Pdv_debug)
00674 printf("wordscale - no range in input image - all words %d\n",wmax) ;
00675 return(-1) ;
00676 }
00677 wscale = (float)(maxbyte - minbyte)/(float)(wmax - wmin) ;
00678
00679 for(i = 0 ; i < 4096 ; i++)
00680 {
00681 if (i < wmin) w2byte[i] = minbyte ;
00682 else if (i > wmax) w2byte[i] = maxbyte ;
00683 w2byte[i] = (u_char)((float)(i - wmin) * wscale + minbyte) ;
00684 }
00685 }
00686 for(i = 0 ; i < count ; i++)
00687 {
00688 bytes[i] = (u_char)w2byte[words[i]] ;
00689 }
00690 return(0) ;
00691 }
00692
00693
00694 int
00695 dvu_winscale(dvu_window *wi, dvu_window *bi, int minbyte, int maxbyte, int doinit)
00696 {
00697 int y, x ;
00698 int toy, tox ;
00699 u_short tmp ;
00700 int i ;
00701 if (doinit)
00702 {
00703 wmax = wmin = wi->mat16[wi->top][wi->left] ;
00704 for(y = wi->top ; y <= wi->bottom ; y++)
00705 {
00706 for(x = wi->left ; x <= wi->right ; x++)
00707 {
00708 tmp = wi->mat16[y][x] ;
00709 if (tmp < wmin) wmin = tmp ;
00710 if (tmp > wmax) wmax = tmp ;
00711 }
00712 }
00713 if (wmax == wmin)
00714 {
00715 printf("wordscale - no range in input image - all words %d\n",wmax) ;
00716 return(-1) ;
00717 }
00718 wscale = (float)(maxbyte - minbyte)/(float)(wmax - wmin) ;
00719
00720 for(i = 0 ; i < 4096 ; i++)
00721 {
00722 if (i < wmin) w2byte[i] = minbyte ;
00723 else if (i > wmax) w2byte[i] = maxbyte ;
00724 w2byte[i] = (u_char )((float)(i - wmin) * wscale + minbyte) ;
00725 }
00726 }
00727 toy = bi->top ;
00728 for(y = wi->top ; y <= wi->bottom ; y++)
00729 {
00730 tox = bi->left ;
00731 for(x = wi->left ; x <= wi->right ; x++)
00732 {
00733 bi->mat[toy][tox] = (u_char)w2byte[wi->mat16[y][x]] ;
00734 tox++ ;
00735 }
00736 toy++ ;
00737 }
00738 return(0) ;
00739 }
00740
00741 static int
00742 init_lookup(int depth)
00743 {
00744 int ncolors = 1 << depth ;
00745 int i ;
00746 if (Pdv_debug)
00747 printf("init_lookup %d bit %d entries\n", depth,ncolors) ;
00748 if (!hist)
00749 {
00750 hist = (int *)malloc(ncolors * sizeof(int)) ;
00751 if (!hist)
00752 {
00753 printf("can't alloc mem for %d element histogram\n",ncolors) ;
00754 return(-1) ;
00755 }
00756 }
00757 if (depth > 8)
00758 {
00759 if (!slookup)
00760 slookup = (u_short *)malloc(ncolors * sizeof(u_short)) ;
00761 if (!slookup)
00762 {
00763 printf("can't alloc mem for %d element lookup\n",ncolors) ;
00764 return(-1) ;
00765 }
00766 for (i = 0 ; i < ncolors ; i++)
00767 {
00768 slookup[i] = i ;
00769 hist[i] = 0 ;
00770 }
00771 }
00772 else
00773 {
00774 if (!blookup)
00775 blookup = (u_char *)malloc(ncolors * sizeof(u_char)) ;
00776 if (!blookup)
00777 {
00778 printf("can't alloc mem for %d element lookup\n",ncolors) ;
00779 return(-1) ;
00780 }
00781 for (i = 0 ; i < ncolors ; i++)
00782 {
00783 blookup[i] = i ;
00784 hist[i] = 0 ;
00785 }
00786 }
00787 return(0) ;
00788 }
00789
00790
00799 int
00800 dvu_histeq(u_char *src, u_char *dst, int size, int depth)
00801 {
00802 int i ;
00803 unsigned long total;
00804 double intermediate ;
00805 int ncolors = 1 << depth ;
00806 int ret ;
00807
00808 if(Pdv_debug) printf("dvu_histeq %p %p %d %d\n",src,dst,size,depth) ;
00809
00810 if ((ret = init_lookup(depth))) return(ret) ;
00811
00812
00813 total = 0;
00814 if (depth > 8)
00815 {
00816 u_short *s ;
00817 s = (u_short *)src ;
00818 for (i = 0 ; i < size ; i++) hist[*s++]++ ;
00819 for (i = 0 ; i < ncolors ; i++)
00820 {
00821 total += hist[i];
00822 intermediate = total ;
00823 intermediate *= (ncolors - 1) ;
00824 intermediate /= size ;
00825 slookup[i] = (u_short)intermediate ;
00826 }
00827 }
00828 else
00829 {
00830 u_char *s ;
00831 s = (u_char *)src ;
00832 for (i = 0 ; i < size ; i++) hist[*s++]++ ;
00833 for (i = 0 ; i < ncolors ; i++)
00834 {
00835 total += hist[i];
00836 blookup[i] = (u_char)((total * (ncolors - 1)) / size) ;
00837 }
00838 }
00839 dvu_lookup(src,dst,size,depth) ;
00840 return(0) ;
00841 }
00842
00843
00844
00845 int
00846 dvu_load_lookup(char *filename,int depth)
00847 {
00848 FILE *ltab ;
00849 int index, val ;
00850 int ncolors = 1 << depth ;
00851 int ret ;
00852
00853 if ((ret = init_lookup(depth))) return(ret) ;
00854
00855 if (Pdv_debug)
00856 printf("loading lookup from %s\n",filename) ;
00857
00858 if ((ltab = fopen(filename,"r")) == NULL)
00859 {
00860 fprintf(stderr, "can't open %s for lookup table\n",filename) ;
00861 return(-1) ;
00862 }
00863 index = 0 ;
00864 while(index < ncolors && (fscanf(ltab,"%d",&val)))
00865 {
00866 if (depth > 8)
00867 slookup[index++] = val ;
00868 else
00869 blookup[index++] = val ;
00870 }
00871 if (Pdv_debug)
00872 printf("read %d values\n",index) ;
00873 fclose(ltab) ;
00874 return(0) ;
00875 }
00876
00877 int
00878 dvu_save_lookup(char *filename,int depth)
00879 {
00880 FILE *ltab ;
00881 int ret ;
00882 int i ;
00883 int ncolors = 1 << depth ;
00884 if (Pdv_debug)
00885 printf("saving lookup to %s\n",filename) ;
00886
00887 if (!blookup && !slookup)
00888 if ((ret = init_lookup(depth)))
00889 return(ret) ;
00890
00891 if (!(ltab = fopen(filename,"wb")))
00892 {
00893 edt_msg_printf_perror(
00894 DVUFATAL,
00895 "Can't open '%s' for lookup table",
00896 filename);
00897 return(-1) ;
00898 }
00899
00900 if (Pdv_debug > 1)
00901 {
00902 if (depth > 8)
00903 for(i = 0 ; i < ncolors ; i++) printf(" %d (%d)\n",
00904 slookup[i],hist[i]) ;
00905 else
00906 for(i = 0 ; i < ncolors ; i++) printf(" %d (%d)\n",
00907 blookup[i],hist[i]) ;
00908 }
00909 if (depth > 8)
00910 for(i = 0 ; i < ncolors ; i++) fprintf(ltab," %d\n",
00911 slookup[i]) ;
00912 else
00913 for(i = 0 ; i < ncolors ; i++) fprintf(ltab," %d\n",
00914 blookup[i]) ;
00915 fclose(ltab) ;
00916 return(0) ;
00917 }
00918
00919 int
00920 dvu_lookup(u_char *src, u_char *dst, int size, int depth)
00921 {
00922 if (Pdv_debug)
00923 printf("dvu_lookup\n") ;
00924 if (depth > 8)
00925 {
00926 u_short *s ;
00927 u_short *d ;
00928 int i ;
00929 d = (u_short *)dst ;
00930 s = (u_short *)src ;
00931 for (i = 0 ; i < size ; i++)
00932 {
00933 *d++ = slookup[*s++] ;
00934 }
00935 }
00936 else
00937 {
00938 u_char *s ;
00939 u_char *d ;
00940 int i ;
00941 d = (u_char *)dst ;
00942 s = (u_char *)src ;
00943 for (i = 0 ; i < size ; i++)
00944 {
00945 *d++ = blookup[*s++] ;
00946 }
00947 }
00948 if (Pdv_debug)
00949 printf("dvu_lookup done\n") ;
00950
00951 return(0) ;
00952 }
00953
00963 int
00964 dvu_exp_histeq(u_char *src, u_char *dst, int size, int depth, int cutoff)
00965 {
00966 int i ;
00967 unsigned long total;
00968 int ncolors = 1 << depth ;
00969 int ret ;
00970 int min, max, distinct ;
00971 float inc ;
00972 float val ;
00973 int ival ;
00974
00975 if(Pdv_debug) printf("dvu_exp_histeq %p %p %d %d\n",src,dst,size,depth) ;
00976
00977 if ((ret = init_lookup(depth))) return(ret) ;
00978
00979
00980 total = 0;
00981 if (depth > 8)
00982 {
00983 u_short *s ;
00984 s = (u_short *)src ;
00985 for (i = 0 ; i < size ; i++) hist[*s++]++ ;
00986 }
00987 else
00988 {
00989 u_char *s ;
00990 s = (u_char *)src ;
00991 for (i = 0 ; i < size ; i++) hist[*s++]++ ;
00992 }
00993 for(i = 0 ; i < ncolors ; i++)
00994 {
00995 if (hist[i] >= cutoff)
00996 {
00997 min = i ;
00998 break ;
00999 }
01000 }
01001 for(i = ncolors-1 ; i >= 0; i--)
01002 {
01003 if (hist[i] >= cutoff)
01004 {
01005 max = i ;
01006 break ;
01007 }
01008 }
01009 distinct = 0 ;
01010 for(i = 0 ; i < ncolors ; i++)
01011 {
01012 if (hist[i] >= cutoff) distinct++ ;
01013 }
01014 if (Pdv_debug)
01015 printf("exp_histeq:min %d max %d distinct %d (with %d pixel cutoff)\n",
01016 min,max,distinct,cutoff) ;
01017 inc = (float)ncolors / (float)distinct ;
01018 val = 0.0 ;
01019 for (i = 0 ; i < ncolors ; i++)
01020 {
01021 ival = (int)(val + 0.5) ;
01022 if (hist[i] >= cutoff) val += inc ;
01023 if (Pdv_debug > 2) printf("%d (%d) %3.2f %d\n",
01024 i,hist[i],val,ival) ;
01025 if (depth > 8)
01026 slookup[i] = ival ;
01027 else
01028 blookup[i] = ival ;
01029 }
01030
01031 dvu_lookup(src,dst,size,depth) ;
01032 return(0) ;
01033 }
01034
01035 void
01036 dvu_free_tables()
01037 {
01038 if (slookup) free(slookup) ;
01039 if (hist) free(hist) ;
01040 }
01041
01042
01043
01044
01045
01046 dvu_window *
01047 dvu_init_window(u_char *data, int sx, int sy,
01048 int dx, int dy, int xdim, int ydim, int depth)
01049 {
01050 dvu_window *s ;
01051 int y ;
01052 int bytes ;
01053
01054 s = (dvu_window *) malloc(sizeof(dvu_window)) ;
01055 bytes = (depth + 7) / 8 ;
01056 if (!data) data = (u_char *)malloc(xdim*ydim*bytes) ;
01057
01058 s->left = sx ;
01059 s->right = sx + dx - 1 ;
01060 s->top = sy ;
01061 s->bottom = sy + dy - 1 ;
01062 s->xdim = xdim ;
01063 s->ydim = ydim ;
01064 s->depth = depth ;
01065 s->data = data ;
01066 s->mat = 0 ;
01067 s->mat16 = 0 ;
01068 s->mat24 = 0 ;
01069 switch(bytes)
01070 {
01071 case 1:
01072 s->mat = (u_char **) calloc(ydim,sizeof(u_char *)) ;
01073 for (y = 0 ; y < ydim ; y++)
01074 s->mat[y] = data + y * xdim ;
01075 break ;
01076 case 2:
01077 s->mat16 = (u_short **) calloc(ydim,sizeof(u_short *)) ;
01078 for (y = 0 ; y < ydim ; y++)
01079 s->mat16[y] = (u_short *)(data + y * xdim * 2) ;
01080 break ;
01081 case 3:
01082 s->mat24 = (bgrpoint **) calloc(ydim,sizeof(bgrpoint *)) ;
01083 for (y = 0 ; y < ydim ; y++)
01084 s->mat24[y] = (bgrpoint *)(data + y * xdim * 3) ;
01085 break ;
01086 }
01087 return(s) ;
01088 }
01089
01090
01091
01092
01093 dvu_window *
01094 dvu_reset_window(dvu_window *s, u_char *data, int sx, int sy, int dx, int dy)
01095 {
01096 register int y ;
01097 register int stride ;
01098 register int rows ;
01099 register int bytes ;
01100
01101 s->left = sx ;
01102 s->right = sx + dx - 1 ;
01103 s->top = sy ;
01104 s->bottom = sy + dy - 1 ;
01105 s->data = data ;
01106 rows = s->ydim ;
01107 stride = s->xdim ;
01108 bytes = (s->depth + 7) / 8 ;
01109 switch(bytes)
01110 {
01111 case 1:
01112 for (y = 0 ; y < rows ; y++)
01113 s->mat[y] = data + y * stride ;
01114 break ;
01115 case 2:
01116 for (y = 0 ; y < rows ; y++)
01117 s->mat16[y] = (u_short *)(data + y * stride * 2) ;
01118 break ;
01119 case 3:
01120 for (y = 0 ; y < rows ; y++)
01121 s->mat24[y] = (bgrpoint *)(data + y * stride * 3) ;
01122 break ;
01123 }
01124 return(s) ;
01125 }
01126
01127
01128
01129
01130 int
01131 dvu_free_window(dvu_window *w)
01132 {
01133 free(w->mat) ;
01134 free(w) ;
01135 return(0) ;
01136 }
01137
01138 int
01139 ten2one(u_short *wbuf, u_char *bbuf, int count)
01140 {
01141 dvu_word2byte(wbuf, bbuf, count, 10) ;
01142 return(0) ;
01143 }
01144
01145 int
01146 dvu_word2byte(u_short *wbuf, u_char *bbuf, int count, int depth)
01147 {
01148 register u_short *from, *end;
01149 register u_char *to;
01150 int shift = depth - 8 ;
01151
01152 from = wbuf;
01153 end = from + count;
01154 to = bbuf;
01155 while (from < end)
01156 {
01157 *to++ = *from++ >> shift;
01158 }
01159 return(0) ;
01160 }
01161
01162
01163
01164
01165 int
01166 dvu_word2byte_with_stride(u_short *wbuf, u_char *bbuf,
01167 int wstride, int bstride,
01168 int xsize, int ysize, int depth)
01169 {
01170 register u_short *from, *end;
01171 register u_char *to;
01172 register u_char *next_toptr;
01173 register u_short *next_fromptr;
01174 register u_short *end_fromptr;
01175 int shift = depth - 8 ;
01176
01177 next_fromptr = wbuf;
01178 next_toptr = bbuf;
01179 end_fromptr = wbuf + (xsize * ysize);
01180 while (next_fromptr < end_fromptr)
01181 {
01182 from = next_fromptr;
01183 to = next_toptr;
01184 end = next_fromptr + xsize;
01185
01186 while (from < end)
01187 *to++ = *from++ >> shift;
01188
01189 next_fromptr += wstride;
01190 next_toptr += bstride;
01191 }
01192 return(0) ;
01193 }
01194
01195
01196 void
01197 dvu_perror(char *str)
01198 {
01199 #ifdef _NT_
01200 LPVOID lpMsgBuf;
01201
01202 FormatMessage(
01203 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
01204 NULL,
01205 GetLastError(),
01206 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
01207 (LPTSTR) &lpMsgBuf,
01208 0,
01209 NULL
01210 );
01211
01212 fprintf(stderr, "%s: %s\n", str, lpMsgBuf) ;
01213 #else
01214 perror(str) ;
01215 #endif
01216 }
01217
01218
01219 static void putshort(FILE *fp, int i)
01220
01221 {
01222 int c, c1;
01223
01224 c = ((unsigned int ) i) & 0xff; c1 = (((unsigned int) i)>>8) & 0xff;
01225 putc(c, fp); putc(c1,fp);
01226 }
01227
01228
01229
01230 static void putint(FILE *fp, int i)
01231
01232 {
01233 int c, c1, c2, c3;
01234 c = ((unsigned int ) i) & 0xff;
01235 c1 = (((unsigned int) i)>>8) & 0xff;
01236 c2 = (((unsigned int) i)>>16) & 0xff;
01237 c3 = (((unsigned int) i)>>24) & 0xff;
01238
01239 putc(c, fp); putc(c1,fp); putc(c2,fp); putc(c3,fp);
01240 }
01241
01242
01243 #ifndef _NT_
01244 #define BI_RGB 0L
01245 #endif
01246
01268 int
01269 dvu_write_bmp(char *fname, u_char *buffer, int width, int height)
01270 {
01271 int w = width, h = height;
01272 FILE *fp ;
01273 int bperlin ;
01274 int nc = 256 ;
01275 int nbits = 8 ;
01276 int i,j,padw;
01277 u_char *pp;
01278
01279 if ((fp = fopen(fname,"wb")) == NULL)
01280 {
01281 dvu_perror(fname) ;
01282 return(-1) ;
01283 }
01284
01285 bperlin = ((w * nbits + 31) / 32) * 4;
01286
01287 putc('B', fp); putc('M', fp);
01288
01289
01290 i = 14 +
01291 40 +
01292 (nc * 4) +
01293 bperlin * h;
01294
01295 putint(fp, i);
01296 putshort(fp, 0);
01297 putshort(fp, 0);
01298 putint(fp, 14 + 40 + (nc * 4));
01299
01300 putint(fp, 40);
01301 putint(fp, w);
01302 putint(fp, h);
01303 putshort(fp, 1);
01304 putshort(fp, nbits);
01305 putint(fp, BI_RGB);
01306 putint(fp, bperlin*h);
01307 putint(fp, 75 * 39);
01308 putint(fp, 75 * 39);
01309 putint(fp, nc);
01310 putint(fp, nc);
01311
01312
01313
01314 for (i=0; i<nc; i++) {
01315 putc(i,fp);
01316 putc(i,fp);
01317 putc(i,fp);
01318 putc(0,fp);
01319 }
01320
01321
01322
01323
01324 padw = ((w + 3)/4) * 4;
01325
01326 for (i=h-1; i>=0; i--)
01327 {
01328 pp = buffer + (i * w);
01329
01330 for (j=0; j<w; j++) putc(*pp++, fp);
01331 for ( ; j<padw; j++) putc(0, fp);
01332 }
01333
01334 fclose(fp) ;
01335 return(0) ;
01336 }
01337
01338 #define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
01339
01340 #ifndef WIN32
01341
01342
01343 typedef struct tagBITMAPFILEHEADER {
01344 WORD bfType;
01345 DWORD bfSize;
01346 WORD bfReserved1;
01347 WORD bfReserved2;
01348 DWORD bfOffBits;
01349 }__attribute__((packed)) BITMAPFILEHEADER;
01350
01351
01352 typedef struct tagBITMAPCOREHEADER {
01353 DWORD bcSize;
01354 WORD bcWidth;
01355 WORD bcHeight;
01356 WORD bcPlanes;
01357 WORD bcBitCount;
01358 }__attribute__((packed)) BITMAPCOREHEADER ;
01359
01360
01361 typedef struct tagBITMAPINFOHEADER{
01362 DWORD biSize;
01363 LONG biWidth;
01364 LONG biHeight;
01365 WORD biPlanes;
01366 WORD biBitCount;
01367 DWORD biCompression;
01368 DWORD biSizeImage;
01369 LONG biXPelsPerMeter;
01370 LONG biYPelsPerMeter;
01371 DWORD biClrUsed;
01372 DWORD biClrImportant;
01373 }__attribute__((packed)) BITMAPINFOHEADER;
01374
01375
01376
01377 #define BI_RLE8 1L
01378 #define BI_RLE4 2L
01379 #define BI_BITFIELDS 3L
01380
01381 typedef struct tagRGBQUAD {
01382 BYTE rgbBlue;
01383 BYTE rgbGreen;
01384 BYTE rgbRed;
01385 BYTE rgbReserved;
01386 }__attribute__((packed)) RGBQUAD, *LPRGBQUAD;
01387
01388 typedef struct tagBITMAPINFO {
01389 BITMAPINFOHEADER bmiHeader;
01390 RGBQUAD bmiColors[1];
01391 }__attribute__((packed)) BITMAPINFO;
01392
01393 #else
01394
01395 #endif
01396
01416 int
01417 dvu_write_bmp_24(char *fname, u_char *buffer, int width, int height)
01418
01419 {
01420 int w = width, h = height;
01421
01422 u_char *bp;
01423
01424 FILE *f;
01425 DWORD dwDIBSize;
01426
01427 DWORD dwBmBitsSize;
01428
01429 int nPadding;
01430 int widthbytes = w * 3;
01431
01432 int row;
01433
01434 BITMAPFILEHEADER bmfHdr;
01435
01436
01437 BITMAPINFO *pBMI = (BITMAPINFO *)
01438 malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
01439
01440
01441 BITMAPINFOHEADER* pBI = (BITMAPINFOHEADER*) pBMI;
01442 pBI->biSize = sizeof(BITMAPINFOHEADER);
01443 pBI->biWidth = w;
01444 pBI->biHeight = h;
01445 pBI->biPlanes = 1;
01446 pBI->biBitCount = 24;
01447 pBI->biCompression = BI_RGB;
01448 pBI->biSizeImage = 0;
01449 pBI->biXPelsPerMeter = 0;
01450 pBI->biYPelsPerMeter = 0;
01451 pBI->biClrUsed = 0;
01452 pBI->biClrImportant = 0;
01453
01454
01455
01456
01457
01458
01459 bmfHdr.bfType = 0x4D42;
01460
01461
01462
01463
01464
01465
01466 dwDIBSize = *(unsigned long *)pBMI ;
01467
01468 dwBmBitsSize = WIDTHBYTES(w * ((DWORD)pBMI->bmiHeader.biBitCount)) *
01469 h;
01470
01471 nPadding = WIDTHBYTES(w * ((DWORD)pBMI->bmiHeader.biBitCount)) -
01472 w * (3);
01473
01474 dwDIBSize += dwBmBitsSize;
01475
01476
01477
01478
01479 pBMI->bmiHeader.biSizeImage = dwBmBitsSize;
01480
01481
01482 bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
01483 bmfHdr.bfReserved1 = 0;
01484 bmfHdr.bfReserved2 = 0;
01485
01486
01487
01488
01489 bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) +
01490 pBMI->bmiHeader.biSize;
01491
01492
01493 if ((f = fopen(fname,"wb")) == NULL)
01494 {
01495 dvu_perror(fname) ;
01496 return(-1) ;
01497 }
01498
01499
01500 fwrite(&bmfHdr,1, sizeof(bmfHdr),f);
01501 fwrite(pBMI, 1, pBMI->bmiHeader.biSize,f);
01502
01503
01504 bp = buffer + (h-1) * (w *3);
01505
01506 for (row = h-1;row >= 0;row--, bp -= widthbytes)
01507 {
01508 fwrite(bp,1,w * 3,f);
01509 if (nPadding)
01510 fwrite(bp,1,nPadding,f);
01511 }
01512
01513
01514 fclose(f);
01515
01516 return 0;
01517 }
01518
01534 int
01535 dvu_write_raw(int imagesize, u_char *imagebuf, char *fname)
01536 {
01537 FILE *fd ;
01538 if ((fd = fopen(fname,"wb")) == NULL)
01539 {
01540 dvu_perror(fname) ;
01541 return(-1) ;
01542 }
01543
01544 fwrite(imagebuf,imagesize,1,fd) ;
01545 fclose(fd) ;
01546 return(0) ;
01547 }
01548
01549
01550 static u_char *
01551 create_cast_tbl(depth_bits, nents)
01552 int depth_bits, nents;
01553 {
01554 int i;
01555 u_char *tbl;
01556 float mult;
01557 float fmin=0.0;
01558 int ncolors = 1 << depth_bits;
01559
01560 mult = (float)255.0/(float)ncolors;
01561 if ((tbl = (u_char *)malloc(ncolors * sizeof(char))) == NULL)
01562 {
01563 printf("malloc for cast_tbl failed, size %d\n", ncolors);
01564 exit(0);
01565 }
01566
01567 for (i=0; i < ncolors; i++)
01568 {
01569 tbl[i] = (int)(fmin + ((mult * (float)i) + 0.5));
01570 }
01571
01572 if (Pdv_debug)
01573 {
01574 printf("Cast_tbl: depth (bytes) %d nents %d ncolors %d mult %1.2f\n",
01575 depth_bits, nents, ncolors, mult);
01576 printf("Cast_tbl %d: %d\n", 0, tbl[0]);
01577 printf("Cast_tbl %d: %d\n", ncolors/2, tbl[ncolors/2]);
01578 printf("Cast_tbl %d: %d\n", ncolors-1, tbl[ncolors-1]);
01579 }
01580
01581
01582
01583
01584 return tbl;
01585 }
01586
01587 static void
01588 free_cast_tbl()
01589 {
01590 free(Cast_tbl);
01591 Cast_tbl = NULL;
01592 }
01593
01594
01595
01596
01597
01598 void
01599 dvu_long_to_charbuf(unsigned int val, u_char *buf)
01600 {
01601 buf[0] = (u_char) ((val & 0xff000000) >> 24);
01602 buf[1] = (u_char) ((val & 0x00ff0000) >> 16);
01603 buf[2] = (u_char) ((val & 0x0000ff00) >> 8);
01604 buf[3] = (u_char) ((val & 0x000000ff) );
01605 }
01606
01608