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 int depth_bytes = ((int)depth_bits + 7) / 8;
00275
00276 for (i=0; i<depth_bits; i++)
00277 mask |= 1 << i;
00278
00279 if ((fp = fopen(fname, "wb")) == NULL) {
00280 edt_msg_printf_perror(
00281 DVUFATAL,
00282 "Can't open destination data file '%s' for writing",
00283 fname);
00284 return -1;
00285 }
00286
00287 if (Cast_tbl == NULL)
00288 Cast_tbl = create_cast_tbl(depth_bits, 256);
00289
00290
00291 if (Pdv_debug) printf("writing rasterfile header to %s\n", fname);
00292 if (Pdv_debug) printf("x %d y %d addr %p name %s\n", x_size, y_size, addr, fname);
00293 rowsize = x_size ;
00294 if(rowsize & 1)
00295 {
00296 rowsize++ ;
00297 }
00298 ras.ras_magic = RAS_MAGIC;
00299 ras.ras_width = x_size;
00300 ras.ras_height = y_size;
00301 ras.ras_depth = 8;
00302 ras.ras_length = x_size * y_size;
00303 ras.ras_type = RT_STANDARD;
00304 ras.ras_maptype = RMT_EQUAL_RGB;
00305 ras.ras_maplength = 256 * 3;
00306
00307 scanline = (u_char *)malloc(x_size * sizeof(short));
00308
00309 if ((ret = fwrite_sun_long(&ras, sizeof(ras), 1, fp)) != 1)
00310 goto err_ret;
00311
00312 for (i = 0; i < 256; i++)
00313 colors[i] = i;
00314
00315 if (fwrite(colors, sizeof(colors), 1, fp) != 1)
00316 goto err_ret;
00317 if (fwrite(colors, sizeof(colors), 1, fp) != 1)
00318 goto err_ret;
00319 if (fwrite(colors, sizeof(colors), 1, fp) != 1)
00320 goto err_ret;
00321
00322
00323 shortp = (u_short *)addr;
00324 for(i=0; i<y_size ; i++)
00325 {
00326 for (j=0; j<x_size; j++)
00327 scanline[j] = Cast_tbl[(*shortp++) & mask];
00328 if ((ret = fwrite(scanline, rowsize, 1, fp)) != 1)
00329 goto err_ret;
00330 }
00331 fclose(fp);
00332 free(scanline);
00333 free_cast_tbl();
00334 return 0;
00335
00336 err_ret:
00337 ret = errno;
00338 fclose(fp);
00339 free(scanline);
00340 free_cast_tbl();
00341 return ret;
00342 }
00343
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 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 edt_msg_printf_perror(
00505 DVUFATAL,
00506 "Can't open destination data file '%s' for writing",
00507 fname);
00508 return (-1);
00509 }
00510
00511 rowsize = x_size ;
00512 if(rowsize & 1)
00513 {
00514 rowsize++ ;
00515 }
00516 ras.ras_magic = RAS_MAGIC;
00517 ras.ras_width = x_size;
00518 ras.ras_height = y_size;
00519 ras.ras_depth = 8;
00520 ras.ras_length = x_size * y_size;
00521 ras.ras_type = RT_STANDARD;
00522 ras.ras_maptype = RMT_EQUAL_RGB;
00523 ras.ras_maplength = 256 * 3;
00524
00525 fwrite_sun_long(&ras, sizeof(ras), 1, fp);
00526
00527 for (i = 0; i < 256; i++)
00528 colors[i] = i;
00529 fwrite(colors, sizeof(colors), 1, fp);
00530 fwrite(colors, sizeof(colors), 1, fp);
00531 fwrite(colors, sizeof(colors), 1, fp);
00532
00533 for(i = 0; i < y_size ; i++)
00534 {
00535 fwrite(addr, rowsize, 1, fp);
00536 addr += istride ;
00537 }
00538 fclose(fp);
00539 return(0) ;
00540 }
00541
00542
00555 dvu_write_rasfile24(char *fname, u_char *addr, int x_size, int y_size)
00556 {
00557 struct rasterfile ras;
00558 FILE *fp;
00559 int rowsize ;
00560 int ret ;
00561
00562 if ((fp = fopen(fname, "wb")) == NULL)
00563 {
00564 edt_msg_printf_perror(
00565 DVUFATAL,
00566 "Can't open destination data file '%s' for writing",
00567 fname);
00568 return (-1);
00569 }
00570
00571 rowsize = x_size ;
00572 if(rowsize & 1)
00573 {
00574 rowsize++ ;
00575 }
00576 ras.ras_magic = RAS_MAGIC;
00577 ras.ras_width = x_size;
00578 ras.ras_height = y_size;
00579 ras.ras_depth = 24;
00580 ras.ras_length = x_size * y_size;
00581 ras.ras_type = RT_STANDARD;
00582 ras.ras_maptype = RMT_NONE ;
00583 ras.ras_maplength = 0 ;
00584
00585 fwrite_sun_long(&ras, sizeof(ras), 1, fp);
00586 if (Pdv_debug)
00587 printf("before write %d %d\n",x_size,y_size*3) ;
00588 ret = (int) fwrite(addr, x_size, y_size*3, fp);
00589 if(Pdv_debug)
00590 printf("done ret %d\n",ret) ;
00591 fclose(fp);
00592 return(0) ;
00593 }
00594
00623 dvu_write_image24(char *fname, u_char *addr, int x_size, int y_size, int istride)
00624 {
00625 struct rasterfile ras;
00626 FILE *fp;
00627 int y ;
00628
00629 if ((fp = fopen(fname, "wb")) == NULL)
00630 {
00631 edt_msg_printf_perror(
00632 DVUFATAL,
00633 "Can't open destination data file '%s' for writing",
00634 fname);
00635 return (-1);
00636 }
00637
00638 ras.ras_magic = RAS_MAGIC;
00639 ras.ras_width = x_size;
00640 ras.ras_height = y_size;
00641 ras.ras_depth = 24;
00642 ras.ras_length = x_size * y_size;
00643 ras.ras_type = RT_STANDARD;
00644 ras.ras_maptype = RMT_NONE ;
00645 ras.ras_maplength = 0 ;
00646
00647 fwrite_sun_long(&ras, sizeof(ras), 1, fp);
00648 for(y = 0 ; y < y_size ; y++)
00649 {
00650 fwrite(addr, x_size*3, 1, fp);
00651 addr += istride*3 ;
00652 }
00653 fclose(fp);
00654 return(0) ;
00655 }
00656
00657
00658 static double wscale ;
00659 static int wmin ;
00660 static int wmax ;
00661 static u_char w2byte[4096] ;
00662
00663
00664 dvu_wordscale(u_short *words, u_char *bytes, int count,
00665 int minbyte, int maxbyte, int doinit)
00666 {
00667 static int did_init = 0 ;
00668 int i ;
00669 if (doinit)
00670 {
00671 wmin = words[0] ;
00672 wmax = words[0] ;
00673 for(i = 0 ; i < count ; i++)
00674 {
00675 if (words[i] < wmin) wmin = words[i] ;
00676 if (words[i] > wmax) wmax = words[i] ;
00677 }
00678 if (wmax == wmin)
00679 {
00680 if (Pdv_debug)
00681 printf("wordscale - no range in input image - all words %d\n",wmax) ;
00682 return(-1) ;
00683 }
00684 wscale = (float)(maxbyte - minbyte)/(float)(wmax - wmin) ;
00685
00686 for(i = 0 ; i < 4096 ; i++)
00687 {
00688 if (i < wmin) w2byte[i] = minbyte ;
00689 else if (i > wmax) w2byte[i] = maxbyte ;
00690 w2byte[i] = (u_char)((float)(i - wmin) * wscale + minbyte) ;
00691 }
00692 }
00693 for(i = 0 ; i < count ; i++)
00694 {
00695 bytes[i] = (u_char)w2byte[words[i]] ;
00696 }
00697 return(0) ;
00698 }
00699
00700
00701 dvu_winscale(dvu_window *wi, dvu_window *bi, int minbyte, int maxbyte, int doinit)
00702 {
00703 static int did_init = 0 ;
00704 int y, x ;
00705 int toy, tox ;
00706 u_short tmp ;
00707 int i ;
00708 if (doinit)
00709 {
00710 wmax = wmin = wi->mat16[wi->top][wi->left] ;
00711 for(y = wi->top ; y <= wi->bottom ; y++)
00712 {
00713 for(x = wi->left ; x <= wi->right ; x++)
00714 {
00715 tmp = wi->mat16[y][x] ;
00716 if (tmp < wmin) wmin = tmp ;
00717 if (tmp > wmax) wmax = tmp ;
00718 }
00719 }
00720 if (wmax == wmin)
00721 {
00722 printf("wordscale - no range in input image - all words %d\n",wmax) ;
00723 return(-1) ;
00724 }
00725 wscale = (float)(maxbyte - minbyte)/(float)(wmax - wmin) ;
00726
00727 for(i = 0 ; i < 4096 ; i++)
00728 {
00729 if (i < wmin) w2byte[i] = minbyte ;
00730 else if (i > wmax) w2byte[i] = maxbyte ;
00731 w2byte[i] = (u_char )((float)(i - wmin) * wscale + minbyte) ;
00732 }
00733 }
00734 toy = bi->top ;
00735 for(y = wi->top ; y <= wi->bottom ; y++)
00736 {
00737 tox = bi->left ;
00738 for(x = wi->left ; x <= wi->right ; x++)
00739 {
00740 bi->mat[toy][tox] = (u_char)w2byte[wi->mat16[y][x]] ;
00741 tox++ ;
00742 }
00743 toy++ ;
00744 }
00745 return(0) ;
00746 }
00747
00748 static int
00749 init_lookup(int depth)
00750 {
00751 int ncolors = 1 << depth ;
00752 int i ;
00753 if (Pdv_debug)
00754 printf("init_lookup %d bit %d entries\n", depth,ncolors) ;
00755 if (!hist)
00756 {
00757 hist = (int *)malloc(ncolors * sizeof(int)) ;
00758 if (!hist)
00759 {
00760 printf("can't alloc mem for %d element histogram\n",ncolors) ;
00761 return(-1) ;
00762 }
00763 }
00764 if (depth > 8)
00765 {
00766 if (!slookup)
00767 slookup = (u_short *)malloc(ncolors * sizeof(u_short)) ;
00768 if (!slookup)
00769 {
00770 printf("can't alloc mem for %d element lookup\n",ncolors) ;
00771 return(-1) ;
00772 }
00773 for (i = 0 ; i < ncolors ; i++)
00774 {
00775 slookup[i] = i ;
00776 hist[i] = 0 ;
00777 }
00778 }
00779 else
00780 {
00781 if (!blookup)
00782 blookup = (u_char *)malloc(ncolors * sizeof(u_char)) ;
00783 if (!blookup)
00784 {
00785 printf("can't alloc mem for %d element lookup\n",ncolors) ;
00786 return(-1) ;
00787 }
00788 for (i = 0 ; i < ncolors ; i++)
00789 {
00790 blookup[i] = i ;
00791 hist[i] = 0 ;
00792 }
00793 }
00794 return(0) ;
00795 }
00796
00797
00806 dvu_histeq(u_char *src, u_char *dst, int size, int depth)
00807 {
00808 int i ;
00809 unsigned long total;
00810 double intermediate ;
00811 int ncolors = 1 << depth ;
00812 int ret ;
00813
00814 if(Pdv_debug) printf("dvu_histeq %p %p %d %d\n",src,dst,size,depth) ;
00815
00816 if (ret = init_lookup(depth)) return(ret) ;
00817
00818
00819 total = 0;
00820 if (depth > 8)
00821 {
00822 u_short *s ;
00823 s = (u_short *)src ;
00824 for (i = 0 ; i < size ; i++) hist[*s++]++ ;
00825 for (i = 0 ; i < ncolors ; i++)
00826 {
00827 total += hist[i];
00828 intermediate = total ;
00829 intermediate *= (ncolors - 1) ;
00830 intermediate /= size ;
00831 slookup[i] = (u_short)intermediate ;
00832 }
00833 }
00834 else
00835 {
00836 u_char *s ;
00837 s = (u_char *)src ;
00838 for (i = 0 ; i < size ; i++) hist[*s++]++ ;
00839 for (i = 0 ; i < ncolors ; i++)
00840 {
00841 total += hist[i];
00842 blookup[i] = (u_char)((total * (ncolors - 1)) / size) ;
00843 }
00844 }
00845 dvu_lookup(src,dst,size,depth) ;
00846 return(0) ;
00847 }
00848
00849
00850
00851 dvu_load_lookup(char *filename,int depth)
00852 {
00853 FILE *ltab ;
00854 int index, val ;
00855 int ncolors = 1 << depth ;
00856 int ret ;
00857
00858 if (ret = init_lookup(depth)) return(ret) ;
00859
00860 if (Pdv_debug)
00861 printf("loading lookup from %s\n",filename) ;
00862 if (!(ltab = fopen(filename,"r")))
00863 {
00864 printf("can't open %s for lookup table\n",filename) ;
00865 return(-1) ;
00866 }
00867 index = 0 ;
00868 while(index < ncolors && (fscanf(ltab,"%ld",&val)))
00869 {
00870 if (depth > 8)
00871 slookup[index++] = val ;
00872 else
00873 blookup[index++] = val ;
00874 }
00875 if (Pdv_debug) printf("read %d values\n",index) ;
00876 fclose(ltab) ;
00877 return(0) ;
00878 }
00879
00880 dvu_save_lookup(char *filename,int depth)
00881 {
00882 FILE *ltab ;
00883 int ret ;
00884 int i ;
00885 int ncolors = 1 << depth ;
00886 if (Pdv_debug)
00887 printf("saving lookup to %s\n",filename) ;
00888
00889 if (!blookup && !slookup)
00890 if (ret = init_lookup(depth)) return(ret) ;
00891
00892 if (!(ltab = fopen(filename,"wb")))
00893 {
00894 edt_msg_printf_perror(
00895 DVUFATAL,
00896 "Can't open '%s' for lookup table",
00897 filename);
00898 return(-1) ;
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 dvu_lookup(u_char *src, u_char *dst, int size, int depth)
00920 {
00921 if (Pdv_debug)
00922 printf("dvu_lookup\n") ;
00923 if (depth > 8)
00924 {
00925 u_short *s ;
00926 u_short *d ;
00927 int i ;
00928 d = (u_short *)dst ;
00929 s = (u_short *)src ;
00930 for (i = 0 ; i < size ; i++)
00931 {
00932 *d++ = slookup[*s++] ;
00933 }
00934 }
00935 else
00936 {
00937 u_char *s ;
00938 u_char *d ;
00939 int i ;
00940 d = (u_char *)dst ;
00941 s = (u_char *)src ;
00942 for (i = 0 ; i < size ; i++)
00943 {
00944 *d++ = blookup[*s++] ;
00945 }
00946 }
00947 if (Pdv_debug)
00948 printf("dvu_lookup done\n") ;
00949
00950 return(0) ;
00951 }
00952
00962 dvu_exp_histeq(u_char *src, u_char *dst, int size, int depth, int cutoff)
00963 {
00964 int i ;
00965 unsigned long total;
00966 int ncolors = 1 << depth ;
00967 int ret ;
00968 int min, max, distinct ;
00969 float inc ;
00970 float val ;
00971 int ival ;
00972
00973 if(Pdv_debug) printf("dvu_exp_histeq %p %p %d %d\n",src,dst,size,depth) ;
00974
00975 if (ret = init_lookup(depth)) return(ret) ;
00976
00977
00978 total = 0;
00979 if (depth > 8)
00980 {
00981 u_short *s ;
00982 s = (u_short *)src ;
00983 for (i = 0 ; i < size ; i++) hist[*s++]++ ;
00984 }
00985 else
00986 {
00987 u_char *s ;
00988 s = (u_char *)src ;
00989 for (i = 0 ; i < size ; i++) hist[*s++]++ ;
00990 }
00991 for(i = 0 ; i < ncolors ; i++)
00992 {
00993 if (hist[i] >= cutoff)
00994 {
00995 min = i ;
00996 break ;
00997 }
00998 }
00999 for(i = ncolors-1 ; i >= 0; i--)
01000 {
01001 if (hist[i] >= cutoff)
01002 {
01003 max = i ;
01004 break ;
01005 }
01006 }
01007 distinct = 0 ;
01008 for(i = 0 ; i < ncolors ; i++)
01009 {
01010 if (hist[i] >= cutoff) distinct++ ;
01011 }
01012 if (Pdv_debug)
01013 printf("exp_histeq:min %d max %d distinct %d (with %d pixel cutoff)\n",
01014 min,max,distinct,cutoff) ;
01015 inc = (float)ncolors / (float)distinct ;
01016 val = 0.0 ;
01017 for (i = 0 ; i < ncolors ; i++)
01018 {
01019 ival = (int)(val + 0.5) ;
01020 if (hist[i] >= cutoff) val += inc ;
01021 if (Pdv_debug > 2) printf("%d (%d) %3.2f %d\n",
01022 i,hist[i],val,ival) ;
01023 if (depth > 8)
01024 slookup[i] = ival ;
01025 else
01026 blookup[i] = ival ;
01027 }
01028
01029 dvu_lookup(src,dst,size,depth) ;
01030 return(0) ;
01031 }
01032
01033 void
01034 dvu_free_tables()
01035 {
01036 if (slookup) free(slookup) ;
01037 if (hist) free(hist) ;
01038 }
01039
01040
01041
01042
01043
01044 dvu_window *
01045 dvu_init_window(u_char *data, int sx, int sy,
01046 int dx, int dy, int xdim, int ydim, int depth)
01047 {
01048 dvu_window *s ;
01049 int y ;
01050 int bytes ;
01051
01052 s = (dvu_window *) malloc(sizeof(dvu_window)) ;
01053 bytes = (depth + 7) / 8 ;
01054 if (!data) data = (u_char *)malloc(xdim*ydim*bytes) ;
01055
01056 s->left = sx ;
01057 s->right = sx + dx - 1 ;
01058 s->top = sy ;
01059 s->bottom = sy + dy - 1 ;
01060 s->xdim = xdim ;
01061 s->ydim = ydim ;
01062 s->depth = depth ;
01063 s->data = data ;
01064 s->mat = 0 ;
01065 s->mat16 = 0 ;
01066 s->mat24 = 0 ;
01067 switch(bytes)
01068 {
01069 case 1:
01070 s->mat = (u_char **) calloc(ydim,sizeof(u_char *)) ;
01071 for (y = 0 ; y < ydim ; y++)
01072 s->mat[y] = data + y * xdim ;
01073 break ;
01074 case 2:
01075 s->mat16 = (u_short **) calloc(ydim,sizeof(u_short *)) ;
01076 for (y = 0 ; y < ydim ; y++)
01077 s->mat16[y] = (u_short *)(data + y * xdim * 2) ;
01078 break ;
01079 case 3:
01080 s->mat24 = (bgrpoint **) calloc(ydim,sizeof(bgrpoint *)) ;
01081 for (y = 0 ; y < ydim ; y++)
01082 s->mat24[y] = (bgrpoint *)(data + y * xdim * 3) ;
01083 break ;
01084 }
01085 return(s) ;
01086 }
01087
01088
01089
01090
01091 dvu_window *
01092 dvu_reset_window(dvu_window *s, u_char *data, int sx, int sy, int dx, int dy)
01093 {
01094 register int y ;
01095 register int stride ;
01096 register int rows ;
01097 register int bytes ;
01098
01099 s->left = sx ;
01100 s->right = sx + dx - 1 ;
01101 s->top = sy ;
01102 s->bottom = sy + dy - 1 ;
01103 s->data = data ;
01104 rows = s->ydim ;
01105 stride = s->xdim ;
01106 bytes = (s->depth + 7) / 8 ;
01107 switch(bytes)
01108 {
01109 case 1:
01110 for (y = 0 ; y < rows ; y++)
01111 s->mat[y] = data + y * stride ;
01112 break ;
01113 case 2:
01114 for (y = 0 ; y < rows ; y++)
01115 s->mat16[y] = (u_short *)(data + y * stride * 2) ;
01116 break ;
01117 case 3:
01118 for (y = 0 ; y < rows ; y++)
01119 s->mat24[y] = (bgrpoint *)(data + y * stride * 3) ;
01120 break ;
01121 }
01122 return(s) ;
01123 }
01124
01125
01126
01127
01128 dvu_free_window(dvu_window *w)
01129 {
01130 free(w->mat) ;
01131 free(w) ;
01132 return(0) ;
01133 }
01134
01135 ten2one(u_short *wbuf, u_char *bbuf, int count)
01136 {
01137 dvu_word2byte(wbuf, bbuf, count, 10) ;
01138 return(0) ;
01139 }
01140
01141 dvu_word2byte(u_short *wbuf, u_char *bbuf, int count, int depth)
01142 {
01143 register u_short *from, *end;
01144 register u_char *to;
01145 int shift = depth - 8 ;
01146
01147 from = wbuf;
01148 end = from + count;
01149 to = bbuf;
01150 while (from < end)
01151 {
01152 *to++ = *from++ >> shift;
01153 }
01154 return(0) ;
01155 }
01156
01157
01158
01159
01160 dvu_word2byte_with_stride(u_short *wbuf, u_char *bbuf,
01161 int wstride, int bstride,
01162 int xsize, int ysize, int depth)
01163 {
01164 register u_short *from, *end;
01165 register u_char *to;
01166 register u_char *next_toptr;
01167 register u_short *next_fromptr;
01168 register u_short *end_fromptr;
01169 int shift = depth - 8 ;
01170
01171 next_fromptr = wbuf;
01172 next_toptr = bbuf;
01173 end_fromptr = wbuf + (xsize * ysize);
01174 while (next_fromptr < end_fromptr)
01175 {
01176 from = next_fromptr;
01177 to = next_toptr;
01178 end = next_fromptr + xsize;
01179
01180 while (from < end)
01181 *to++ = *from++ >> shift;
01182
01183 next_fromptr += wstride;
01184 next_toptr += bstride;
01185 }
01186 return(0) ;
01187 }
01188
01189
01190 void
01191 dvu_perror(char *str)
01192 {
01193 #ifdef _NT_
01194 LPVOID lpMsgBuf;
01195
01196 FormatMessage(
01197 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
01198 NULL,
01199 GetLastError(),
01200 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
01201 (LPTSTR) &lpMsgBuf,
01202 0,
01203 NULL
01204 );
01205
01206 fprintf(stderr, "%s: %s\n", str, lpMsgBuf) ;
01207 #else
01208 perror(str) ;
01209 #endif
01210 }
01211
01212
01213 static void putshort(FILE *fp, int i)
01214
01215 {
01216 int c, c1;
01217
01218 c = ((unsigned int ) i) & 0xff; c1 = (((unsigned int) i)>>8) & 0xff;
01219 putc(c, fp); putc(c1,fp);
01220 }
01221
01222
01223
01224 static void putint(FILE *fp, int i)
01225
01226 {
01227 int c, c1, c2, c3;
01228 c = ((unsigned int ) i) & 0xff;
01229 c1 = (((unsigned int) i)>>8) & 0xff;
01230 c2 = (((unsigned int) i)>>16) & 0xff;
01231 c3 = (((unsigned int) i)>>24) & 0xff;
01232
01233 putc(c, fp); putc(c1,fp); putc(c2,fp); putc(c3,fp);
01234 }
01235
01236
01237 #ifndef _NT_
01238 #define BI_RGB 0L
01239 #endif
01240
01262 int
01263 dvu_write_bmp(char *fname, u_char *buffer, int width, int height)
01264 {
01265 int w = width, h = height;
01266 FILE *fp ;
01267 int bperlin ;
01268 int nc = 256 ;
01269 int nbits = 8 ;
01270 int i,j,padw;
01271 u_char *pp;
01272
01273 fp = fopen(fname,"wb") ;
01274 if (!fp) return(-1) ;
01275
01276 bperlin = ((w * nbits + 31) / 32) * 4;
01277
01278 putc('B', fp); putc('M', fp);
01279
01280
01281 i = 14 +
01282 40 +
01283 (nc * 4) +
01284 bperlin * h;
01285
01286 putint(fp, i);
01287 putshort(fp, 0);
01288 putshort(fp, 0);
01289 putint(fp, 14 + 40 + (nc * 4));
01290
01291 putint(fp, 40);
01292 putint(fp, w);
01293 putint(fp, h);
01294 putshort(fp, 1);
01295 putshort(fp, nbits);
01296 putint(fp, BI_RGB);
01297 putint(fp, bperlin*h);
01298 putint(fp, 75 * 39);
01299 putint(fp, 75 * 39);
01300 putint(fp, nc);
01301 putint(fp, nc);
01302
01303
01304
01305 for (i=0; i<nc; i++) {
01306 putc(i,fp);
01307 putc(i,fp);
01308 putc(i,fp);
01309 putc(0,fp);
01310 }
01311
01312
01313
01314
01315 padw = ((w + 3)/4) * 4;
01316
01317 for (i=h-1; i>=0; i--) {
01318 pp = buffer + (i * w);
01319
01320 for (j=0; j<w; j++) putc(*pp++, fp);
01321 for ( ; j<padw; j++) putc(0, fp);
01322 }
01323
01324 fclose(fp) ;
01325 return(0) ;
01326 }
01327
01328 #define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4)
01329
01330 #ifndef WIN32
01331
01332 #define DWORD unsigned long
01333 #define LONG long
01334 #define WORD unsigned short
01335 #define BYTE unsigned char
01336
01337
01338 typedef struct tagBITMAPFILEHEADER {
01339 WORD bfType;
01340 DWORD bfSize;
01341 WORD bfReserved1;
01342 WORD bfReserved2;
01343 DWORD bfOffBits;
01344 } BITMAPFILEHEADER;
01345
01346
01347 typedef struct tagBITMAPCOREHEADER {
01348 DWORD bcSize;
01349 WORD bcWidth;
01350 WORD bcHeight;
01351 WORD bcPlanes;
01352 WORD bcBitCount;
01353 } BITMAPCOREHEADER ;
01354
01355
01356 typedef struct tagBITMAPINFOHEADER{
01357 DWORD biSize;
01358 LONG biWidth;
01359 LONG biHeight;
01360 WORD biPlanes;
01361 WORD biBitCount;
01362 DWORD biCompression;
01363 DWORD biSizeImage;
01364 LONG biXPelsPerMeter;
01365 LONG biYPelsPerMeter;
01366 DWORD biClrUsed;
01367 DWORD biClrImportant;
01368 } BITMAPINFOHEADER;
01369
01370
01371
01372 #define BI_RLE8 1L
01373 #define BI_RLE4 2L
01374 #define BI_BITFIELDS 3L
01375
01376 typedef struct tagRGBQUAD {
01377 BYTE rgbBlue;
01378 BYTE rgbGreen;
01379 BYTE rgbRed;
01380 BYTE rgbReserved;
01381 } RGBQUAD, *LPRGBQUAD;
01382
01383 typedef struct tagBITMAPINFO {
01384 BITMAPINFOHEADER bmiHeader;
01385 RGBQUAD bmiColors[1];
01386 } BITMAPINFO;
01387
01388 #else
01389
01390 #endif
01391
01411 int
01412 dvu_write_bmp_24(char *fname, u_char *buffer, int width, int height)
01413
01414 {
01415 int w = width, h = height;
01416
01417 u_char *bp;
01418
01419 FILE *f;
01420 DWORD dwDIBSize;
01421
01422 DWORD dwBmBitsSize;
01423
01424 int nPadding;
01425 int widthbytes = w * 3;
01426
01427 int row;
01428
01429 BITMAPFILEHEADER bmfHdr;
01430
01431
01432 BITMAPINFO *pBMI = (BITMAPINFO *)
01433 malloc(sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
01434
01435
01436 BITMAPINFOHEADER* pBI = (BITMAPINFOHEADER*) pBMI;
01437 pBI->biSize = sizeof(BITMAPINFOHEADER);
01438 pBI->biWidth = w;
01439 pBI->biHeight = h;
01440 pBI->biPlanes = 1;
01441 pBI->biBitCount = 24;
01442 pBI->biCompression = BI_RGB;
01443 pBI->biSizeImage = 0;
01444 pBI->biXPelsPerMeter = 0;
01445 pBI->biYPelsPerMeter = 0;
01446 pBI->biClrUsed = 0;
01447 pBI->biClrImportant = 0;
01448
01449
01450
01451
01452
01453
01454 bmfHdr.bfType = 0x4D42;
01455
01456
01457
01458
01459
01460
01461 dwDIBSize = *(unsigned long *)pBMI ;
01462
01463 dwBmBitsSize = WIDTHBYTES(w * ((DWORD)pBMI->bmiHeader.biBitCount)) *
01464 h;
01465
01466 nPadding = WIDTHBYTES(w * ((DWORD)pBMI->bmiHeader.biBitCount)) -
01467 w * (3);
01468
01469 dwDIBSize += dwBmBitsSize;
01470
01471
01472
01473
01474 pBMI->bmiHeader.biSizeImage = dwBmBitsSize;
01475
01476
01477 bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
01478 bmfHdr.bfReserved1 = 0;
01479 bmfHdr.bfReserved2 = 0;
01480
01481
01482
01483
01484 bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) +
01485 pBMI->bmiHeader.biSize;
01486
01487
01488 f = fopen(fname, "wb");
01489
01490
01491
01492 fwrite(&bmfHdr,1, sizeof(bmfHdr),f);
01493 fwrite(pBMI, 1, pBMI->bmiHeader.biSize,f);
01494
01495
01496 bp = buffer + (h-1) * (w *3);
01497
01498 for (row = h-1;row >= 0;row--, bp -= widthbytes)
01499 {
01500 fwrite(bp,1,w * 3,f);
01501 if (nPadding)
01502 fwrite(bp,1,nPadding,f);
01503 }
01504
01505
01506 fclose(f);
01507
01508 return 0;
01509 }
01510
01526 int
01527 dvu_write_raw(int imagesize, u_char *imagebuf, char *fname)
01528 {
01529 FILE *fd ;
01530 if ((fd = fopen(fname,"wb")) == NULL)
01531 {
01532 dvu_perror(fname) ;
01533 return(-1) ;
01534 }
01535 fwrite(imagebuf,imagesize,1,fd) ;
01536 fclose(fd) ;
01537 return(0) ;
01538 }
01539
01540
01541 static u_char *
01542 create_cast_tbl(depth_bits, nents)
01543 int depth_bits, nents;
01544 {
01545 int i;
01546 u_char *tbl;
01547 float mult;
01548 float fmin=0.0;
01549 int ncolors = 1 << depth_bits;
01550
01551 mult = (float)255.0/(float)ncolors;
01552 if ((tbl = (u_char *)malloc(ncolors * sizeof(char))) == NULL)
01553 {
01554 printf("malloc for cast_tbl failed, size %d\n", ncolors);
01555 exit(0);
01556 }
01557
01558 for (i=0; i < ncolors; i++)
01559 {
01560 tbl[i] = (int)(fmin + ((mult * (float)i) + 0.5));
01561 }
01562
01563 if (Pdv_debug)
01564 {
01565 printf("Cast_tbl: depth (bytes) %d nents %d ncolors %d mult %1.2f\n",
01566 depth_bits, nents, ncolors, mult);
01567 printf("Cast_tbl %d: %d\n", 0, tbl[0]);
01568 printf("Cast_tbl %d: %d\n", ncolors/2, tbl[ncolors/2]);
01569 printf("Cast_tbl %d: %d\n", ncolors-1, tbl[ncolors-1]);
01570 }
01571
01572
01573
01574
01575 return tbl;
01576 }
01577
01578 static void
01579 free_cast_tbl()
01580 {
01581 free(Cast_tbl);
01582 Cast_tbl = NULL;
01583 }
01584
01585
01586
01587
01588
01589 void
01590 dvu_long_to_charbuf(unsigned int val, u_char *buf)
01591 {
01592 buf[0] = (u_char) ((val & 0xff000000) >> 24);
01593 buf[1] = (u_char) ((val & 0x00ff0000) >> 16);
01594 buf[2] = (u_char) ((val & 0x0000ff00) >> 8);
01595 buf[3] = (u_char) ((val & 0x000000ff) );
01596 }
01597
01599