BlinkenLib v.0.1.1 (2005-01...
Christian Heimke authored 13 years ago
|
56) stBlinkenFrame * BlinkenFrameNew( int height, int width, int channels, int maxval, int duration )
57) {
58) stBlinkenFrame * pFrame;
59)
60) if( height < BlinkenHeightMin ) height = BlinkenHeightMin;
61) if( height > BlinkenHeightMax ) height = BlinkenHeightMax;
62) if( width < BlinkenWidthMin ) width = BlinkenWidthMin;
63) if( width > BlinkenWidthMax ) width = BlinkenWidthMax;
64) if( channels < BlinkenChannelsMin ) channels = BlinkenChannelsMin;
65) if( channels > BlinkenChannelsMax ) channels = BlinkenMaxvalMax;
66) if( maxval < BlinkenMaxvalMin ) maxval = BlinkenMaxvalMin;
67) if( maxval > BlinkenMaxvalMax ) maxval = BlinkenMaxvalMax;
68) if( duration < BlinkenDurationMin ) duration = BlinkenDurationMin;
69) if( duration > BlinkenDurationMax ) duration = BlinkenDurationMax;
70)
71) pFrame = (stBlinkenFrame *)malloc( sizeof( stBlinkenFrame ) );
72) if( pFrame == NULL )
73) return NULL;
74)
75) pFrame->height = height;
76) pFrame->width = width;
77) pFrame->channels = channels;
78) pFrame->maxval = maxval;
79) pFrame->duration = duration;
80)
81) pFrame->pppData = (unsigned char * * *)malloc3D( height, width, channels, sizeof( unsigned char ) );
82) if( pFrame->pppData == NULL )
83) {
84) free( pFrame );
85) return NULL;
86) }
87)
88) return pFrame;
89) }
90)
91) stBlinkenFrame * BlinkenFrameClone( stBlinkenFrame * pSrcFrame )
92) {
93) int y, x, c;
94) stBlinkenFrame * pFrame;
95)
96) if( pSrcFrame == NULL )
97) return NULL;
98)
99) pFrame = BlinkenFrameNew( pSrcFrame->height, pSrcFrame->width,
100) pSrcFrame->channels, pSrcFrame->maxval, pSrcFrame->duration );
101) if( pFrame == NULL )
102) return NULL;
103)
104) for( y = 0; y < pFrame->height; y++ )
105) for( x = 0; x < pFrame->width; x++ )
106) for( c = 0; c < pFrame->channels; c++ )
107) pFrame->pppData[y][x][c] = pSrcFrame->pppData[y][x][c];
108)
109) return pFrame;
110) }
111)
112) void BlinkenFrameFree( stBlinkenFrame * pFrame )
113) {
114) if( pFrame == NULL )
115) return;
116)
117) free( pFrame->pppData );
118) free( pFrame );
119) }
120)
121) void BlinkenFrameClear( stBlinkenFrame * pFrame )
122) {
123) int y, x, c;
124)
125) if( pFrame == NULL )
126) return;
127)
128) for( y = 0; y < pFrame->height; y++ )
129) for( x = 0; x < pFrame->width; x++ )
130) for( c = 0; c < pFrame->channels; c++ )
131) pFrame->pppData[y][x][c] = 0;
132) }
133)
134) int BlinkenFrameGetHeight( stBlinkenFrame * pFrame )
135) {
136) if( pFrame == NULL )
137) return 0;
138)
139) return pFrame->height;
140) }
141)
142) int BlinkenFrameGetWidth( stBlinkenFrame * pFrame )
143) {
144) if( pFrame == NULL )
145) return 0;
146)
147) return pFrame->width;
148) }
149)
150) int BlinkenFrameGetChannels( stBlinkenFrame * pFrame )
151) {
152) if( pFrame == NULL )
153) return 0;
154)
155) return pFrame->channels;
156) }
157)
158) int BlinkenFrameGetMaxval( stBlinkenFrame * pFrame )
159) {
160) if( pFrame == NULL )
161) return 0;
162)
163) return pFrame->maxval;
164) }
165)
166) int BlinkenFrameGetDuration( stBlinkenFrame * pFrame )
167) {
168) if( pFrame == NULL )
169) return 0;
170)
171) return pFrame->duration;
172) }
173)
174) void BlinkenFrameSetDuration( stBlinkenFrame * pFrame, int duration )
175) {
176) if( pFrame == NULL )
177) return;
178)
179) if( duration < BlinkenDurationMin ) duration = BlinkenDurationMin;
180) if( duration > BlinkenDurationMax ) duration = BlinkenDurationMax;
181)
182) pFrame->duration = duration;
183) }
184)
185) unsigned char BlinkenFrameGetPixel( stBlinkenFrame * pFrame, int y, int x, int c )
186) {
187) if( pFrame == NULL ||
188) y < 0 || y >= pFrame->height ||
189) x < 0 || x >= pFrame->width ||
190) c < 0 || c >= pFrame->channels )
191) return 0;
192)
193) return pFrame->pppData[y][x][c];
194) }
195)
196) void BlinkenFrameSetPixel( stBlinkenFrame * pFrame, int y, int x, int c, unsigned char val )
197) {
198) if( pFrame == NULL ||
199) y < 0 || y >= pFrame->height ||
200) x < 0 || x >= pFrame->width ||
201) c < 0 || c >= pFrame->channels )
202) return;
203)
204) if( val > pFrame->maxval )
205) val = pFrame->maxval;
206) pFrame->pppData[y][x][c] = val;
207) }
208)
209) unsigned long BlinkenFrameGetColor( stBlinkenFrame * pFrame, int y, int x )
210) {
211) if( pFrame == NULL ||
212) y < 0 || y >= pFrame->height ||
213) x < 0 || x >= pFrame->width )
214) return 0;
215)
216) if( pFrame->channels == 1 )
217) return (((unsigned long)pFrame->pppData[y][x][0] * 255 + pFrame->maxval / 2) / pFrame->maxval) << 16 |
218) (((unsigned long)pFrame->pppData[y][x][0] * 255 + pFrame->maxval / 2) / pFrame->maxval) << 8 |
219) (((unsigned long)pFrame->pppData[y][x][0] * 255 + pFrame->maxval / 2) / pFrame->maxval);
220) if( pFrame->channels == 2 )
221) return (((unsigned long)pFrame->pppData[y][x][0] * 255 + pFrame->maxval / 2) / pFrame->maxval) << 16 |
222) (((unsigned long)pFrame->pppData[y][x][1] * 255 + pFrame->maxval / 2) / pFrame->maxval) << 8;
223) return (((unsigned long)pFrame->pppData[y][x][0] * 255 + pFrame->maxval / 2) / pFrame->maxval) << 16 |
224) (((unsigned long)pFrame->pppData[y][x][1] * 255 + pFrame->maxval / 2) / pFrame->maxval) << 8 |
225) (((unsigned long)pFrame->pppData[y][x][2] * 255 + pFrame->maxval / 2) / pFrame->maxval);
226) }
227)
228) void BlinkenFrameSetColor( stBlinkenFrame * pFrame, int y, int x, unsigned long color )
229) {
230) int alpha, alpha_, c;
231)
232) if( pFrame == NULL ||
233) y < 0 || y >= pFrame->height ||
234) x < 0 || x >= pFrame->width )
235) return;
236)
237) alpha = (color >> 24) & 0xFF;
238) alpha_ = 255 - alpha;
239) if( pFrame->channels >= 1 )
240) pFrame->pppData[y][x][0] = (unsigned char)(( ((((color >> 16) & 0xFF) * pFrame->maxval + 127) / 255) * alpha
241) + (unsigned long)pFrame->pppData[y][x][0] * alpha_
242) ) / 255);
243) if( pFrame->channels >= 2 )
244) pFrame->pppData[y][x][1] = (unsigned char)(( ((((color >> 8) & 0xFF) * pFrame->maxval + 127) / 255) * alpha
245) + (unsigned long)pFrame->pppData[y][x][1] * alpha_
246) ) / 255);
247) if( pFrame->channels >= 3 )
248) pFrame->pppData[y][x][2] = (unsigned char)(( (((color & 0xFF) * pFrame->maxval + 127) / 255) * alpha
249) + (unsigned long)pFrame->pppData[y][x][2] * alpha_
250) ) / 255);
251) for( c = 3; c < pFrame->channels; c++ )
252) pFrame->pppData[y][x][c] = (unsigned char)(( 0
253) + (unsigned long)pFrame->pppData[y][x][c] * alpha_
254) ) / 255);
255) }
256)
257) void BlinkenFrameResize( stBlinkenFrame * pFrame, int height, int width, int channels, int maxval )
258) {
259) unsigned char * * * pppData;
260) int y, x, c;
261) int emptyY, emptyX, skipY, skipX, rangeY, rangeX;
262) unsigned long val, div;
263)
264) if( pFrame == NULL )
265) return;
266)
267) if( height < BlinkenHeightMin ) height = BlinkenHeightMin;
268) if( height > BlinkenHeightMax ) height = BlinkenHeightMax;
269) if( width < BlinkenWidthMin ) width = BlinkenWidthMin;
270) if( width > BlinkenWidthMax ) width = BlinkenWidthMax;
271) if( channels < BlinkenChannelsMin ) channels = BlinkenChannelsMin;
272) if( channels > BlinkenChannelsMax ) channels = BlinkenMaxvalMax;
273) if( maxval < BlinkenMaxvalMin ) maxval = BlinkenMaxvalMin;
274) if( maxval > BlinkenMaxvalMax ) maxval = BlinkenMaxvalMax;
275)
276) if( height == pFrame->height &&
277) width == pFrame->width &&
278) channels == pFrame->channels &&
279) maxval == pFrame->maxval )
280) return;
281)
282) //allocate new data array
283) pppData = (unsigned char * * *)malloc3D( height, width, channels, sizeof( unsigned char ) );
284) if( pppData == NULL )
285) return;
286) for( y = 0; y < height; y++ )
287) for( x = 0; x < width; x++ )
288) for( c = 0; c < channels; c++ )
289) pppData[y][x][c] = 0;
290)
291) //get number of pixels to skip / to leave empty in X and Y direction
292) if( height > pFrame->height )
293) {
294) emptyY = (height - pFrame->height) / 2;
295) skipY = 0;
296) rangeY = pFrame->height;
297) }
298) else
299) {
300) emptyY = 0;
301) skipY = (pFrame->height - height) / 2;
302) rangeY = height;
303) }
304) if( width > pFrame->width )
305) {
306) emptyX = (width - pFrame->width) / 2;
307) skipX = 0;
308) rangeX = pFrame->width;
309) }
310) else
311) {
312) emptyX = 0;
313) skipX = (pFrame->width - width) / 2;
314) rangeX = width;
315) }
316)
317) //resize frame with help of calculated parameters
318) for( y = 0; y < rangeY; y++ )
319) {
320) for( x = 0; x < rangeX; x++ )
321) {
322) if( channels >= pFrame->channels ) //add channels: copy last channel into new channels
323) {
324) for( c = 0; c < pFrame->channels; c++ )
325) pppData[emptyY + y][emptyX + x][c] = (unsigned char)(((unsigned long)pFrame->pppData[skipY + y][skipX + x][c] * maxval + pFrame->maxval / 2) / pFrame->maxval);
326) for( ; c < channels; c++ )
327) pppData[emptyY + y][emptyX + x][c] = pppData[emptyY + y][emptyX + x][pFrame->channels - 1];
328) }
329) else //remove channels: merge leftover channels with last kept channel
330) {
331) val = 0;
332) for( c = 0; c < channels - 1; c++ )
333) pppData[emptyY + y][emptyX + x][c] = (unsigned char)(((unsigned long)pFrame->pppData[skipY + y][skipX + x][c] * maxval + pFrame->maxval / 2) / pFrame->maxval);
334) for( c = channels - 1; c < pFrame->channels; c++ )
335) val += (unsigned long)pFrame->pppData[skipY + y][skipX + x][c];
336) div = pFrame->maxval * (pFrame->channels - channels + 1);
337) pppData[emptyY + y][emptyX + x][channels - 1] = (unsigned char)((val * maxval + div / 2) / div);
338) }
339) }
340) }
341)
342) pFrame->height = height;
343) pFrame->width = width;
344) pFrame->channels = channels;
345) pFrame->maxval = maxval;
346) free( pFrame->pppData );
347) pFrame->pppData = pppData;
348) }
349)
350) void BlinkenFrameScale( stBlinkenFrame * pFrame, int height, int width )
351) {
352) unsigned char * * * pppData;
353) double scaleHor, scaleVer, ox, oy, ox1, oy1, val;
354) int c, nx, ny, x, y, oxi, oyi, ox1i, oy1i;
355)
356) if( pFrame == NULL )
357) return;
358)
359) if( height < BlinkenHeightMin ) height = BlinkenHeightMin;
360) if( height > BlinkenHeightMax ) height = BlinkenHeightMax;
361) if( width < BlinkenWidthMin ) width = BlinkenWidthMin;
362) if( width > BlinkenWidthMax ) width = BlinkenWidthMax;
363)
364) if( height == pFrame->height &&
365) width == pFrame->width )
366) return;
367)
368) scaleHor = (double)width / (double)pFrame->width;
369) scaleVer = (double)height / (double)pFrame->height;
370)
371) //allocate new data array
372) pppData = (unsigned char * * *)malloc3D( height, width, pFrame->channels, sizeof( unsigned char ) );
373) if( pppData == NULL )
374) return;
375)
376) //scale every channel
377) for( c = 0; c < pFrame->channels; c++ )
378) {
379) for( ny = 0; ny < height; ny++ )
380) {
381) for( nx = 0; nx < width; nx++ )
382) {
383) oy = (double)ny / scaleVer; //sub-pixel exact range in old picture
384) ox = (double)nx / scaleHor;
385) oy1 = (double)(ny + 1) / scaleVer - 0.000001;
386) ox1 = (double)(nx + 1) / scaleHor - 0.000001;
387) if( oy < 0 || ox < 0 || oy1 >= pFrame->height || ox1 >= pFrame->width) //out of old picture
388) pppData[ny][nx][c] = 0;
389) else
390) {
391) oyi = (int)oy;
392) oxi = (int)ox;
393) oy1i = (int)oy1;
394) ox1i = (int)ox1;
395) if( oyi == oy1i )
396) {
397) if( oxi == ox1i) //one source pixel
398) {
399) val = (double)pFrame->pppData[oyi][oxi][c];
400) }
401) else //one line of source pixels
402) {
403) val = (double)pFrame->pppData[oyi][oxi][c] * (1 - ox + oxi)
404) + (double)pFrame->pppData[oyi][ox1i][c] * (ox1 - ox1i);
405) for( x = oxi + 1; x < ox1i; x++ )
406) val += (double)pFrame->pppData[oyi][x][c];
407) val /= ox1 - ox;
408) }
409) }
410) else //one column of source pixels
411) {
412) if( oxi == ox1i )
413) {
414) val = (double)pFrame->pppData[oyi][oxi][c] * (1 - oy + oyi)
415) + (double)pFrame->pppData[oy1i][oxi][c] * (oy1 - oy1i);
416) for( y = oyi + 1; y < oy1i; y++ )
417) val += (double)pFrame->pppData[y][oxi][c];
418) val /= oy1 - oy;
419) }
420) else //rectangle of source pixels
421) {
422) val = (double)pFrame->pppData[oyi][oxi][c] * (1 - oy + oyi) * (1 - ox + oxi)
423) + (double)pFrame->pppData[oyi][ox1i][c] * (1 - oy + oyi) * (ox1 - ox1i)
424) + (double)pFrame->pppData[oy1i][oxi][c] * (oy1 - oy1i) * (1 - ox + oxi)
425) + (double)pFrame->pppData[oy1i][ox1i][c] * (oy1 - oy1i) * (ox1 - ox1i);
426) for( y = oyi + 1; y < oy1i; y++ )
427) {
428) val += (double)pFrame->pppData[y][oxi][c] * (1 - ox + oxi)
429) + (double)pFrame->pppData[y][ox1i][c] * (ox1 - ox1i);
430) }
431) for( x = oxi + 1; x < ox1i; x++ )
432) {
433) val += (double)pFrame->pppData[oyi][x][c] * (1 - oy + oyi)
434) + (double)pFrame->pppData[oy1i][x][c] * (oy1 - oy1i);
435) }
436) for( y = oyi + 1; y < oy1i; y++ )
437) for( x = oxi + 1; x < ox1i; x++ )
438) val += (double)pFrame->pppData[y][x][c];
439) val /= (oy1 - oy) * (ox1 - ox);
440) }
441) }
442) pppData[ny][nx][c] = (unsigned char)(val + 0.5);
443) }
444) } //for( nx ...
445) } //for( ny ...
446) } //for( c ...
447)
448) pFrame->height = height;
449) pFrame->width = width;
450) free( pFrame->pppData );
451) pFrame->pppData = pppData;
452) }
453)
454) char * BlinkenFrameToString( stBlinkenFrame * pFrame )
455) {
456) int size, y, x, c;
457) char * str, * ptr;
458) unsigned long val;
459)
460) if( pFrame == NULL )
461) return NULL;
462)
463) size = pFrame->height * (pFrame->width + 1) + 32;
464)
465) str = (char *)malloc( size );
466) if( str == NULL )
467) return NULL;
468)
469) ptr = str;
470)
471) for( y = 0; y < pFrame->height; y++ )
472) {
473) for( x = 0; x < pFrame->width; x++ )
474) {
475) val = 0;
476) for( val = 0, c = 0; c < pFrame->channels; c++ )
477) val += pFrame->pppData[y][x][c];
478) val = val * 7 / pFrame->maxval / pFrame->channels;
479) *ptr = " -+*%#&@"[val];
480) ptr++;
481) }
482) *ptr = '\n';
483) ptr++;
484) }
485)
486) sprintf( ptr, "%u ms\n", pFrame->duration );
487)
488) return str;
489) }
490)
|