int adm(const char *ref_path, const char *dis_path, int w, int h, const char *fmt) { double score = 0; double score_num = 0; double score_den = 0; double scores[2*4]; number_t *ref_buf = 0; number_t *dis_buf = 0; number_t *temp_buf = 0; FILE *ref_rfile = 0; FILE *dis_rfile = 0; size_t data_sz; int stride; int ret = 1; if (w <= 0 || h <= 0 || (size_t)w > ALIGN_FLOOR(INT_MAX) / sizeof(number_t)) { goto fail_or_end; } stride = ALIGN_CEIL(w * sizeof(number_t)); if ((size_t)h > SIZE_MAX / stride) { goto fail_or_end; } data_sz = (size_t)stride * h; if (!(ref_buf = aligned_malloc(data_sz, MAX_ALIGN))) { printf("error: aligned_malloc failed for ref_buf.\n"); fflush(stdout); goto fail_or_end; } if (!(dis_buf = aligned_malloc(data_sz, MAX_ALIGN))) { printf("error: aligned_malloc failed for dis_buf.\n"); fflush(stdout); goto fail_or_end; } if (!(temp_buf = aligned_malloc(data_sz * 2, MAX_ALIGN))) { printf("error: aligned_malloc failed for temp_buf.\n"); fflush(stdout); goto fail_or_end; } if (!(ref_rfile = fopen(ref_path, "rb"))) { printf("error: fopen ref_path %s failed\n", ref_path); fflush(stdout); goto fail_or_end; } if (!(dis_rfile = fopen(dis_path, "rb"))) { printf("error: fopen dis_path %s failed.\n", dis_path); fflush(stdout); goto fail_or_end; } size_t offset; if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv420p10le")) { if ((w * h) % 2 != 0) { printf("error: (w * h) %% 2 != 0, w = %d, h = %d.\n", w, h); fflush(stdout); goto fail_or_end; } offset = w * h / 2; } else if (!strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv422p10le")) { offset = w * h; } else if (!strcmp(fmt, "yuv444p") || !strcmp(fmt, "yuv444p10le")) { offset = w * h * 2; } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } int frm_idx = 0; while (1) { // read ref y if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { ret = read_image_b(ref_rfile, ref_buf, OPT_RANGE_PIXEL_OFFSET, w, h, stride); } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { ret = read_image_w(ref_rfile, ref_buf, OPT_RANGE_PIXEL_OFFSET, w, h, stride); } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } if (ret) { if (feof(ref_rfile)) { ret = 0; // OK if end of file } goto fail_or_end; } // read dis y if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { ret = read_image_b(dis_rfile, dis_buf, OPT_RANGE_PIXEL_OFFSET, w, h, stride); } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { ret = read_image_w(dis_rfile, dis_buf, OPT_RANGE_PIXEL_OFFSET, w, h, stride); } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } if (ret) { if (feof(dis_rfile)) { ret = 0; // OK if end of file } goto fail_or_end; } // compute if ((ret = compute_adm(ref_buf, dis_buf, w, h, stride, stride, &score, &score_num, &score_den, scores, ADM_BORDER_FACTOR))) { printf("error: compute_adm failed.\n"); fflush(stdout); goto fail_or_end; } // print printf("adm: %d %f\n", frm_idx, score); fflush(stdout); printf("adm_num: %d %f\n", frm_idx, score_num); fflush(stdout); printf("adm_den: %d %f\n", frm_idx, score_den); fflush(stdout); for(int scale=0;scale<4;scale++) { printf("adm_num_scale%d: %d %f\n", scale, frm_idx, scores[2*scale]); fflush(stdout); printf("adm_den_scale%d: %d %f\n", scale, frm_idx, scores[2*scale+1]); fflush(stdout); } // ref skip u and v if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { if (fread(temp_buf, 1, offset, ref_rfile) != (size_t)offset) { printf("error: ref fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { if (fread(temp_buf, 2, offset, ref_rfile) != (size_t)offset) { printf("error: ref fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } // dis skip u and v if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { if (fread(temp_buf, 1, offset, dis_rfile) != (size_t)offset) { printf("error: dis fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { if (fread(temp_buf, 2, offset, dis_rfile) != (size_t)offset) { printf("error: dis fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } frm_idx++; } ret = 0; fail_or_end: if (ref_rfile) { fclose(ref_rfile); } if (dis_rfile) { fclose(dis_rfile); } aligned_free(ref_buf); aligned_free(dis_buf); aligned_free(temp_buf); return ret; }
int compute_adm(const number_t *ref, const number_t *dis, int w, int h, int ref_stride, int dis_stride, double *score, double *score_num, double *score_den, double *scores, double border_factor) { #ifdef ADM_OPT_SINGLE_PRECISION double numden_limit = 1e-2 * (w * h) / (1920.0 * 1080.0); #else double numden_limit = 1e-10 * (w * h) / (1920.0 * 1080.0); #endif number_t *data_buf = 0; char *data_top; number_t *ref_scale; number_t *dis_scale; adm_dwt_band_t ref_dwt2; adm_dwt_band_t dis_dwt2; adm_dwt_band_t decouple_r; adm_dwt_band_t decouple_a; adm_dwt_band_t csf_o; adm_dwt_band_t csf_r; adm_dwt_band_t csf_a; number_t *mta; adm_dwt_band_t cm_r; const number_t *curr_ref_scale = ref; const number_t *curr_dis_scale = dis; int curr_ref_stride = ref_stride; int curr_dis_stride = dis_stride; int orig_h = h; int buf_stride = ALIGN_CEIL(((w + 1) / 2) * sizeof(number_t)); size_t buf_sz_one = (size_t)buf_stride * ((h + 1) / 2); double num = 0; double den = 0; int scale; int ret = 1; if (SIZE_MAX / buf_sz_one < 35) { printf("error: SIZE_MAX / buf_sz_one < 35, buf_sz_one = %lu.\n", buf_sz_one); fflush(stdout); goto fail; } if (!(data_buf = aligned_malloc(buf_sz_one * 35, MAX_ALIGN))) { printf("error: aligned_malloc failed for data_buf.\n"); fflush(stdout); goto fail; } data_top = (char *)data_buf; ref_scale = (number_t *)data_top; data_top += buf_sz_one; dis_scale = (number_t *)data_top; data_top += buf_sz_one; data_top = init_dwt_band(&ref_dwt2, data_top, buf_sz_one); data_top = init_dwt_band(&dis_dwt2, data_top, buf_sz_one); data_top = init_dwt_band(&decouple_r, data_top, buf_sz_one); data_top = init_dwt_band(&decouple_a, data_top, buf_sz_one); data_top = init_dwt_band(&csf_o, data_top, buf_sz_one); data_top = init_dwt_band(&csf_r, data_top, buf_sz_one); data_top = init_dwt_band(&csf_a, data_top, buf_sz_one); mta = (number_t *)data_top; data_top += buf_sz_one; data_top = init_dwt_band(&cm_r, data_top, buf_sz_one); for (scale = 0; scale < 4; ++scale) { #ifdef ADM_OPT_DEBUG_DUMP char pathbuf[256]; #endif float num_scale = 0.0; float den_scale = 0.0; adm_dwt2(curr_ref_scale, &ref_dwt2, w, h, curr_ref_stride, buf_stride); adm_dwt2(curr_dis_scale, &dis_dwt2, w, h, curr_dis_stride, buf_stride); w = (w + 1) / 2; h = (h + 1) / 2; adm_decouple(&ref_dwt2, &dis_dwt2, &decouple_r, &decouple_a, w, h, buf_stride, buf_stride, buf_stride, buf_stride); adm_csf(&ref_dwt2, &csf_o, orig_h, scale, w, h, buf_stride, buf_stride); adm_csf(&decouple_r, &csf_r, orig_h, scale, w, h, buf_stride, buf_stride); adm_csf(&decouple_a, &csf_a, orig_h, scale, w, h, buf_stride, buf_stride); adm_cm_thresh(&csf_a, mta, w, h, buf_stride, buf_stride); adm_cm(&csf_r, &cm_r, mta, w, h, buf_stride, buf_stride, buf_stride); #ifdef ADM_OPT_DEBUG_DUMP sprintf(pathbuf, "stage/ref[%d]_a.yuv", scale); write_image(pathbuf, ref_dwt2.band_a, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/ref[%d]_h.yuv", scale); write_image(pathbuf, ref_dwt2.band_h, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/ref[%d]_v.yuv", scale); write_image(pathbuf, ref_dwt2.band_v, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/ref[%d]_d.yuv", scale); write_image(pathbuf, ref_dwt2.band_d, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/dis[%d]_a.yuv", scale); write_image(pathbuf, dis_dwt2.band_a, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/dis[%d]_h.yuv", scale); write_image(pathbuf, dis_dwt2.band_h, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/dis[%d]_v.yuv", scale); write_image(pathbuf, dis_dwt2.band_v, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/dis[%d]_d.yuv", scale); write_image(pathbuf, dis_dwt2.band_d, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/r[%d]_h.yuv", scale); write_image(pathbuf, decouple_r.band_h, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/r[%d]_v.yuv", scale); write_image(pathbuf, decouple_r.band_v, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/r[%d]_d.yuv", scale); write_image(pathbuf, decouple_r.band_d, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/a[%d]_h.yuv", scale); write_image(pathbuf, decouple_a.band_h, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/a[%d]_v.yuv", scale); write_image(pathbuf, decouple_a.band_v, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/a[%d]_d.yuv", scale); write_image(pathbuf, decouple_a.band_d, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/csf_o[%d]_h.yuv", scale); write_image(pathbuf, csf_o.band_h, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/csf_o[%d]_v.yuv", scale); write_image(pathbuf, csf_o.band_v, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/csf_o[%d]_d.yuv", scale); write_image(pathbuf, csf_o.band_d, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/csf_r[%d]_h.yuv", scale); write_image(pathbuf, csf_r.band_h, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/csf_r[%d]_v.yuv", scale); write_image(pathbuf, csf_r.band_v, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/csf_r[%d]_d.yuv", scale); write_image(pathbuf, csf_r.band_d, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/csf_a[%d]_h.yuv", scale); write_image(pathbuf, csf_a.band_h, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/csf_a[%d]_v.yuv", scale); write_image(pathbuf, csf_a.band_v, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/csf_a[%d]_d.yuv", scale); write_image(pathbuf, csf_a.band_d, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/mta[%d].yuv", scale); write_image(pathbuf, mta, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/cm_r[%d]_h.yuv", scale); write_image(pathbuf, cm_r.band_h, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/cm_r[%d]_v.yuv", scale); write_image(pathbuf, cm_r.band_v, w, h, buf_stride, sizeof(number_t)); sprintf(pathbuf, "stage/cm_r[%d]_d.yuv", scale); write_image(pathbuf, cm_r.band_d, w, h, buf_stride, sizeof(number_t)); #endif num_scale += adm_sum_cube(cm_r.band_h, w, h, buf_stride, border_factor); num_scale += adm_sum_cube(cm_r.band_v, w, h, buf_stride, border_factor); num_scale += adm_sum_cube(cm_r.band_d, w, h, buf_stride, border_factor); den_scale += adm_sum_cube(csf_o.band_h, w, h, buf_stride, border_factor); den_scale += adm_sum_cube(csf_o.band_v, w, h, buf_stride, border_factor); den_scale += adm_sum_cube(csf_o.band_d, w, h, buf_stride, border_factor); num += num_scale; den += den_scale; /* Copy DWT2 approximation band to buffer for next scale. */ adm_buffer_copy(ref_dwt2.band_a, ref_scale, w * sizeof(number_t), h, buf_stride, buf_stride); adm_buffer_copy(dis_dwt2.band_a, dis_scale, w * sizeof(number_t), h, buf_stride, buf_stride); curr_ref_scale = ref_scale; curr_dis_scale = dis_scale; curr_ref_stride = buf_stride; curr_dis_stride = buf_stride; #ifdef ADM_OPT_DEBUG_DUMP printf("num: %f\n", num); printf("den: %f\n", den); #endif scores[2*scale+0] = num_scale; scores[2*scale+1] = den_scale; } num = num < numden_limit ? 0 : num; den = den < numden_limit ? 0 : den; if (den == 0.0) { *score = 1.0f; } else { *score = num / den; } *score_num = num; *score_den = den; ret = 0; fail: aligned_free(data_buf); return ret; }
// dump current using buffer in Layer void Layer::dumpActiveBuffer() const { XLOGV("[dumpActiveBuffer] + id=%p", this); if (mActiveBuffer != NULL) { char value[PROPERTY_VALUE_MAX]; bool raw; const void* identity; property_get("debug.sf.layerdump.raw", value, "0"); raw = (0 != atoi(value)); identity = this; char fname[128]; void* ptr; float bpp; SkBitmap b; SkBitmap::Config c; int inputFormat = mActiveBuffer->format; int dumpHeight = mActiveBuffer->height; #ifndef EMULATOR_SUPPORT // check private format if (inputFormat == HAL_PIXEL_FORMAT_YUV_PRIVATE) { gralloc_buffer_info_t buffInfo; GraphicBufferExtra::get().getBufInfo(mActiveBuffer->handle, &buffInfo); int fillFormat = (buffInfo.status & GRALLOC_EXTRA_MASK_CM); switch (fillFormat) { case GRALLOC_EXTRA_BIT_CM_YV12: inputFormat = HAL_PIXEL_FORMAT_YV12; break; case GRALLOC_EXTRA_BIT_CM_NV12_BLK: inputFormat = HAL_PIXEL_FORMAT_NV12_BLK; dumpHeight = ALIGN_CEIL(mActiveBuffer->height, 32); break; case GRALLOC_EXTRA_BIT_CM_NV12_BLK_FCM: inputFormat = HAL_PIXEL_FORMAT_NV12_BLK_FCM; dumpHeight = ALIGN_CEIL(mActiveBuffer->height, 32); break; default: XLOGD("unexpected format for dumpping clear motion: 0x%x", fillFormat); return; } } #endif bpp = 1.0f; c = SkBitmap::kNo_Config; switch (inputFormat) { case PIXEL_FORMAT_RGBA_8888: case PIXEL_FORMAT_RGBX_8888: if (false == raw) { c = SkBitmap::kARGB_8888_Config; sprintf(fname, "/data/SF_dump/%p.png", identity); } else { bpp = 4.0; sprintf(fname, "/data/SF_dump/%p.RGBA", identity); } break; case PIXEL_FORMAT_BGRA_8888: case 0x1ff: // tricky format for SGX_COLOR_FORMAT_BGRX_8888 in fact if (false == raw) { c = SkBitmap::kARGB_8888_Config; sprintf(fname, "/data/SF_dump/%p(RBswapped).png", identity); } else { bpp = 4.0; sprintf(fname, "/data/SF_dump/%p.BGRA", identity); } break; case PIXEL_FORMAT_RGB_565: if (false == raw) { c = SkBitmap::kRGB_565_Config; sprintf(fname, "/data/SF_dump/%p.png", identity); } else { bpp = 2.0; sprintf(fname, "/data/SF_dump/%p.RGB565", identity); } break; case HAL_PIXEL_FORMAT_I420: bpp = 1.5; sprintf(fname, "/data/SF_dump/%p.i420", identity); break; case HAL_PIXEL_FORMAT_NV12_BLK: bpp = 1.5; sprintf(fname, "/data/SF_dump/%p.nv12_blk", identity); break; case HAL_PIXEL_FORMAT_NV12_BLK_FCM: bpp = 1.5; sprintf(fname, "/data/SF_dump/%p.nv12_blk_fcm", identity); break; case HAL_PIXEL_FORMAT_YV12: bpp = 1.5; sprintf(fname, "/data/SF_dump/%p.yv12", identity); break; default: XLOGE("[%s] cannot dump format:%p for identity:%d", __func__, mActiveBuffer->format, identity); return; } { //Mutex::Autolock _l(mDumpLock); mActiveBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &ptr); { XLOGI("[%s] %s", __func__, getName().string()); XLOGI(" %s (config:%d, stride:%d, height:%d, ptr:%p)", fname, c, mActiveBuffer->stride, dumpHeight, ptr); if (SkBitmap::kNo_Config != c) { b.setConfig(c, mActiveBuffer->stride, dumpHeight); b.setPixels(ptr); SkImageEncoder::EncodeFile(fname, b, SkImageEncoder::kPNG_Type, SkImageEncoder::kDefaultQuality); } else { uint32_t size = mActiveBuffer->stride * dumpHeight * bpp; // correction for YV12 case, pending for VU planes should also pending to 16 if (HAL_PIXEL_FORMAT_YV12 == inputFormat) { uint32_t u_remainder = (mActiveBuffer->stride / 2) % 16; if (0 != u_remainder) { size += (16 - u_remainder) * dumpHeight; } } FILE *f = fopen(fname, "wb"); fwrite(ptr, size, 1, f); fclose(f); } } mActiveBuffer->unlock(); } } XLOGV("[dumpActiveBuffer] - id=%p", this); }
int ms_ssim(int (*read_frame)(float *ref_data, float *main_data, float *temp_data, int stride, void *user_data), void *user_data, int w, int h, const char *fmt) { double score = 0; double l_scores[SCALES], c_scores[SCALES], s_scores[SCALES]; float *ref_buf = 0; float *dis_buf = 0; float *temp_buf = 0; size_t data_sz; int stride; int ret = 1; if (w <= 0 || h <= 0 || (size_t)w > ALIGN_FLOOR(INT_MAX) / sizeof(float)) { goto fail_or_end; } stride = ALIGN_CEIL(w * sizeof(float)); if ((size_t)h > SIZE_MAX / stride) { goto fail_or_end; } data_sz = (size_t)stride * h; if (!(ref_buf = aligned_malloc(data_sz, MAX_ALIGN))) { printf("error: aligned_malloc failed for ref_buf.\n"); fflush(stdout); goto fail_or_end; } if (!(dis_buf = aligned_malloc(data_sz, MAX_ALIGN))) { printf("error: aligned_malloc failed for dis_buf.\n"); fflush(stdout); goto fail_or_end; } if (!(temp_buf = aligned_malloc(data_sz * 2, MAX_ALIGN))) { printf("error: aligned_malloc failed for temp_buf.\n"); fflush(stdout); goto fail_or_end; } int frm_idx = 0; while (1) { ret = read_frame(ref_buf, dis_buf, temp_buf, stride, user_data); if(ret == 1){ goto fail_or_end; } if (ret == 2) { break; } // compute ret = compute_ms_ssim(ref_buf, dis_buf, w, h, stride, stride, &score, l_scores, c_scores, s_scores); if (ret) { printf("error: compute_ms_ssim failed.\n"); fflush(stdout); goto fail_or_end; } // print printf("ms_ssim: %d %f\n", frm_idx, score); for (int scale=0; scale<SCALES; scale++) { printf("ms_ssim_l_scale%d: %d %f\n", scale, frm_idx, l_scores[scale]); printf("ms_ssim_c_scale%d: %d %f\n", scale, frm_idx, c_scores[scale]); printf("ms_ssim_s_scale%d: %d %f\n", scale, frm_idx, s_scores[scale]); } fflush(stdout); frm_idx++; } ret = 0; fail_or_end: aligned_free(ref_buf); aligned_free(dis_buf); aligned_free(temp_buf); return ret; }
int psnr(const char *ref_path, const char *dis_path, int w, int h, const char *fmt) { double score = 0; number_t *ref_buf = 0; number_t *dis_buf = 0; number_t *temp_buf = 0; FILE *ref_rfile = 0; FILE *dis_rfile = 0; size_t data_sz; int stride; int ret = 1; if (w <= 0 || h <= 0 || (size_t)w > ALIGN_FLOOR(INT_MAX) / sizeof(number_t)) { goto fail_or_end; } stride = ALIGN_CEIL(w * sizeof(number_t)); if ((size_t)h > SIZE_MAX / stride) { goto fail_or_end; } data_sz = (size_t)stride * h; if (!(ref_buf = aligned_malloc(data_sz, MAX_ALIGN))) { printf("error: aligned_malloc failed for ref_buf.\n"); fflush(stdout); goto fail_or_end; } if (!(dis_buf = aligned_malloc(data_sz, MAX_ALIGN))) { printf("error: aligned_malloc failed for dis_buf.\n"); fflush(stdout); goto fail_or_end; } if (!(temp_buf = aligned_malloc(data_sz * 2, MAX_ALIGN))) { printf("error: aligned_malloc failed for temp_buf.\n"); fflush(stdout); goto fail_or_end; } if (!(ref_rfile = fopen(ref_path, "rb"))) { printf("error: fopen ref_path %s failed\n", ref_path); fflush(stdout); goto fail_or_end; } if (!(dis_rfile = fopen(dis_path, "rb"))) { printf("error: fopen dis_path %s failed.\n", dis_path); fflush(stdout); goto fail_or_end; } size_t offset; if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv420p10le")) { if ((w * h) % 2 != 0) { printf("error: (w * h) %% 2 != 0, w = %d, h = %d.\n", w, h); fflush(stdout); goto fail_or_end; } offset = w * h / 2; } else if (!strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv422p10le")) { offset = w * h; } else if (!strcmp(fmt, "yuv444p") || !strcmp(fmt, "yuv444p10le")) { offset = w * h * 2; } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } int frm_idx = 0; while ((!feof(ref_rfile)) && (!feof(dis_rfile))) { // read ref y if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { ret = read_image_b(ref_rfile, ref_buf, 0, w, h, stride); } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { ret = read_image_w(ref_rfile, ref_buf, 0, w, h, stride); } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } if (ret) { goto fail_or_end; } // read dis y if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { ret = read_image_b(dis_rfile, dis_buf, 0, w, h, stride); } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { ret = read_image_w(dis_rfile, dis_buf, 0, w, h, stride); } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } if (ret) { goto fail_or_end; } // compute if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { // max psnr 60.0 for 8-bit per Ioannis ret = compute_psnr(ref_buf, dis_buf, w, h, stride, stride, &score, 255.0, 60.0); } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { // 10 bit gets normalized to 8 bit, peak is 1023 / 4.0 = 255.75 // max psnr 72.0 for 10-bit per Ioannis ret = compute_psnr(ref_buf, dis_buf, w, h, stride, stride, &score, 255.75, 72.0); } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } if (ret) { printf("error: compute_psnr failed.\n"); fflush(stdout); goto fail_or_end; } // print printf("psnr: %d %f\n", frm_idx, score); fflush(stdout); // ref skip u and v if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { if (fread(temp_buf, 1, offset, ref_rfile) != (size_t)offset) { printf("error: ref fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { if (fread(temp_buf, 2, offset, ref_rfile) != (size_t)offset) { printf("error: ref fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } // dis skip u and v if (!strcmp(fmt, "yuv420p") || !strcmp(fmt, "yuv422p") || !strcmp(fmt, "yuv444p")) { if (fread(temp_buf, 1, offset, dis_rfile) != (size_t)offset) { printf("error: dis fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else if (!strcmp(fmt, "yuv420p10le") || !strcmp(fmt, "yuv422p10le") || !strcmp(fmt, "yuv444p10le")) { if (fread(temp_buf, 2, offset, dis_rfile) != (size_t)offset) { printf("error: dis fread u and v failed.\n"); fflush(stdout); goto fail_or_end; } } else { printf("error: unknown format %s.\n", fmt); fflush(stdout); goto fail_or_end; } frm_idx++; } ret = 0; fail_or_end: if (ref_rfile) { fclose(ref_rfile); } if (dis_rfile) { fclose(dis_rfile); } aligned_free(ref_buf); aligned_free(dis_buf); aligned_free(temp_buf); return ret; }
void adm_dwt2_d(const double *src, const adm_dwt_band_t_d *dst, int w, int h, int src_stride, int dst_stride) { const double *filter_lo = dwt2_db2_coeffs_lo_d; const double *filter_hi = dwt2_db2_coeffs_hi_d; int fwidth = sizeof(dwt2_db2_coeffs_lo_d) / sizeof(double); int src_px_stride = src_stride / sizeof(double); int dst_px_stride = dst_stride / sizeof(double); double *tmplo = aligned_malloc(ALIGN_CEIL(sizeof(double) * w), MAX_ALIGN); double *tmphi = aligned_malloc(ALIGN_CEIL(sizeof(double) * w), MAX_ALIGN); double fcoeff_lo, fcoeff_hi, imgcoeff; int i, j, fi, fj, ii, jj; for (i = 0; i < (h + 1) / 2; ++i) { /* Vertical pass. */ for (j = 0; j < w; ++j) { double accum_lo = 0; double accum_hi = 0; for (fi = 0; fi < fwidth; ++fi) { fcoeff_lo = filter_lo[fi]; fcoeff_hi = filter_hi[fi]; /* Border handling by mirroring. */ ii = 2 * i - 1 + fi; if (ii < 0) ii = -ii; else if (ii >= h) ii = 2 * h - ii - 1; imgcoeff = src[ii * src_px_stride + j]; accum_lo += fcoeff_lo * imgcoeff; accum_hi += fcoeff_hi * imgcoeff; } tmplo[j] = accum_lo; tmphi[j] = accum_hi; } /* Horizontal pass (lo). */ for (j = 0; j < (w + 1) / 2; ++j) { double accum_lo = 0; double accum_hi = 0; for (fj = 0; fj < fwidth; ++fj) { fcoeff_lo = filter_lo[fj]; fcoeff_hi = filter_hi[fj]; /* Border handling by mirroring. */ jj = 2 * j - 1 + fj; if (jj < 0) jj = -jj; else if (jj >= w) jj = 2 * w - jj - 1; imgcoeff = tmplo[jj]; accum_lo += fcoeff_lo * imgcoeff; accum_hi += fcoeff_hi * imgcoeff; } dst->band_a[i * dst_px_stride + j] = accum_lo; dst->band_v[i * dst_px_stride + j] = accum_hi; } /* Horizontal pass (hi). */ for (j = 0; j < (w + 1) / 2; ++j) { double accum_lo = 0; double accum_hi = 0; for (fj = 0; fj < fwidth; ++fj) { fcoeff_lo = filter_lo[fj]; fcoeff_hi = filter_hi[fj]; /* Border handling by mirroring. */ jj = 2 * j - 1 + fj; if (jj < 0) jj = -jj; else if (jj >= w) jj = 2 * w - jj - 1; imgcoeff = tmphi[jj]; accum_lo += fcoeff_lo * imgcoeff; accum_hi += fcoeff_hi * imgcoeff; } dst->band_h[i * dst_px_stride + j] = accum_lo; dst->band_d[i * dst_px_stride + j] = accum_hi; } } aligned_free(tmplo); aligned_free(tmphi); }
int compute_ansnr(const number_t *ref, const number_t *dis, int w, int h, int ref_stride, int dis_stride, double *score, double *score_psnr, double peak, double psnr_max) { number_t *data_buf = 0; char *data_top; number_t *ref_filtr; number_t *ref_filtd; number_t *dis_filtd; number_t sig, noise; #ifdef ANSNR_OPT_NORMALIZE number_t noise_min; #endif int buf_stride = ALIGN_CEIL(w * sizeof(number_t)); size_t buf_sz_one = (size_t)buf_stride * h; int ret = 1; if (SIZE_MAX / buf_sz_one < 3) { goto fail; } if (!(data_buf = aligned_malloc(buf_sz_one * 3, MAX_ALIGN))) { goto fail; } data_top = (char *)data_buf; ref_filtr = (number_t *)data_top; data_top += buf_sz_one; ref_filtd = (number_t *)data_top; data_top += buf_sz_one; dis_filtd = (number_t *)data_top; data_top += buf_sz_one; #ifdef ANSNR_OPT_FILTER_1D ansnr_filter1d(ansnr_filter1d_ref, ref, ref_filtr, w, h, ref_stride, buf_stride, ansnr_filter1d_ref_width); ansnr_filter1d(ansnr_filter1d_dis, ref, ref_filtd, w, h, ref_stride, buf_stride, ansnr_filter1d_dis_width); ansnr_filter1d(ansnr_filter1d_dis, dis, dis_filtd, w, h, dis_stride, buf_stride, ansnr_filter1d_dis_width); #else ansnr_filter2d(ansnr_filter2d_ref, ref, ref_filtr, w, h, ref_stride, buf_stride, ansnr_filter2d_ref_width); ansnr_filter2d(ansnr_filter2d_dis, ref, ref_filtd, w, h, ref_stride, buf_stride, ansnr_filter2d_dis_width); ansnr_filter2d(ansnr_filter2d_dis, dis, dis_filtd, w, h, dis_stride, buf_stride, ansnr_filter2d_dis_width); #endif #ifdef ANSNR_OPT_DEBUG_DUMP write_image("stage/ref_filtr.bin", ref_filtr, w, h, buf_stride, sizeof(number_t)); write_image("stage/ref_filtd.bin", ref_filtd, w, h, buf_stride, sizeof(number_t)); write_image("stage/dis_filtd.bin", dis_filtd, w, h, buf_stride, sizeof(number_t)); #endif ansnr_mse(ref_filtr, dis_filtd, &sig, &noise, w, h, buf_stride, buf_stride); #ifdef ANSNR_OPT_NORMALIZE ansnr_mse(ref_filtr, ref_filtd, 0, &noise_min, w, h, buf_stride, buf_stride); *score = 10.0 * log10(noise / (noise - noise_min)); #else *score = noise==0 ? psnr_max : 10.0 * log10(sig / noise); #endif double eps = 1e-10; *score_psnr = MIN(10 * log10(peak * peak * w * h / MAX(noise, eps)), psnr_max); ret = 0; fail: aligned_free(data_buf); return ret; }