| 177 | } |
| 178 | |
| 179 | void rleFrPoly( RLE *R, const double *xy, siz k, siz h, siz w ) { |
| 180 | /* upsample and get discrete points densely along entire boundary */ |
| 181 | siz j, m=0; double scale=5; int *x, *y, *u, *v; uint *a, *b; |
| 182 | x=malloc(sizeof(int)*(k+1)); y=malloc(sizeof(int)*(k+1)); |
| 183 | for(j=0; j<k; j++) x[j]=(int)(scale*xy[j*2+0]+.5); x[k]=x[0]; |
| 184 | for(j=0; j<k; j++) y[j]=(int)(scale*xy[j*2+1]+.5); y[k]=y[0]; |
| 185 | for(j=0; j<k; j++) m+=umax(abs(x[j]-x[j+1]),abs(y[j]-y[j+1]))+1; |
| 186 | u=malloc(sizeof(int)*m); v=malloc(sizeof(int)*m); m=0; |
| 187 | for( j=0; j<k; j++ ) { |
| 188 | int xs=x[j], xe=x[j+1], ys=y[j], ye=y[j+1], dx, dy, t, d; |
| 189 | int flip; double s; dx=abs(xe-xs); dy=abs(ys-ye); |
| 190 | flip = (dx>=dy && xs>xe) || (dx<dy && ys>ye); |
| 191 | if(flip) { t=xs; xs=xe; xe=t; t=ys; ys=ye; ye=t; } |
| 192 | s = dx>=dy ? (double)(ye-ys)/dx : (double)(xe-xs)/dy; |
| 193 | if(dx>=dy) for( d=0; d<=dx; d++ ) { |
| 194 | t=flip?dx-d:d; u[m]=t+xs; v[m]=(int)(ys+s*t+.5); m++; |
| 195 | } else for( d=0; d<=dy; d++ ) { |
| 196 | t=flip?dy-d:d; v[m]=t+ys; u[m]=(int)(xs+s*t+.5); m++; |
| 197 | } |
| 198 | } |
| 199 | /* get points along y-boundary and downsample */ |
| 200 | free(x); free(y); k=m; m=0; double xd, yd; |
| 201 | x=malloc(sizeof(int)*k); y=malloc(sizeof(int)*k); |
| 202 | for( j=1; j<k; j++ ) if(u[j]!=u[j-1]) { |
| 203 | xd=(double)(u[j]<u[j-1]?u[j]:u[j]-1); xd=(xd+.5)/scale-.5; |
| 204 | if( floor(xd)!=xd || xd<0 || xd>w-1 ) continue; |
| 205 | yd=(double)(v[j]<v[j-1]?v[j]:v[j-1]); yd=(yd+.5)/scale-.5; |
| 206 | if(yd<0) yd=0; else if(yd>h) yd=h; yd=ceil(yd); |
| 207 | x[m]=(int) xd; y[m]=(int) yd; m++; |
| 208 | } |
| 209 | /* compute rle encoding given y-boundary points */ |
| 210 | k=m; a=malloc(sizeof(uint)*(k+1)); |
| 211 | for( j=0; j<k; j++ ) a[j]=(uint)(x[j]*(int)(h)+y[j]); |
| 212 | a[k++]=(uint)(h*w); free(u); free(v); free(x); free(y); |
| 213 | qsort(a,k,sizeof(uint),uintCompare); uint p=0; |
| 214 | for( j=0; j<k; j++ ) { uint t=a[j]; a[j]-=p; p=t; } |
| 215 | b=malloc(sizeof(uint)*k); j=m=0; b[m++]=a[j++]; |
| 216 | while(j<k) if(a[j]>0) b[m++]=a[j++]; else { |
| 217 | j++; if(j<k) b[m-1]+=a[j++]; } |
| 218 | rleInit(R,h,w,m,b); free(a); free(b); |
| 219 | } |
| 220 | |
| 221 | char* rleToString( const RLE *R ) { |
| 222 | /* Similar to LEB128 but using 6 bits/char and ascii chars 48-111. */ |
no test coverage detected