1 #ifndef MAKEFOURCC
2 #define MAKEFOURCC(ch0, ch1, ch2, ch3) \
3 ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \
4 ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))
5 typedef DWORD FOURCC; /* a four character code */
6 #endif
7 typedef enum PixFmtSamp{
8 PIX_SAMPLE_444,
9 PIX_SAMPLE_422,
10 PIX_SAMPLE_420,
11 PIX_SAMPLE_411,
12 }PixFmtSamp;
13 typedef enum PixFmtYUV{
14 PIX_FMT_YUYV,
15 PIX_FMT_YUV,
16 PIX_FMT_YUY,
17 PIX_FMT_UYVY,
18 PIX_FMT_YVYU,
19 PIX_FMT_YVU,
20 }PixFmtYUV;
21 typedef enum PixIntPro{
22 PIX_INTLACED,
23 PIX_PROGRESS,
24 }PixIntPro;
25 typedef enum PixPackPlanar{
26 PIX_PACKED,
27 PIX_PLANAR,
28 PIX_SEMI_PLANAR,
29 }PixPackPlanar;
30 #define PIXFMT_ID(samp, fmt, ip, pp) (((samp)<<24)|((fmt)<<16)|((ip)<<8)|((pp)<<0))
31 typedef enum PixFmt{
32 PIX_FMT_422_YUYV_INT_PACK=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_YUYV, PIX_INTLACED, PIX_PACKED),//YUYV-422-interlaced-packed
33 PIX_FMT_422_YUV_INT_PLAN=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_YUV, PIX_INTLACED, PIX_PLANAR),//YUV-422-interlaced-planar <YV16>
34 PIX_FMT_422_YUYV_PRO_PACK=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_YUYV, PIX_PROGRESS, PIX_PACKED),//YUYV-422-progressive-packed <YUY2, YUNV, V422, YUYV>
35 PIX_FMT_422_YUY_PRO_PLAN=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_YUY, PIX_PROGRESS, PIX_PLANAR),//YUY-422-progressive-planar
36 PIX_FMT_422_UYVY_INT_PACK=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_UYVY, PIX_INTLACED, PIX_PACKED),//UYVY-422-interlaced-packed <IUYV>
37 PIX_FMT_422_UYVY_PRO_PACK=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_UYVY, PIX_PROGRESS, PIX_PACKED),//UYVY-422-progressive-packed <UYVY, UYNV, Y422 >
38 PIX_FMT_422_YVYU_INT_PACK=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_YVYU, PIX_INTLACED, PIX_PACKED),//YVYU-422-interlaced-packed
39 PIX_FMT_422_YVU_INT_PLAN=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_YVU, PIX_INTLACED, PIX_PLANAR),//YVU-422-interlaced-planar
40 PIX_FMT_422_YVYU_PRO_PACK=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_YVYU, PIX_PROGRESS, PIX_PACKED),//YVYU-422-progressive-packed <YVYU>
41 PIX_FMT_422_YVU_PRO_PLAN=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_YVU, PIX_PROGRESS, PIX_PLANAR),//YVU-422-progressive-planar
42
43 PIX_FMT_420_YUV_INT_PLAN=PIXFMT_ID(PIX_SAMPLE_420, PIX_FMT_YUV, PIX_INTLACED, PIX_PLANAR),//YUV-420-interlaced-planar
44 PIX_FMT_420_YUV_PRO_PLAN=PIXFMT_ID(PIX_SAMPLE_420, PIX_FMT_YUV, PIX_PROGRESS, PIX_PLANAR),//YUV-420-progressive-planar <IYUV, I420>
45 PIX_FMT_420_YVU_INT_PLAN=PIXFMT_ID(PIX_SAMPLE_420, PIX_FMT_YVU, PIX_INTLACED, PIX_PLANAR),//YVU-420-interlaced-planar <YV12>
46 PIX_FMT_420_YVU_PRO_PLAN=PIXFMT_ID(PIX_SAMPLE_420, PIX_FMT_YVU, PIX_PROGRESS, PIX_PLANAR),//YVU-420-progressive-planar
47 }PixFmt;
48 struct YuvImg{
49 FOURCC fcc;
50 enum PixFmtSamp samp;
51 enum PixFmtYUV fmt;
52 enum PixIntPro ip;
53 enum PixPackPlanar pp;
54 int width,height;
55 //interlaced, packed, macro pix
56 char*evenyuvaddr;
57
58 char*oddyuvaddr;
59
60 //interlaced, planar
61 char*evenyaddr;
62 char*evenuaddr;
63 char*evenvaddr;
64 char*oddyaddr;
65 char*odduaddr;
66 char*oddvaddr;
67 //interlaced, semi planar, macro pix
68 //char*evenyaddr;
69 //char*oddyaddr;
70 char*evenuvaddr;
71 char*odduvaddr;
72 //progress, packed, macro pix,
73 char*yuvaddr;
74 //progress, planar
75 char*yaddr;
76 char*uaddr;
77 char*vaddr;
78 //progress, semi planar, macro pix,
79 //char*yaddr;
80 char*uvaddr;
81 };
82 /*
83 case PIX_FMT_422_YUYV_INT_PACK://YUYV-422-interlaced-packed
84 case PIX_FMT_422_YUYV_PRO_PACK://YUYV-422-progressive-packed <YUY2, YUNV, V422, YUYV>
85 case PIX_FMT_422_UYVY_INT_PACK://UYVY-422-interlaced-packed <IUYV>
86 case PIX_FMT_422_UYVY_PRO_PACK://UYVY-422-progressive-packed <UYVY, UYNV, Y422 >
87 case PIX_FMT_422_YVYU_INT_PACK://YVYU-422-interlaced-packed
88 case PIX_FMT_422_YVYU_PRO_PACK://YVYU-422-progressive-packed <YVYU>
89
90 case PIX_FMT_422_YVU_INT_PLAN://YVU-422-interlaced-planar
91 case PIX_FMT_422_YVU_PRO_PLAN://YVU-422-progressive-planar
92 case PIX_FMT_422_YUV_INT_PLAN://YUV-422-interlaced-planar <YV16>
93 case PIX_FMT_422_YUY_PRO_PLAN://YUY-422-progressive-planar
94
95 case PIX_FMT_420_YUV_INT_PLAN://YUV-420-interlaced-planar
96 case PIX_FMT_420_YUV_PRO_PLAN://YUV-420-progressive-planar <IYUV, I420>
97 case PIX_FMT_420_YVU_INT_PLAN://YVU-420-interlaced-planar <YV12>
98 case PIX_FMT_420_YVU_PRO_PLAN://YVU-420-progressive-planar
99 */
100 enum{
101 //ref. http://www.sunrayimage.com/examples.html
102 YUV_4CC_YV16=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_YUV, PIX_INTLACED, PIX_PLANAR),
103 YUV_4CC_YUY2=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_YUYV, PIX_PROGRESS, PIX_PACKED),
104 YUV_4CC_YUNV=YUV_4CC_YUY2,
105 YUV_4CC_V422=YUV_4CC_YUY2,
106 YUV_4CC_YUYV=YUV_4CC_YUY2,
107 YUV_4CC_IUYV=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_UYVY, PIX_INTLACED, PIX_PACKED),
108 YUV_4CC_UYVY=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_UYVY, PIX_PROGRESS, PIX_PACKED),
109 YUV_4CC_UYNV=YUV_4CC_UYVY,
110 YUV_4CC_Y422=YUV_4CC_UYVY,
111 YUV_4CC_YVYU=PIXFMT_ID(PIX_SAMPLE_422, PIX_FMT_YVYU, PIX_PROGRESS, PIX_PACKED),
112 YUV_4CC_IYUV=PIXFMT_ID(PIX_SAMPLE_420, PIX_FMT_YUV, PIX_PROGRESS, PIX_PLANAR),
113 YUV_4CC_I420=YUV_4CC_IYUV,
114 YUV_4CC_YV12=PIXFMT_ID(PIX_SAMPLE_420, PIX_FMT_YVU, PIX_INTLACED, PIX_PLANAR),
115
116 };
117 void yuvimg_getpix(YuvImg*img, int r, int c, char *py, char*pu, char*pv)
118 {
119 char *y=0, *u=0, *v=0;
120 char*lineaddr=0;
121 char y0=0,u0=0,v0=0;
122 switch(img->pp)
123 {
124 case PIX_PACKED:
125 {//PIX_FMT_UYVY, PIX_FMT_YUYV, PIX_FMT_YVYU
126 int linebytes = (img->width/2*4);
127 switch(img->ip)
128 {
129 case PIX_INTLACED:
130 if(r&1)
131 lineaddr = img->oddyuvaddr;
132 else
133 lineaddr = img->evenyuvaddr;
134 lineaddr += r/2*linebytes;
135 break;
136 case PIX_PROGRESS:
137 lineaddr = img->yuvaddr+(linebytes*r);
138 break;
139 }
140
141 switch(img->samp)
142 {
143 case PIX_SAMPLE_422:
144 {
145 switch(img->fmt)
146 {
147 case PIX_FMT_UYVY:
148 u = lineaddr+c/2*4;
149 y = u+1;
150 v = y+1;
151 if(c&1) y=v+1;
152 break;
153 case PIX_FMT_YUYV://test done
154 y = lineaddr+c/2*4;
155 u = y+1;
156 v = u+2;
157 if(c&1) y=u+1;
158 break;
159 case PIX_FMT_YVYU:
160 y = lineaddr+c/2*4;
161 v = y+1;
162 u = v+2;
163 if(c&1) y=v+1;
164 break;
165 default:
166 assert(0);
167 break;
168 }
169 break;
170 }
171 break;
172 case PIX_SAMPLE_420:
173 break;
174 }
175 break;
176 }
177 case PIX_PLANAR:
178 {
179 char *ylineaddr=0,*ulineaddr=0,*vlineaddr=0;
180 int ylinebytes=0, ulinebytes=0, vlinebytes=0;
181 char y0=0,u0=0,v0=0;
182
183 switch(img->samp)
184 {
185 case PIX_SAMPLE_422:
186 {
187 ylinebytes=img->width;
188 ulinebytes=vlinebytes=img->width/2;
189 switch(img->ip)
190 {
191 case PIX_INTLACED:
192 {
193 if(r&1){
194 ylineaddr=img->oddyaddr+ylinebytes*r/2;
195 ulineaddr=img->odduaddr+ulinebytes*r/2;
196 vlineaddr=img->oddvaddr+vlinebytes*r/2;
197 }
198 else{
199 ylineaddr=img->evenyaddr+ylinebytes*r/2;
200 ulineaddr=img->evenuaddr+ulinebytes*r/2;
201 vlineaddr=img->evenvaddr+vlinebytes*r/2;
202 }
203
204 switch(img->fmt)
205 {
206 //TODO
207 //按照FOURCC YV16格式编写,显示出来不对,实际格式未知YUVTools也没有给出FOURCC代码
208 case PIX_FMT_YUV:
209 {
210 y=ylineaddr+c;
211 u=ulineaddr+c/2;
212 v=vlineaddr+c/2;
213 break;
214 }
215
216 case PIX_FMT_YVU:
217 {//TODO
218 y=ylineaddr+c;
219 u=ulineaddr+c/2;
220 v=vlineaddr+c/2;
221 char *u1=u, *v1=v;
222 u = v1;
223 v = u1;
224 break;
225 }
226 }
227 break;
228 }
229
230 case PIX_PROGRESS:
231 {
232 switch(img->fmt)
233 {
234 case PIX_FMT_YUV://YV16
235 {
236 y=img->yaddr+img->width*r+c;
237 u=img->uaddr+img->width/2*r+c/2;
238 v=img->vaddr+img->width/2*r+c/2;
239 break;
240 }
241
242 case PIX_FMT_YVU:
243 {
244 y=img->yaddr+img->width*r+c;
245 u=img->uaddr+img->width/2*r+c/2;
246 v=img->vaddr+img->width/2*r+c/2;
247 char *u1=u, *v1=v;
248 u = v1;
249 v = u1;
250 break;
251 }
252 }
253 break;
254 }
255 }
256 break;
257 }
258 case PIX_SAMPLE_420:
259 {
260 ylinebytes=img->width;
261 ulinebytes=vlinebytes=img->width/2;
262 switch(img->ip)
263 {
264 case PIX_INTLACED:
265 {
266 if(r&1){
267 ylineaddr=img->oddyaddr+ylinebytes*r/2;
268 ulineaddr=img->odduaddr+ulinebytes*r/4;
269 vlineaddr=img->oddvaddr+vlinebytes*r/4;
270 }
271 else{
272 ylineaddr=img->evenyaddr+ylinebytes*r/2;
273 ulineaddr=img->evenuaddr+ulinebytes*r/4;
274 vlineaddr=img->evenvaddr+vlinebytes*r/4;
275 }
276
277 switch(img->fmt)
278 {
279 //TODO
280 case PIX_FMT_YUV:
281 {
282 y=ylineaddr+c;
283 u=ulineaddr+c/2;
284 v=vlineaddr+c/2;
285 break;
286 }
287
288 case PIX_FMT_YVU:
289 {//TODO
290 y=ylineaddr+c;
291 u=ulineaddr+c/2;
292 v=vlineaddr+c/2;
293 char *u1=u, *v1=v;
294 u = v1;
295 v = u1;
296 break;
297 }
298 }
299 break;
300 }
301
302 case PIX_PROGRESS:
303 {
304 switch(img->fmt)
305 {
306 case PIX_FMT_YUV://IYUV, I420
307 {
308 y=img->yaddr+img->width*r+c;
309 u=img->uaddr+img->width/2*(r/2)+c/2;
310 v=img->vaddr+img->width/2*(r/2)+c/2;
311 break;
312 }
313
314 case PIX_FMT_YVU://YV12
315 {
316 y=img->yaddr+img->width*r+c;
317 u=img->uaddr+img->width/2*(r/2)+c/2;
318 v=img->vaddr+img->width/2*(r/2)+c/2;
319 char *u1=u, *v1=v;
320 u = v1;
321 v = u1;
322 break;
323 }
324 }
325 break;
326 }
327 }
328 break;
329 }
330 }
331 break;
332 }
333 case PIX_SEMI_PLANAR:
334 {
335 char *ylineaddr=0,*uvlineaddr=0;
336 int ylinebytes=0, uvlinebytes=0;
337 char y0=0,u0=0,v0=0;
338
339 switch(img->samp)
340 {
341 case PIX_SAMPLE_422:
342 {
343 ylinebytes=img->width;
344 uvlinebytes=img->width;///2;
345 switch(img->ip)
346 {
347 case PIX_INTLACED:
348 {
349 if(r&1){
350 ylineaddr=img->oddyaddr+ylinebytes*r/2;
351 uvlineaddr=img->odduaddr+uvlinebytes*r/2;
352 }
353 else{
354 ylineaddr=img->evenyaddr+ylinebytes*r/2;
355 uvlineaddr=img->evenuaddr+uvlinebytes*r/2;
356 }
357
358 switch(img->fmt)
359 {
360 //TODO
361 //按照FOURCC YV16格式编写,显示出来不对,实际格式未知YUVTools也没有给出FOURCC代码
362 case PIX_FMT_YUV:
363 {
364 y=ylineaddr+c;
365 u=uvlineaddr+c/2*2;
366 v=u+1;
367 break;
368 }
369
370 case PIX_FMT_YVU:
371 {//TODO
372 y=ylineaddr+c;
373 u=uvlineaddr+c/2*2;
374 v=u+1;
375 char *u1=u, *v1=v;
376 u = v1;
377 v = u1;
378 break;
379 }
380 }
381 break;
382 }
383
384 case PIX_PROGRESS:
385 {
386 ylineaddr=img->yaddr+ylinebytes*r;
387 uvlineaddr=img->uvaddr+uvlinebytes*r;
388 switch(img->fmt)
389 {
390 case PIX_FMT_YUV://YV16
391 {
392 y=ylineaddr+c;
393 u=uvlineaddr+c/2*2;
394 v=u+1;
395 break;
396 }
397
398 case PIX_FMT_YVU:
399 {
400 y=ylineaddr+c;
401 u=uvlineaddr+c/2*2;
402 v=u+1;
403 char *u1=u, *v1=v;
404 u = v1;
405 v = u1;
406 break;
407 }
408 }
409 break;
410 }
411 }
412 break;
413 }
414 case PIX_SAMPLE_420:
415 {
416 ylinebytes=img->width;
417 uvlinebytes=img->width;///2;
418 switch(img->ip)
419 {
420 case PIX_INTLACED:
421 {
422 if(r&1){
423 ylineaddr=img->oddyaddr+ylinebytes*r/2;
424 uvlineaddr=img->odduaddr+uvlinebytes*r/4;
425 }
426 else{
427 ylineaddr=img->evenyaddr+ylinebytes*r/2;
428 uvlineaddr=img->evenuaddr+uvlinebytes*r/4;
429 }
430
431 switch(img->fmt)
432 {
433 //TODO
434 case PIX_FMT_YUV:
435 {
436 y=ylineaddr+c;
437 u=uvlineaddr+c/2*2;
438 v=u+1;
439 break;
440 }
441
442 case PIX_FMT_YVU:
443 {//TODO
444 y=ylineaddr+c;
445 u=uvlineaddr+c/2*2;
446 v=u+1;
447 char *u1=u, *v1=v;
448 u = v1;
449 v = u1;
450 break;
451 }
452 }
453 break;
454 }
455
456 case PIX_PROGRESS:
457 {
458 ylineaddr=img->yaddr+ylinebytes*r;
459 uvlineaddr=img->uvaddr+uvlinebytes*r/2;
460 switch(img->fmt)
461 {
462 case PIX_FMT_YUV://YV16
463 {
464 y=ylineaddr+c;
465 u=uvlineaddr+c/2*2;
466 v=u+1;
467 break;
468 }
469
470 case PIX_FMT_YVU:
471 {
472 y=ylineaddr+c;
473 u=uvlineaddr+c/2*2;
474 v=u+1;
475 char *u1=u, *v1=v;
476 u = v1;
477 v = u1;
478 break;
479 }
480 }
481 break;
482 }
483 }
484 break;
485 }
486 }
487 }
488 }
489
490 if(y&&u&&v&&py&&pu&&pv)
491 {
492 int byte_offset = 4*(r*176/2+c/2);
493 char *yvyu= img->evenyuvaddr+byte_offset;
494 if(c&1){
495 if(yvyu+2!=y||yvyu+1!=v||yvyu+3!=u)
496 byte_offset++;
497 }
498 else{
499 if(yvyu+0!=y||yvyu+1!=v||yvyu+3!=u)
500 byte_offset++;
501 }
502 *py = *y;
503 *pu = *u;
504 *pv = *v;
505 }
506 }
507 YuvImg* yuvimg_load(const char*fname,
508 PixFmtSamp samp, PixFmtYUV fmt, PixIntPro ip, PixPackPlanar pp,
509 int w, int h)
510 {
511 YuvImg *ret=0;
512 FILE *pf = fopen(fname, "rb");
513 if(pf){
514 int datalen=sizeof(*ret);
515 int ylen=w*h,ulen=0,vlen=0;
516
517 switch(samp)
518 {
519 case PIX_SAMPLE_422:
520 {
521 ulen=vlen=w*h/2;
522 datalen+=w*h*2;
523 break;
524 }
525
526 case PIX_SAMPLE_420:
527 {
528 ulen=vlen=w*h/4;
529 datalen+=w*h*3/2;
530 break;
531 }
532 }
533 ret = (YuvImg*)malloc(datalen+8);
534 memset(ret, 0, datalen+8);
535 ret->samp = samp;
536 ret->fmt=fmt;
537 ret->ip=ip;
538 ret->pp=pp;
539 ret->width=w;
540 ret->height=h;
541 switch(ip)
542 {
543 case PIX_INTLACED:
544 {
545 switch(pp)
546 {
547 case PIX_PACKED:
548 ret->evenyuvaddr=(char*)(ret+1);
549 ret->oddyuvaddr=ret->evenyuvaddr+(datalen-sizeof(*ret))/2;
550 fread(ret->evenyuvaddr, datalen-sizeof(*ret), 1, pf);
551 break;
552 case PIX_PLANAR:
553 ret->evenyaddr=(char*)(ret+1);
554 ret->evenuaddr=(char*)(ret->evenyaddr+ylen/2);
555 ret->evenvaddr=(char*)(ret->evenuaddr+ulen/2);
556 ret->oddyaddr=(char*)(ret->evenyaddr+(datalen-sizeof(*ret))/2);
557 ret->odduaddr=(char*)(ret->oddyaddr+ylen/2);
558 ret->oddvaddr=(char*)(ret->odduaddr+ulen/2);
559 fread(ret->evenyaddr, datalen-sizeof(*ret), 1, pf);
560 break;
561 }
562 break;
563 }
564 case PIX_PROGRESS:
565 {
566 switch(pp)
567 {
568 case PIX_PACKED:
569 ret->yuvaddr=(char*)(ret+1);
570 fread(ret->yuvaddr, datalen-sizeof(*ret), 1, pf);
571 break;
572 case PIX_PLANAR:
573 ret->yaddr=(char*)(ret+1);
574 ret->uaddr=(char*)(ret->yaddr+ylen);
575 ret->vaddr=(char*)(ret->uaddr+ulen);
576 fread(ret->yaddr, datalen-sizeof(*ret), 1, pf);
577 break;
578 }
579 break;
580 }
581 }
582 fclose(pf);
583 }
584 return ret;
585 }
586 YuvImg* yuvimg_construct(PixFmtSamp samp, PixFmtYUV fmt, PixIntPro ip, PixPackPlanar pp,
587 int w, int h,
588 char*buffer,
589 YuvImg *ret
590 )
591 {
592 int datalen=sizeof(*ret);
593 int ylen=w*h,ulen=0,vlen=0;
594 switch(samp)
595 {
596 case PIX_SAMPLE_422:
597 {
598 ulen=vlen=w*h/2;
599 datalen+=w*h*2;
600 break;
601 }
602
603 case PIX_SAMPLE_420:
604 {
605 ulen=vlen=w*h/4;
606 datalen+=w*h*3/2;
607 break;
608 }
609 }
610 ret->samp = samp;
611 ret->fmt=fmt;
612 ret->ip=ip;
613 ret->pp=pp;
614 ret->width=w;
615 ret->height=h;
616 switch(ip)
617 {
618 case PIX_INTLACED:
619 {
620 switch(pp)
621 {
622 case PIX_PACKED:
623 ret->evenyuvaddr=buffer;//(char*)(ret+1);
624 ret->oddyuvaddr=ret->evenyuvaddr+(datalen-sizeof(*ret))/2;
625 break;
626 case PIX_PLANAR:
627 ret->evenyaddr=buffer;//(char*)(ret+1);
628 ret->evenuaddr=(char*)(ret->evenyaddr+ylen/2);
629 ret->evenvaddr=(char*)(ret->evenuaddr+ulen/2);
630 ret->oddyaddr=(char*)(ret->evenyaddr+(datalen-sizeof(*ret))/2);
631 ret->odduaddr=(char*)(ret->oddyaddr+ylen/2);
632 ret->oddvaddr=(char*)(ret->odduaddr+ulen/2);
633 break;
634 case PIX_SEMI_PLANAR:
635 ret->evenyaddr=buffer;//(char*)(ret+1);
636 ret->evenuvaddr=(char*)(ret->evenyaddr+ylen/2);
637 ret->oddyaddr=(char*)(ret->evenyaddr+(datalen-sizeof(*ret))/2);
638 ret->odduvaddr=(char*)(ret->oddyaddr+ylen/2);
639 break;
640 }
641 break;
642 }
643 case PIX_PROGRESS:
644 {
645 switch(pp)
646 {
647 case PIX_PACKED:
648 ret->yuvaddr=buffer;//(char*)(ret+1);
649 break;
650 case PIX_PLANAR:
651 ret->yaddr=buffer;//(char*)(ret+1);
652 ret->uaddr=(char*)(ret->yaddr+ylen);
653 ret->vaddr=(char*)(ret->uaddr+ulen);
654 break;
655 case PIX_SEMI_PLANAR:
656 ret->yaddr=buffer;//(char*)(ret+1);
657 ret->uvaddr=(char*)(ret->yaddr+ylen);
658 break;
659 }
660 break;
661 }
662 }
663 return ret;
664 }
665 void yuvimg_free(YuvImg**img)
666 {
667 free(*img);
668 *img = 0;
669 }
670 Bitmap* yuvimg_2bmp(YuvImg*img)
671 {
672 Bitmap*ret=0;
673 if(img)
674 {
675 ret = bmp_create_2(img->width, img->height);
676 if(ret){
677 int row, col;
678 for(row=0; row<img->height; row++)
679 {
680 for(col=0; col<img->width; col++)
681 {
682 char y=0, u=0, v=0;
683 yuvimg_getpix(img, row, col, &y, &u, &v);
684 char r = y + 1.4075 * (v - 128);
685 char g = y - 0.3455 * (u - 128) - (0.7169 * (v - 128));
686 char b = y + 1.7790 * (u - 128);
687 bmp_set_pix(ret, r, g, b, row, col);
688 }
689 }
690 }
691 }
692 return ret;
693 }
694 void yuvimg_show(YuvImg*img,CDC*pDC,int offx, int offy, const char*fname)
695 {
696 if(img)
697 {
698 int row, col;
699 Bitmap*ret=bmp_create_2(img->width, img->height);
700 for(row=0; row<img->height; row++)
701 {
702 for(col=0; col<img->width; col++)
703 {
704 unsigned char y=0, u=0, v=0;
705 yuvimg_getpix(img, row, col, (char*)&y, (char*)&u, (char*)&v);
706 unsigned char r = y + 1.4075 * (v - 128);
707 unsigned char g = y - 0.3455 * (u - 128) - (0.7169 * (v - 128));
708 unsigned char b = y + 1.7790 * (u - 128);
709 POINT pt;
710 unsigned char Y=(r*30+g*59+b*11)/100;
711 /*
712 if(row&1){
713 //pt.x = img->width-col+offx;
714 if(col<img->width/2)
715 pt.x = img->width/2+col+offx;
716 else
717 pt.x = col-img->width/2;
718 }
719 else*/
720 pt.x = col+offx;
721 pt.y = row+offy;
722 pDC->SetPixel(pt, RGB(r,g,b));
723 pt.x+=img->width+20;
724 pDC->SetPixel(pt, RGB(Y,Y,Y));
725 pt.x+=img->width+20;
726 pDC->SetPixel(pt, RGB(Y,Y,0));
727 bmp_set_pix(ret, r, g, b, col, row);
728 }
729 }
730 bmp_save_raw_argb(ret, fname);
731 bmp_free(&ret);
732 }
733 }
734 /*
735 422 progress YVYU+UYVY+YUYV
736 "tulips_yvyu422_prog_packed_qcif.yuv",//"tulips_uyvy422_prog_packed_qcif.yuv",//"tulips_yuyv422_prog_packed_qcif.yuv",
737 PIX_SAMPLE_422,
738 PIX_FMT_YVYU,//PIX_FMT_UYVY,//PIX_FMT_YUYV,
739 PIX_PROGRESS,
740 PIX_PACKED,
741 176,
742 144
743 "tulips_yuv422_inter_planar_qcif.yuv",
744 PIX_SAMPLE_422,
745 PIX_FMT_YUV,
746 PIX_INTLACED,
747 PIX_PLANAR,
748 176,
749 144
750 */
751 typedef struct{
752 const char*fname;
753 enum PixFmtSamp samp;
754 enum PixFmtYUV fmt;
755 enum PixIntPro ip;
756 enum PixPackPlanar pp;
757 int w;
758 int h;
759 }TestFile;
760 #if 0
761 void CTab_calView::OnDraw(CDC* pDC)
762 {
763 CTab_calDoc* pDoc = GetDocument();
764 m_pDC = pDC;
765 //pDC->TextOut(0,0,"一");
766 //chars2bmp(pDC);
767 //if(file_name.size())
768 {
769 int row,col,find;
770 row=col=0;
771 TestFile test_files[]={
772 {"tulips_yvyu422_inter_packed_qcif.yuv", PIX_SAMPLE_422, PIX_FMT_YVYU, PIX_INTLACED, PIX_PACKED, 176, 144},
773 {"tulips_uyvy422_inter_packed_qcif.yuv", PIX_SAMPLE_422, PIX_FMT_UYVY, PIX_INTLACED, PIX_PACKED, 176, 144},
774 {"tulips_yuyv422_inter_packed_qcif.yuv", PIX_SAMPLE_422, PIX_FMT_YUYV, PIX_INTLACED, PIX_PACKED, 176, 144},
775 {"tulips_yvyu422_prog_packed_qcif.yuv", PIX_SAMPLE_422, PIX_FMT_YVYU, PIX_PROGRESS, PIX_PACKED, 176, 144},
776
777 {"tulips_uyvy422_prog_packed_qcif.yuv", PIX_SAMPLE_422, PIX_FMT_UYVY, PIX_PROGRESS, PIX_PACKED, 176, 144},
778 {"tulips_yuyv422_prog_packed_qcif.yuv", PIX_SAMPLE_422, PIX_FMT_YUYV, PIX_PROGRESS, PIX_PACKED, 176, 144},
779 {"tulips_yuv422_inter_planar_qcif.yuv", PIX_SAMPLE_422, PIX_FMT_YUV, PIX_INTLACED, PIX_PLANAR, 176, 144},
780 {"tulips_yvu422_inter_planar_qcif.yuv", PIX_SAMPLE_422, PIX_FMT_YVU, PIX_INTLACED, PIX_PLANAR, 176, 144},
781
782 {"tulips_yuv422_prog_planar_qcif.yuv", PIX_SAMPLE_422, PIX_FMT_YUV, PIX_PROGRESS, PIX_PLANAR, 176, 144},
783 {"tulips_yvu422_prog_planar_qcif.yuv", PIX_SAMPLE_422, PIX_FMT_YVU, PIX_PROGRESS, PIX_PLANAR, 176, 144},
784 {"tulips_yuv420_inter_planar_qcif.yuv", PIX_SAMPLE_420, PIX_FMT_YUV, PIX_INTLACED, PIX_PLANAR, 176, 144},
785 {"tulips_yvu420_inter_planar_qcif.yuv", PIX_SAMPLE_420, PIX_FMT_YVU, PIX_INTLACED, PIX_PLANAR, 176, 144},
786
787 {"tulips_yuv420_prog_planar_qcif.yuv", PIX_SAMPLE_420, PIX_FMT_YUV, PIX_PROGRESS, PIX_PLANAR, 176, 144},
788 {"tulips_yvu420_prog_planar_qcif.yuv", PIX_SAMPLE_420, PIX_FMT_YVU, PIX_PROGRESS, PIX_PLANAR, 176, 144},
789
790 };
791 //bmp_show(file_name.c_str(), pDC);
792 for(find=0; find<sizeof(test_files)/sizeof(*test_files); find++)
793 {
794 YuvImg *img = yuvimg_load(test_files[find].fname,
795 test_files[find].samp,
796 test_files[find].fmt,
797 test_files[find].ip,
798 test_files[find].pp,
799 test_files[find].w,
800 test_files[find].h
801 );
802
803 yuvimg_show(img,pDC, 188*col, row*168);
804 col++;
805 if(col>=5)
806 row++,col=0;
807 yuvimg_free(&img);
808 }
809 file_name.clear();
810 }
811 // TODO: add draw code for native data here
812 }
813 #endif