📄 image.c
字号:
break; case XVID_CSP_BGR: safe_packed_conv( src[0], src_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?bgri_to_yv12 :bgr_to_yv12, interlacing?bgri_to_yv12_c:bgr_to_yv12_c, 3); break; case XVID_CSP_BGRA: safe_packed_conv( src[0], src_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?bgrai_to_yv12 :bgra_to_yv12, interlacing?bgrai_to_yv12_c:bgra_to_yv12_c, 4); break; case XVID_CSP_ABGR : safe_packed_conv( src[0], src_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?abgri_to_yv12 :abgr_to_yv12, interlacing?abgri_to_yv12_c:abgr_to_yv12_c, 4); break; case XVID_CSP_RGBA : safe_packed_conv( src[0], src_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?rgbai_to_yv12 :rgba_to_yv12, interlacing?rgbai_to_yv12_c:rgba_to_yv12_c, 4); break; case XVID_CSP_ARGB: safe_packed_conv( src[0], src_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?argbi_to_yv12 : argb_to_yv12, interlacing?argbi_to_yv12_c: argb_to_yv12_c, 4); break; case XVID_CSP_YUY2: safe_packed_conv( src[0], src_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?yuyvi_to_yv12 :yuyv_to_yv12, interlacing?yuyvi_to_yv12_c:yuyv_to_yv12_c, 2); break; case XVID_CSP_YVYU: /* u/v swapped */ safe_packed_conv( src[0], src_stride[0], image->y, image->v, image->u, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?yuyvi_to_yv12 :yuyv_to_yv12, interlacing?yuyvi_to_yv12_c:yuyv_to_yv12_c, 2); break; case XVID_CSP_UYVY: safe_packed_conv( src[0], src_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?uyvyi_to_yv12 :uyvy_to_yv12, interlacing?uyvyi_to_yv12_c:uyvy_to_yv12_c, 2); break; case XVID_CSP_I420: /* YCbCr == YUV == internal colorspace for MPEG */ yv12_to_yv12(image->y, image->u, image->v, edged_width, edged_width2, src[0], src[0] + src_stride[0]*height, src[0] + src_stride[0]*height + (src_stride[0]/2)*height2, src_stride[0], src_stride[0]/2, width, height, (csp & XVID_CSP_VFLIP)); break; case XVID_CSP_YV12: /* YCrCb == YVA == U and V plane swapped */ yv12_to_yv12(image->y, image->v, image->u, edged_width, edged_width2, src[0], src[0] + src_stride[0]*height, src[0] + src_stride[0]*height + (src_stride[0]/2)*height2, src_stride[0], src_stride[0]/2, width, height, (csp & XVID_CSP_VFLIP)); break; case XVID_CSP_PLANAR: /* YCbCr with arbitrary pointers and different strides for Y and UV */ yv12_to_yv12(image->y, image->u, image->v, edged_width, edged_width2, src[0], src[1], src[2], src_stride[0], src_stride[1], /* v: dst_stride[2] not yet supported */ width, height, (csp & XVID_CSP_VFLIP)); break; case XVID_CSP_NULL: break; default : return -1; } /* pad out image when the width and/or height is not a multiple of 16 */ if (width & 15) { int i; int pad_width = 16 - (width&15); for (i = 0; i < height; i++) { memset(image->y + i*edged_width + width, *(image->y + i*edged_width + width - 1), pad_width); } for (i = 0; i < height/2; i++) { memset(image->u + i*edged_width2 + width2, *(image->u + i*edged_width2 + width2 - 1),pad_width/2); memset(image->v + i*edged_width2 + width2, *(image->v + i*edged_width2 + width2 - 1),pad_width/2); } } if (height & 15) { int pad_height = 16 - (height&15); int length = ((width+15)/16)*16; int i; for (i = 0; i < pad_height; i++) { memcpy(image->y + (height+i)*edged_width, image->y + (height-1)*edged_width,length); } for (i = 0; i < pad_height/2; i++) { memcpy(image->u + (height2+i)*edged_width2, image->u + (height2-1)*edged_width2,length/2); memcpy(image->v + (height2+i)*edged_width2, image->v + (height2-1)*edged_width2,length/2); } }/* if (interlacing) image_printf(image, edged_width, height, 5,5, "[i]"); image_dump_yuvpgm(image, edged_width, ((width+15)/16)*16, ((height+15)/16)*16, "\\encode.pgm");*/ return 0;}intimage_output(IMAGE * image, uint32_t width, int height, uint32_t edged_width, uint8_t * dst[4], int dst_stride[4], int csp, int interlacing){ const int edged_width2 = edged_width/2; int height2 = height/2;/* if (interlacing) image_printf(image, edged_width, height, 5,100, "[i]=%i,%i",width,height); image_dump_yuvpgm(image, edged_width, width, height, "\\decode.pgm");*/ switch (csp & ~XVID_CSP_VFLIP) { case XVID_CSP_RGB555: safe_packed_conv( dst[0], dst_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?yv12_to_rgb555i :yv12_to_rgb555, interlacing?yv12_to_rgb555i_c:yv12_to_rgb555_c, 2); return 0; case XVID_CSP_RGB565: safe_packed_conv( dst[0], dst_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?yv12_to_rgb565i :yv12_to_rgb565, interlacing?yv12_to_rgb565i_c:yv12_to_rgb565_c, 2); return 0; case XVID_CSP_BGR: safe_packed_conv( dst[0], dst_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?yv12_to_bgri :yv12_to_bgr, interlacing?yv12_to_bgri_c:yv12_to_bgr_c, 3); return 0; case XVID_CSP_BGRA: safe_packed_conv( dst[0], dst_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?yv12_to_bgrai :yv12_to_bgra, interlacing?yv12_to_bgrai_c:yv12_to_bgra_c, 4); return 0; case XVID_CSP_ABGR: safe_packed_conv( dst[0], dst_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?yv12_to_abgri :yv12_to_abgr, interlacing?yv12_to_abgri_c:yv12_to_abgr_c, 4); return 0; case XVID_CSP_RGBA: safe_packed_conv( dst[0], dst_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?yv12_to_rgbai :yv12_to_rgba, interlacing?yv12_to_rgbai_c:yv12_to_rgba_c, 4); return 0; case XVID_CSP_ARGB: safe_packed_conv( dst[0], dst_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?yv12_to_argbi :yv12_to_argb, interlacing?yv12_to_argbi_c:yv12_to_argb_c, 4); return 0; case XVID_CSP_YUY2: safe_packed_conv( dst[0], dst_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?yv12_to_yuyvi :yv12_to_yuyv, interlacing?yv12_to_yuyvi_c:yv12_to_yuyv_c, 2); return 0; case XVID_CSP_YVYU: /* u,v swapped */ safe_packed_conv( dst[0], dst_stride[0], image->y, image->v, image->u, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?yv12_to_yuyvi :yv12_to_yuyv, interlacing?yv12_to_yuyvi_c:yv12_to_yuyv_c, 2); return 0; case XVID_CSP_UYVY: safe_packed_conv( dst[0], dst_stride[0], image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP), interlacing?yv12_to_uyvyi :yv12_to_uyvy, interlacing?yv12_to_uyvyi_c:yv12_to_uyvy_c, 2); return 0; case XVID_CSP_I420: /* YCbCr == YUV == internal colorspace for MPEG */ yv12_to_yv12(dst[0], dst[0] + dst_stride[0]*height, dst[0] + dst_stride[0]*height + (dst_stride[0]/2)*height2, dst_stride[0], dst_stride[0]/2, image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP)); return 0; case XVID_CSP_YV12: /* YCrCb == YVU == U and V plane swapped */ yv12_to_yv12(dst[0], dst[0] + dst_stride[0]*height, dst[0] + dst_stride[0]*height + (dst_stride[0]/2)*height2, dst_stride[0], dst_stride[0]/2, image->y, image->v, image->u, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP)); return 0; case XVID_CSP_PLANAR: /* YCbCr with arbitrary pointers and different strides for Y and UV */ yv12_to_yv12(dst[0], dst[1], dst[2], dst_stride[0], dst_stride[1], /* v: dst_stride[2] not yet supported */ image->y, image->u, image->v, edged_width, edged_width2, width, height, (csp & XVID_CSP_VFLIP)); return 0; case XVID_CSP_INTERNAL : dst[0] = image->y; dst[1] = image->u; dst[2] = image->v; dst_stride[0] = edged_width; dst_stride[1] = edged_width/2; dst_stride[2] = edged_width/2; return 0; case XVID_CSP_NULL: case XVID_CSP_SLICE: return 0; } return -1;}floatimage_psnr(IMAGE * orig_image, IMAGE * recon_image, uint16_t stride, uint16_t width, uint16_t height){ int32_t diff, x, y, quad = 0; uint8_t *orig = orig_image->y; uint8_t *recon = recon_image->y; float psnr_y; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { diff = *(orig + x) - *(recon + x); quad += diff * diff; } orig += stride; recon += stride; } psnr_y = (float) quad / (float) (width * height); if (psnr_y) { psnr_y = (float) (255 * 255) / psnr_y; psnr_y = 10 * (float) log10(psnr_y); } else psnr_y = (float) 99.99; return psnr_y;}float sse_to_PSNR(long sse, int pixels){ if (sse==0) return 99.99F; return 48.131F - 10*(float)log10((float)sse/(float)(pixels)); /* log10(255*255)=4.8131 */}long plane_sse(uint8_t *orig, uint8_t *recon, uint16_t stride, uint16_t width, uint16_t height){ int y, bwidth, bheight; long sse = 0; bwidth = width & (~0x07); bheight = height & (~0x07); /* Compute the 8x8 integer part */ for (y = 0; y<bheight; y += 8) { int x; /* Compute sse for the band */ for (x = 0; x<bwidth; x += 8) sse += sse8_8bit(orig + x, recon + x, stride); /* remaining pixels of the 8 pixels high band */ for (x = bwidth; x < width; x++) { int diff; diff = *(orig + 0*stride + x) - *(recon + 0*stride + x); sse += diff * diff; diff = *(orig + 1*stride + x) - *(recon + 1*stride + x); sse += diff * diff; diff = *(orig + 2*stride + x) - *(recon + 2*stride + x); sse += diff * diff; diff = *(orig + 3*stride + x) - *(recon + 3*stride + x); sse += diff * diff; diff = *(orig + 4*stride + x) - *(recon + 4*stride + x); sse += diff * diff; diff = *(orig + 5*stride + x) - *(recon + 5*stride + x); sse += diff * diff; diff = *(orig + 6*stride + x) - *(recon + 6*stride + x); sse += diff * diff; diff = *(orig + 7*stride + x) - *(recon + 7*stride + x); sse += diff * diff; } orig += 8*stride; recon += 8*stride; } /* Compute the down rectangle sse */ for (y = bheight; y < height; y++) { int x; for (x = 0; x < width; x++) { int diff; diff = *(orig + x) - *(recon + x); sse += diff * diff; } orig += stride; recon += stride; } return (sse);}#if 0#include <stdio.h>#include <string.h>int image_dump_pgm(uint8_t * bmp, uint32_t width, uint32_t height, char * filename){ FILE * f; char hdr[1024]; f = fopen(filename, "wb"); if ( f == NULL) { return -1; } sprintf(hdr, "P5\n#xvid\n%i %i\n255\n", width, height); fwrite(hdr, strlen(hdr), 1, f); fwrite(bmp, width, height, f); fclose(f); return 0;}/* dump image+edges to yuv pgm files */int image_dump(IMAGE * image, uint32_t edged_width, uint32_t edged_height, char * path, int number){ char filename[1024]; sprintf(filename, "%s_%i_%c.pgm", path, number, 'y'); image_dump_pgm( image->y - (EDGE_SIZE * edged_width + EDGE_SIZE), edged_width, edged_height, filename); sprintf(filename, "%s_%i_%c.pgm", path, number, 'u'); image_dump_pgm( image->u - (EDGE_SIZE2 * edged_width / 2 + EDGE_SIZE2), edged_width / 2, edged_height / 2, filename); sprintf(filename, "%s_%i_%c.pgm", path, number, 'v'); image_dump_pgm( image->v - (EDGE_SIZE2 * edged_width / 2 + EDGE_SIZE2), edged_width / 2, edged_height / 2, filename); return 0;}#endif/* dump image to yuvpgm file */#include <stdio.h>intimage_dump_yuvpgm(const IMAGE * image, const uint32_t edged_width, const uint32_t width, const uint32_t height, char *filename){ FILE *f; char hdr[1024]; uint32_t i; uint8_t *bmp1; uint8_t *bmp2; f = fopen(filename, "wb"); if (f == NULL) { return -1; } sprintf(hdr, "P5\n#xvid\n%i %i\n255\n", width, (3 * height) / 2); fwrite(hdr, strlen(hdr), 1, f); bmp1 = image->y; for (i = 0; i < height; i++) { fwrite(bmp1, width, 1, f); bmp1 += edged_width; } bmp1 = image->u; bmp2 = image->v; for (i = 0; i < height / 2; i++) { fwrite(bmp1, width / 2, 1, f); fwrite(bmp2, width / 2, 1, f); bmp1 += edged_width / 2; bmp2 += edged_width / 2; } fclose(f); return 0;}floatimage_mad(const IMAGE * img1, const IMAGE * img2, uint32_t stride, uint32_t width, uint32_t height){ const uint32_t stride2 = stride / 2; const uint32_t width2 = width / 2; const uint32_t height2 = height / 2; uint32_t x, y; uint32_t sum = 0; for (y = 0; y < height; y++) for (x = 0; x < width; x++) sum += abs(img1->y[x + y * stride] - img2->y[x + y * stride]); for (y = 0; y < height2; y++) for (x = 0; x < width2; x++) sum += abs(img1->u[x + y * stride2] - img2->u[x + y * stride2]); for (y = 0; y < height2; y++) for (x = 0; x < width2; x++) sum += abs(img1->v[x + y * stride2] - img2->v[x + y * stride2]); return (float) sum / (width * height * 3 / 2);}voidoutput_slice(IMAGE * cur, int stride, int width, xvid_image_t* out_frm, int mbx, int mby,int mbl) { uint8_t *dY,*dU,*dV,*sY,*sU,*sV; int stride2 = stride >> 1; int w = mbl << 4, w2,i; if(w > width) w = width; w2 = w >> 1; dY = (uint8_t*)out_frm->plane[0] + (mby << 4) * out_frm->stride[0] + (mbx << 4); dU = (uint8_t*)out_frm->plane[1] + (mby << 3) * out_frm->stride[1] + (mbx << 3); dV = (uint8_t*)out_frm->plane[2] + (mby << 3) * out_frm->stride[2] + (mbx << 3); sY = cur->y + (mby << 4) * stride + (mbx << 4); sU = cur->u + (mby << 3) * stride2 + (mbx << 3); sV = cur->v + (mby << 3) * stride2 + (mbx << 3); for(i = 0 ; i < 16 ; i++) { memcpy(dY,sY,w); dY += out_frm->stride[0]; sY += stride; } for(i = 0 ; i < 8 ; i++) { memcpy(dU,sU,w2); dU += out_frm->stride[1]; sU += stride2; } for(i = 0 ; i < 8 ; i++) { memcpy(dV,sV,w2); dV += out_frm->stride[2]; sV += stride2; }}voidimage_clear(IMAGE * img, int width, int height, int edged_width, int y, int u, int v){ uint8_t * p; int i; p = img->y; for (i = 0; i < height; i++) { memset(p, y, width); p += edged_width; } p = img->u; for (i = 0; i < height/2; i++) { memset(p, u, width/2); p += edged_width/2; } p = img->v; for (i = 0; i < height/2; i++) { memset(p, v, width/2); p += edged_width/2; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -