📄 png2yuv.c
字号:
#endif png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) mjpeg_error_exit1("%s: Could not allocate PNG read struct !", pngname); png_init_io(png_ptr, pngfile); //png_set_sig_bytes(png_ptr, 8); info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); mjpeg_error_exit1("%s: Could not allocate PNG info struct !", pngname); } end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); mjpeg_error_exit1("%s: Could not allocate PNG end info struct !", pngname); } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); mjpeg_error("%s: Corrupted PNG file !", pngname); return -1; } if (process) png_set_read_user_transform_fn(png_ptr, png_separation); png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_STRIP_16 | PNG_TRANSFORM_STRIP_ALPHA, NULL); if (png_get_IHDR(png_ptr, info_ptr, ¶m->width, ¶m->height, &bit_depth, // &color_type, &interlace_type, &compression_type, &filter_type)) &color_type, NULL, NULL, NULL)) num_pass = png_set_interlace_handling(png_ptr); else mjpeg_error_exit1("PNG header reading failed !!\n");#if 0 mjpeg_info("Reading info struct...\n"); png_read_info(png_ptr, info_ptr); mjpeg_info("Done...\n"); if (png_get_IHDR(png_ptr, info_ptr, ¶m->width, ¶m->height, &bit_depth, // &color_type, &interlace_type, &compression_type, &filter_type)) &color_type, NULL, NULL, NULL)) num_pass = png_set_interlace_handling(png_ptr); else mjpeg_error_exit1("PNG header reading failed !!\n"); if (process) { printf("%d passes needed\n\n", num_pass); if (bit_depth != 8 && bit_depth != 16) { mjpeg_error_exit1("Invalid bit_depth %d, only 8 and 16 bit allowed !!\n", bit_depth); } png_set_strip_16(png_ptr); // always has to strip the 16bit input, MPEG can't handle it png_set_strip_alpha(png_ptr); // Alpha can't be processed until Z/Alpha is integrated printf("\nAllocating row buffer..."); png_set_read_user_transform_fn(png_ptr, png_separation); png_bytep row_buf = (png_bytep)png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)); for (int n=0; n < num_pass; n++) for (int y=0; y < sh_param->height; y++) { printf("Writing row data for pass %d\n", n); png_read_rows(png_ptr, (png_bytepp)&row_buf, NULL, 1); } png_free(png_ptr, row_buf); } png_read_end(png_ptr, info_ptr);#endif png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(pngfile); return 1;}/** init_parse_files * Verifies the PNG input files and prepares YUV4MPEG header information. * @returns 0 on success */static int init_parse_files(parameters_t *param){ char pngname[255]; snprintf(pngname, sizeof(pngname), param->pngformatstr, param->begin); mjpeg_debug("Analyzing %s to get the right pic params", pngname); if (decode_png(pngname, 0, param) == -1) mjpeg_error_exit1("Reading of %s failed.\n", pngname); mjpeg_info("Image dimensions are %ldx%ld", param->width, param->height); mjpeg_info("Movie frame rate is: %f frames/second", Y4M_RATIO_DBL(param->framerate)); switch (param->interlace) { case Y4M_ILACE_NONE: mjpeg_info("Non-interlaced/progressive frames."); break; case Y4M_ILACE_BOTTOM_FIRST: mjpeg_info("Interlaced frames, bottom field first."); break; case Y4M_ILACE_TOP_FIRST: mjpeg_info("Interlaced frames, top field first."); break; default: mjpeg_error_exit1("Interlace has not been specified (use -I option)"); break; } if ((param->interlace != Y4M_ILACE_NONE) && (param->interleave == -1)) mjpeg_error_exit1("Interleave has not been specified (use -L option)"); if (!(param->interleave) && (param->interlace != Y4M_ILACE_NONE)) { param->height *= 2; mjpeg_info("Non-interleaved fields (image height doubled)"); } mjpeg_info("Frame size: %ld x %ld", param->width, param->height); return 0;}static int generate_YUV4MPEG(parameters_t *param){ uint32_t frame; //size_t pngsize; char pngname[FILENAME_MAX]; uint8_t *yuv[3]; /* buffer for Y/U/V planes of decoded PNG */ y4m_stream_info_t streaminfo; y4m_frame_info_t frameinfo; if ((param->width % 2) == 0) param->new_width = param->width; else { param->new_width = ((param->width >> 1) + 1) << 1; printf("Setting new, even image width %d", param->new_width); } mjpeg_info("Now generating YUV4MPEG stream."); y4m_init_stream_info(&streaminfo); y4m_init_frame_info(&frameinfo); y4m_si_set_width(&streaminfo, param->new_width); y4m_si_set_height(&streaminfo, param->height); y4m_si_set_interlace(&streaminfo, param->interlace); y4m_si_set_framerate(&streaminfo, param->framerate); y4m_si_set_chroma(&streaminfo, param->ss_mode); yuv[0] = (uint8_t *)malloc(param->new_width * param->height * sizeof(yuv[0][0])); yuv[1] = (uint8_t *)malloc(param->new_width * param->height * sizeof(yuv[1][0])); yuv[2] = (uint8_t *)malloc(param->new_width * param->height * sizeof(yuv[2][0])); y4m_write_stream_header(STDOUT_FILENO, &streaminfo); for (frame = param->begin; (frame < param->numframes + param->begin) || (param->numframes == -1); frame++) { // if (frame < 25) // else //snprintf(pngname, sizeof(pngname), param->pngformatstr, frame - 25); snprintf(pngname, sizeof(pngname), param->pngformatstr, frame); raw0 = yuv[0]; raw1 = yuv[1]; raw2 = yuv[2]; if (decode_png(pngname, 1, param) == -1) { mjpeg_info("Read from '%s' failed: %s", pngname, strerror(errno)); if (param->numframes == -1) { mjpeg_info("No more frames. Stopping."); break; /* we are done; leave 'while' loop */ } else { mjpeg_info("Rewriting latest frame instead."); } } else {#if 0 mjpeg_debug("Preparing frame"); /* Now open this PNG file, and examine its header to retrieve the YUV4MPEG info that shall be written */ if ((param->interlace == Y4M_ILACE_NONE) || (param->interleave == 1)) { mjpeg_info("Processing non-interlaced/interleaved %s.", pngname, pngsize); decode_png(imagedata, 0, 420, yuv[0], yuv[1], yuv[2], param->width, param->height, param->new_width); #if 0 if (param->make_z_alpha) { mjpeg_info("Writing Z/Alpha data.\n"); za_write(real_z_imagemap, param->width, param->height,z_alpha_fp,frame); }#endif } else { mjpeg_error_exit1("Can't handle interlaced PNG information (yet) since there is no standard for it.\n" "Use interleaved mode (-L option) to create interlaced material."); switch (param->interlace) { case Y4M_ILACE_TOP_FIRST: mjpeg_info("Processing interlaced, top-first %s", pngname);#if 0 decode_jpeg_raw(jpegdata, jpegsize, Y4M_ILACE_TOP_FIRST, /* gz: was: LAV_INTER_TOP_FIRST */ 420, param->width, param->height, yuv[0], yuv[1], yuv[2]);#endif break; case Y4M_ILACE_BOTTOM_FIRST: mjpeg_info("Processing interlaced, bottom-first %s", pngname);#if 0 decode_jpeg_raw(jpegdata, jpegsize, Y4M_ILACE_BOTTOM_FIRST, /* gz: was: LAV_INTER_TOP_FIRST */ 420, param->width, param->height, yuv[0], yuv[1], yuv[2]);#endif break; default: mjpeg_error_exit1("FATAL logic error?!?"); break; } }#endif mjpeg_debug("Converting frame to YUV format."); /* Transform colorspace, then subsample (in place) */ convert_RGB_to_YCbCr(yuv, param->height * param->new_width); chroma_subsample(param->ss_mode, yuv, param->new_width, param->height); mjpeg_debug("Frame decoded, now writing to output stream."); } mjpeg_debug("Frame decoded, now writing to output stream."); y4m_write_frame(STDOUT_FILENO, &streaminfo, &frameinfo, yuv); }#if 0 if (param->make_z_alpha) { za_write_end(z_alpha_fp); fclose(z_alpha_fp); }#endif y4m_fini_stream_info(&streaminfo); y4m_fini_frame_info(&frameinfo); free(yuv[0]); free(yuv[1]); free(yuv[2]); return 0;}/* main * in: argc, argv: Classic commandline parameters. * returns: int: 0: success, !0: !success :-) */int main(int argc, char ** argv){ parameters_t param; sh_param = ¶m; y4m_accept_extensions(1); parse_commandline(argc, argv, ¶m); mjpeg_default_handler_verbosity(param.verbose); mjpeg_info("Parsing & checking input files."); if (init_parse_files(¶m)) { mjpeg_error_exit1("* Error processing the PNG input."); } if (generate_YUV4MPEG(¶m)) { mjpeg_error_exit1("* Error processing the input files."); } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -