yuv格式解析

相关标准描述参考网站:http://www.fourcc.org/
参考解析工具和图片参考网站:http://www.sunrayimage.com/examples.html
网上有很多解析YUV格式的工具,觉得还是sunrayimage的工具比较全还有示例图片。
只有代码,花半天时间折腾出来的。
  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

posted on 2016-11-01 18:01 zlf 阅读(469) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


导航

<2016年11月>
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

统计

常用链接

留言簿(1)

随笔档案

文章档案

搜索

最新评论

阅读排行榜

评论排行榜