⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 enc.c

📁 a small program by Yuval Fisher that has gone a long way to revealing some of the secrets of fracal
💻 C
📖 第 1 页 / 共 3 页
字号:
void average1(x,y,xsize,ysize, psum, psum2)int x,y,xsize,ysize;double *psum, *psum2;{    register int i,j;    register double pixel;    *psum = *psum2 = 0.0;    for (i=x; i<x+xsize; ++i)    for (j=y; j<y+ysize; ++j) {	   pixel = (double)image[j][i];       *psum += pixel;       *psum2 += pixel*pixel;    }}/* ************************************************************** *//* Take a region of the image at x,y and classify it.             *//* The four quadrants of the region are ordered from brightest to *//* least bright average value, then it is rotated into one of the *//* three cannonical orientations possible with the brightest quad *//* in the upper left corner.                                      *//* The routine returns two indices that are class numbers: pfirst *//* and psecond; the symmetry operation that bring the square into *//* cannonical position; and the sum and sum^2 of the pixel values *//* ************************************************************** */classify(x, y, xsize, ysize, pfirst, psecond, psym, psum, psum2, type)int x,y,xsize,ysize,   /* position, size of subimage to be classified */    *pfirst, *psecond, /* returned first and second class numbers     */    *psym;             /* returned symmetry operation that brings the */                       /* subimage to cannonical position.            */double *psum, *psum2;  /* returned sum and sum^2 of pixel values      */int type;              /* flag for decimating (for domains) or not    */ {    int order[4], i,j;     double a[4],a2[4];    void (*average_func)();        if (type == 2) average_func = average; else average_func = average1;    /* get the average values of each quadrant                         */    (*average_func)(x,y,                 xsize/2,ysize/2,   &a[0], &a2[0]);    (*average_func)(x,y+ysize/2,         xsize/2,ysize/2,   &a[1], &a2[1]);    (*average_func)(x+xsize/2,y+ysize/2, xsize/2,ysize/2,   &a[2], &a2[2]);    (*average_func)(x+xsize/2,y,         xsize/2,ysize/2,   &a[3], &a2[3]);    *psum = a[0] + a[1] + a[2] + a[3];    *psum2 =  a2[0] + a2[1] + a2[2] + a2[3];    for (i=0; i<4; ++i) {         /* after the sorting below order[i] is the i-th brightest   */         /* quadrant.                                                */         order[i] = i;          /* convert a2[] to store the variance of each quadrant      */         a2[i] -= (double)(1<<(2*type))*a[i]*a[i]/(double)(xsize*ysize);    }    /* Now order the average value and also in order[],   which will */    /* then tell us the indices (in a[]) of the brightest to darkest */    for (i=2; i>=0; --i)    for (j=0; j<=i; ++j)        if (a[j]<a[j+1]) {            swap(order[j], order[j+1],int)            swap(a[j], a[j+1],double)    }    /* because of the way we ordered the a[] the rotation can be */    /* read right off of order[]. That will make the brightest   */    /* quadrant be in the upper left corner. But we must still   */     /* decide which cannonical class the image portion belogs    */    /* to and whether to do a flip or just a rotation. This is   */    /* the following table summarizes the horrid lines below     */    /* order      class            do a rotation                 */    /* 0,2,1,3      0                   0                        */    /* 0,2,3,1      0                   1                        */    /* 0,1,2,3      1                   0                        */    /* 0,3,2,1      1                   1                        */    /* 0,1,3,2      2                   0                        */    /* 0,3,1,2      2                   1                        */    *psym = order[0];     /* rotate the values */    for (i=0; i<4; ++i)        order[i] = (order[i] - (*psym) + 4)%4;     for (i=0; order[i] != 2; ++i);     *pfirst = i-1;    if (order[3] == 1 || (*pfirst == 2 && order[2] == 1)) *psym += 4;    /* Now further classify the sub-image by the variance of its    */    /* quadrants. This give 24 subclasses for each of the 3 classes */    for (i=0; i<4; ++i) order[i] = i;     for (i=2; i>=0; --i)    for (j=0; j<=i; ++j)        if (a2[j]<a2[j+1]) {            swap(order[j], order[j+1],int)            swap(a2[j], a2[j+1],double)    }    /* Now do the symmetry operation */    for (i=0; i<4; ++i)        order[i] = (order[i] - (*psym%4) + 4)%4;     if (*psym > 3)         for (i=0; i<4; ++i)           if (order[i]%2) order[i] = (2 + order[i])%4;    /* We want to return a class number from 0 to 23 depending on */    /* the ordering of the quadrants according to their variance  */    *psecond = 0;    for (i=2; i>=0; --i)    for (j=0; j<=i; ++j)        if (order[j] > order[j+1]) {            swap(order[j],order[j+1], int);            if (order[j] == 0 || order [j+1] == 0)                  *psecond += 6;            else if (order[j] == 1 || order [j+1] == 1)                  *psecond += 2;            else if (order[j] == 2 || order [j+1] == 2)                  *psecond += 1;        }}/* ************************************************************ *//* Compute sum and sum^2 of pixel values in domains for use in  *//* the rms computation later. Since a domain is compared with   *//* many ranges, doing this just once saves a lot of computation *//* This routine also fills a list structure with the domains    *//* as they are classified and creates the memory for the domain *//* data in a matrix.                                            *//* ************************************************************ */compute_sums(hsize,vsize)int hsize,vsize;{    int i,j,k,l,         domain_x,          domain_y,          first_class,          second_class,         domain_size,          domain_step_size,          size,           x_exponent,          y_exponent;    struct classified_domain *node;    printf("\nComputing domain sums... ");    fflush(stdout);     /* pre-decimate the image into domimage to avoid having to      */    /* do repeated averaging of 2x2 pixel groups.                   */    /* There are 4 ways to decimate the image, depending on the     */    /* location of the domain, odd or even address.                 */    for (i=0; i<2; ++i)    for (j=0; j<2; ++j)    for (k=i; k<hsize-i; k += 2)    for (l=j; l<vsize-j; l += 2)         domimage[(i<<1)+j][l>>1][k>>1] =                      ((double)image[l][k] + (double)image[l+1][k+1] +                     (double)image[l][k+1] + (double)image[l+1][k])*0.25;    /* Allocate memory for the sum and sum^2 of domain pixels        */    /* We first compute the size of the largest square that fits in  */    /* the image.                                                    */    x_exponent = (int)floor(log((double)hsize)/log(2.0));    y_exponent = (int)floor(log((double)vsize)/log(2.0));       /* exponent is min of x_ and y_ exponent */    max_exponent = (x_exponent > y_exponent ? y_exponent : x_exponent);    /* size is the size of the largest square that fits in the image */    /* It is used to compute the domain and range sizes.             */    size =  1<<max_exponent;     if (max_exponent < max_part)      fatal("Reduce maximum number of quadtree partitions.");    if (max_exponent-2 < max_part)      printf("\nWarning: so many quadtree partitions yield absurd ranges.");    i = max_part - min_part + 1;    domain.no_h_domains = (int *)malloc(sizeof(int)*i);    domain.no_v_domains = (int *)malloc(sizeof(int)*i);    domain.domain_hsize = (int *)malloc(sizeof(int)*i);    domain.domain_vsize = (int *)malloc(sizeof(int)*i);    domain.domain_hstep = (int *)malloc(sizeof(int)*i);    domain.domain_vstep = (int *)malloc(sizeof(int)*i);    domain.pixel= (struct domain_pixels ***)              malloc(i*sizeof(struct domain_pixels **));    if (domain.pixel == NULL) fatal("No memory for domain pixel sums.");    for (i=0; i <= max_part-min_part; ++i) {       /* first compute how many domains there are horizontally */       domain.domain_hsize[i] = size >> (min_part+i-1);       if (dom_type == 2)              domain.domain_hstep[i] = dom_step;        else if (dom_type == 1)             if (dom_step_type == 1)                domain.domain_hstep[i] = (size >> (max_part - i-1))*dom_step;             else                domain.domain_hstep[i] = (size >> (max_part - i-1))/dom_step;       else              if (dom_step_type == 1)                domain.domain_hstep[i] = domain.domain_hsize[i]*dom_step;             else                domain.domain_hstep[i] = domain.domain_hsize[i]/dom_step;       domain.no_h_domains[i] = 1+(hsize-domain.domain_hsize[i])/                                                  domain.domain_hstep[i];       /* bits_needed[i][0] = ceil(log(domain.no_h_domains[i])/log(2.0));  */       /* now compute how many domains there are vertically. The sizes  */       /* are the same for square domains, but not for rectangular ones */       domain.domain_vsize[i] = size >> (min_part+i-1);       if (dom_type == 2)              domain.domain_vstep[i] = dom_step;        else if (dom_type == 1)             if (dom_step_type == 1)                domain.domain_vstep[i] = (size >> (max_part - i-1))*dom_step;             else               domain.domain_vstep[i] = (size >> (max_part - i-1))/dom_step;       else              if (dom_step_type == 1)                domain.domain_vstep[i] = domain.domain_vsize[i]*dom_step;             else               domain.domain_vstep[i] = domain.domain_vsize[i]/dom_step;       domain.no_v_domains[i] = 1+(vsize-domain.domain_vsize[i])/                                                  domain.domain_vstep[i];       /* Now compute the number of bits needed to store the domain data */       bits_needed[i] = ceil(log((double)domain.no_h_domains[i]*                                 (double)domain.no_v_domains[i])/log(2.0));        matrix_allocate(domain.pixel[i], domain.no_h_domains[i],                     domain.no_v_domains[i], struct domain_pixels)     }    /* allocate and zero the list containing the classified domain data */    i = max_part - min_part + 1;    for (first_class = 0; first_class < 3; ++first_class)    for (second_class = 0; second_class < 24; ++second_class) {       the_domain[first_class][second_class] =                            (struct classified_domain **)                            malloc(i*sizeof(struct classified_domain *));       for (j=0; j<i; ++j)                    the_domain[first_class][second_class][j] = NULL;    }    /* Precompute sum and sum of squares for domains                 */    /* This part can get faster for overlapping domains if repeated  */    /* sums are avoided                                              */    for (i=0; i <= max_part-min_part; ++i) {      for (j=0,domain_x=0; j<domain.no_h_domains[i]; ++j,             domain_x+=domain.domain_hstep[i])       for (k=0,domain_y=0; k<domain.no_v_domains[i]; ++k,             domain_y+=domain.domain_vstep[i]) {		classify(domain_x, domain_y,                  domain.domain_hsize[i],                  domain.domain_vsize[i], 					 &first_class, &second_class,					 &domain.pixel[i][k][j].sym,                      &domain.pixel[i][k][j].sum,                      &domain.pixel[i][k][j].sum2, 2);        /* When the domain data is referenced from the list, we need to */        /* know where the domain is.. so we have to store the position  */        domain.pixel[i][k][j].dom_x = j;        domain.pixel[i][k][j].dom_y = k;        node = (struct classified_domain *)                                malloc(sizeof(struct classified_domain));                /* put this domain in the classified list structure */        node->the = &domain.pixel[i][k][j];        node->next = the_domain[first_class][second_class][i];        the_domain[first_class][second_class][i] = node;	  }    }    /* Now we make sure no domain class is actually empty.  */    for (i=0; i <= max_part-min_part; ++i)     for (first_class = 0; first_class < 3; ++first_class)    for (second_class = 0; second_class < 24; ++second_class)        if (the_domain[first_class][second_class][i] == NULL) {           node = (struct classified_domain *)                                malloc(sizeof(struct classified_domain));           node->the = &domain.pixel[i][0][0];           node->next = NULL;           the_domain[first_class][second_class][i] = node;       }    printf("Done.");    fflush(stdout); }/* ************************************************************ *//* pack value using size bits and output into foutf *//* ************************************************************ */int pack(size, value, foutf)int size; long int value;FILE *foutf;{     int i;     static int ptr = 1, /* how many bits are packed in sum so far */                sum = 0, /* packed bits */                 num_of_packed_bytes = 0; /* total bytes written out */    /* size == -1 means we are at the end, so write out what is left */    if (size == -1 && ptr != 1) {        fputc(sum<<(8-ptr), foutf);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -