xzoom

A simple screen magnifier for X11.
git clone git://r-36.net/xzoom
Log | Files | Refs

scale.h (2019B)


      1 /* scale image from SRC to DST - parameterized by type T */
      2 
      3 /* get pixel address of point (x,y) in image t */
      4 #define getP(t,x,y) \
      5 	(T *) (&ximage[t]->data[(ximage[t]->xoffset+(x))*sizeof(T) + \
      6 	                        (y)*ximage[t]->bytes_per_line])
      7 
      8 {
      9 	int i, j, k;
     10 
     11 	/* copy scaled lines from SRC to DST */
     12 	j = flipxy ? width[SRC] - 1 : height[SRC] - 1;
     13 	do {
     14 		T *p1;
     15 		T *p2;
     16 		int p2step;
     17 		T *p1_save;
     18 
     19 		/* p1 point to begining of scanline j*magy in DST */
     20 		p1 = getP(DST,0,j*magy);
     21 		p1_save = p1;
     22 		/* p2 point to begining of scanline j in SRC */
     23 		/* if flipy then line height[SRC]-1-j */
     24 		p2 = getP(SRC,0,flipy ? (height[SRC]-1-j) : j);
     25 
     26 		if (flipxy)
     27 		{
     28 			p2 = getP(SRC,flipy ? j : (width[SRC]-1-j),0);
     29 			p2step = ximage[SRC]->bytes_per_line / sizeof(T);
     30 
     31 			if (flipx)
     32 			{
     33 				p2 += p2step * (height[SRC]-1);
     34 				p2step = -p2step;
     35 			}
     36 
     37 			i = height[SRC];
     38 			do {
     39 				T c = *p2; p2 += p2step;
     40 				k = magx; do *p1++ = c; while (--k > 0);
     41 			} while (--i > 0);
     42 		}
     43 		else if (flipx)
     44 		{
     45 			p2 += width[SRC];
     46 			i = width[SRC];
     47 			do {
     48 				T c = *--p2;
     49 				k = magx; do *p1++ = c; while (--k > 0);
     50 			} while (--i > 0);
     51 		}
     52 		else
     53 		{
     54 			i = width[SRC];
     55 			do {
     56 				T c = *p2++;
     57 				k = magx; do *p1++ = c; while (--k > 0);
     58 			} while (--i > 0);
     59 		}
     60 
     61 		/* draw vertical grid */
     62 		if (gridy && magx >= 2)
     63 		{
     64 			p1 = p1_save - 1;
     65 			i = magx;
     66 			k = flipxy ? height[SRC] : width[SRC];
     67 			do {
     68 				p1 += i;
     69 				*p1 ^= ~((T)0);
     70 			} while (--k > 0);
     71 		}
     72 
     73 		/* duplicate that line as needed */
     74 		if (magy > 1)
     75 		{
     76 			/* p1 point to begining of scanline j*magy in DST */
     77 			p1 = p1_save;
     78 			/* p2 points to begining of next line */
     79 			p2 = p1;
     80 			p2step = ximage[DST]->bytes_per_line / sizeof(T);
     81 
     82 			i = width[DST] * sizeof(T);
     83 			k = magy - 1;
     84 			do {
     85 				p2 += p2step;
     86 				memcpy(p2, p1, i);
     87 			} while (--k > 0);
     88 
     89 			/* draw horizontal grid */
     90 			if (gridx && magy >= 2)
     91 			{
     92 				k = width[DST];
     93 				do {
     94 					*p2++ ^= ~((T)0);
     95 				} while (--k > 0);
     96 			}
     97 		}
     98 	} while (--j >= 0);
     99 }
    100 
    101 #undef getP
    102