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