- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我的任务是恢复 mp3 文件,该文件在 PNG 文件中逐位编码。我从 vector 中的 PNG RGB 数据(每像素)中获得了正确的位。我正在使用 C++。
我必须通过 png 文件并读取像素的 RGB 数据:然后我有 3 个十进制值。从十进制值的二进制表示,我需要最小的局部值。 11 个像素以 33 位显示 mp3 的长度。然后我从像素中解码所有二进制数据,并放入一个 vector 中;
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <vector>
#include <math.h>
#include <iostream>
#include <fstream>
#define PNG_DEBUG 3
#include <png.h>
void abort_(const char * s, ...)
{
va_list args;
va_start(args, s);
vfprintf(stderr, s, args);
fprintf(stderr, "\n");
va_end(args);
abort();
}
void itob(short n, std::vector<int> &bin)
{
int d = n;
if (n > 1)
{
d = n % 2;
itob(n / 2, bin);
}
bin.push_back(d);
}
void btoi(unsigned int& n, std::vector<int> bin)
{
n = 0;
int k = 32;
for(int i = 0; i < bin.size() ; i++){
if(bin[i] == 1){
long int num = pow(2,k);
n += num;
}
k--;
}
}
int x, y;
int width, height;
png_byte color_type;
png_byte bit_depth;
png_structp png_ptr;
png_infop info_ptr;
int number_of_passes;
png_bytep * row_pointers;
void read_png_file()
{
unsigned char header[8]; // 8 is the maximum size that can be checked
/* open file and test for it being a png */
FILE *fp = fopen("image.png", "rb");
if (!fp)
abort_("[read_png_file] File %s could not be opened for reading", "image.png");
fread(header, 1, 8, fp);
if (png_sig_cmp(header, 0, 8))
abort_("[read_png_file] File %s is not recognized as a PNG file", "image.png");
/* initialize stuff */
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!png_ptr)
abort_("[read_png_file] png_create_read_struct failed");
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
abort_("[read_png_file] png_create_info_struct failed");
png_init_io(png_ptr, fp);
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
width = png_get_image_width(png_ptr, info_ptr);
height = png_get_image_height(png_ptr, info_ptr);
color_type = png_get_color_type(png_ptr, info_ptr);
bit_depth = png_get_bit_depth(png_ptr, info_ptr);
number_of_passes = png_set_interlace_handling(png_ptr);
png_read_update_info(png_ptr, info_ptr);
row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height);
for (y=0; y<height; y++)
row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(png_ptr,info_ptr));
png_read_image(png_ptr, row_pointers);
fclose(fp);
}
void process_file(void)
{
if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_RGBA)
abort_("[process_file] input file is PNG_COLOR_TYPE_RGB but must be PNG_COLOR_TYPE_RGB "
"(lacks the alpha channel)");
if (png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_RGB)
abort_("[process_file] color_type of input file must be PNG_COLOR_TYPE_RGB (%d) (is %d)",
PNG_COLOR_TYPE_RGBA, png_get_color_type(png_ptr, info_ptr));
printf("width: %d\nheight: %d\n", width, height);
int mHeader = 33; unsigned int mSize = 0;
std::vector<int> mSizeByBites;
for (y=0; y<height; y++) {
png_byte* row = row_pointers[y];
for (x=0; x<width; x++) {
png_byte* ptr = &(row[x*3]);
if(mHeader == 0){ break; }
mHeader-=3;
std::vector<int> b;
itob(ptr[0], b);
mSizeByBites.push_back(b[b.size()-1]);
b.clear();
itob(ptr[1], b);
mSizeByBites.push_back(b[b.size()-1]);
b.clear();
itob(ptr[2], b);
mSizeByBites.push_back(b[b.size()-1]);
b.clear();
}
if(mHeader == 0){ break; }
}
for(int i =0; i<mSizeByBites.size(); i++){
printf("%d", mSizeByBites[i]);
}
btoi(mSize, mSizeByBites);
printf(" = %i\n", mSize);
std::vector<int> mDataBaBites;
for (y=0; y<height; y++) {
png_byte* row = row_pointers[y];
for (x=0; x<width; x++) {
if(mSize <= 0){ break; }
png_byte* ptr = &(row[x*3]);
std::vector<int> b;
itob(ptr[0], b);
mDataBaBites.push_back(b[b.size()-1]);
b.clear();
mSize--;
if(mSize <= 0){ break; }
itob(ptr[1], b);
mDataBaBites.push_back(b[b.size()-1]);
b.clear();
mSize--;
if(mSize <= 0){ break; }
itob(ptr[2], b);
mDataBaBites.push_back(b[b.size()-1]);
b.clear();
mSize--;
if(mSize <= 0){ break; }
printf("%i\n", mSize);
}
if(mSize<=0){ break; }
}
std::ofstream output("result.mp3", std::ios::out | std::ios::binary);
printf("[D] Writing to file start: %li\n", mDataBaBites.size());
output.write( (char*)(&mDataBaBites[0]), mDataBaBites.size() );
output.close();
}
int main(int argc, char **argv)
{
read_png_file();
process_file();
return 0;
}
现在我不知道如何将它写入文件,我可以将其作为 mp3 播放。我尝试将位转换为六位。
mp3 文件的正确格式是什么?如何以正确的格式写入位?
最佳答案
试试这个:
#include <fstream> //For std::min
std::ofstream mp3File( "restored.mp3", std::ios::out | std::ios::binary );
//Assuming rgbData is a char* with the mp3 data,
//and rgbDataSize is its size in bytes
mp3File.write( rgbData, rgbDataSize );
mp3File.close();
更新:当我们(程序员)说“二进制表示”时,我们几乎总是指字节,而不是位。根据您对解码过程的描述,我认为您应该比较每个像素的 3 个 RGB 分量,并将最小值保留为解码字节。为此:
#include <algorithm>
//...
std::vector<char> mDataBaBites;
for (y=0; y<height; y++) {
png_byte* row = row_pointers[y];
for (x=0; x<width; x++) {
png_byte red = row[x*3];
png_byte green = row[x*3 + 1];
png_byte blue = row[x*3 + 2];
png_byte minByte = std::min( std::min(red,green), blue );
mDataBaBites.push_back( minByte );
mSize -= 3;
}
if(mSize<=0){ break; }
}
std::ofstream output("result.mp3", std::ios::out | std::ios::binary);
printf("[D] Writing to file start: %li\n", mDataBaBites.size());
output.write( (char*)(&mDataBaBites[0]), mDataBaBites.size() );
output.close();
更新 2:
std::ofstream output("result.mp3", std::ios::out | std::ios::binary);
printf("[D] Writing to file start: %li\n", mDataBaBites.size());
for( int i=0; i<mDataBaBites.size(); i+=8 ){
char decodedByte = 0;
for( int j=0; j<8; j++ )
decodedByte |= (mDataBaBites[i+j] << j);
output.write( (char*)(&mDataBaBites[0]), 1 );
}
output.close();
如果这也不起作用,您可能想澄清解码过程定义(它的来源是什么?有一些正式的定义吗?)
关于c++ - 从二进制数据恢复 MP3 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21436449/
我正在使用以下代码播放声音,过一会儿它将停止播放声音,这是因为我相信有太多的Mediaplayer打开实例,所以我添加了一个额外的mp.release();,这只会使我的应用程序崩溃(目前已被注释掉)
我正在查看 XV-6 代码,它通过它识别 MP 结构。它首先在 EBDA 的第一个 kb 中搜索。代码是这样的 static struct mp* mpsearch(void) { uchar *
我在我的应用程序中使用 Mp 饼图。它显示非常小的尺寸,我试图增加它的尺寸但它没有增加它的尺寸。我无法找出问题所在。请告诉我们如何增加尺寸。 这是我的代码: public class MPpiecha
如何使用 MPAndroidChart 实现此目的? 使用版本:com.github.PhilJay:MPAndroidChart:v3.1.0-alpha 添加图例和饼图边距的代码: private
亲爱的社区,我面临以下问题,我正在使用此处提供的 MP android 图表库创建条形图:https://github.com/PhilJay/MPAndroidChart . 我想为我的条设置渐变背
我正在使用 SAS MP Connect 开发我的第一段代码,以运行同一个 sas 作业的并行线程。 我知道 MP CONNECT 仅受可用 CPU 数量的物理限制,但理想情况下我不想在我的工作中使用
我最近购买了在 Linux 服务器上运行的 Stata MP12(8 核)许可证。 有没有人写过 Stata 程序,比如说模拟研究来测试 Stata MP 的性能?我想监视在作业处理过程中实际使用的内
我将不胜感激任何“一步一步”指南,说明如何更改 PHP/HTML 页面上的动态数据库连接/连接字符串/等上的代码,使其“即插即用”工作通过 ftp 将页面和 MySQL 数据库托管在“Azure 网站
试图在我的应用程序中放置一个“暂停”按钮,以播放一些声音片段循环播放。 当我打电话mp.pause();一切都破了,我完全迷路了! 这是我正在使用的方法。 protected void man
我想使用 Mp Chart 创建折线图 我想要实现的是这张图片 但是到目前为止我已经得到了这个。 我使用的代码是这个 private fun setData() { val entries
通常,我可能会编写一个类似simd的循环: float * x = (float *) malloc(10 * sizeof(float)); float * y = (float *) malloc
在与堆栈空间、OpenMP 以及如何处理这些问题相关的其他帖子上,有很多回复。但是,我找不到信息来真正理解 OpenMP 调整编译器选项的原因: 原因是什么-fopenmp在 gfortran 中暗示
我有一段代码,可以根据漂移、波动性和随机数计算任意给定日期的股票价格。但是当我检查输出列表时 - 它们是算术级数,而不是几何级数(幂函数)。我共享的变量有问题吗? 代码如下: #include #i
我正在尝试在 C++11 中并行化动态编程算法使用这种方法: void buildBaseCases() { cout << "Building base cases" << endl
我正在 open MP 中实现并行点积 我有这个代码: #include #include #include #include #include #include #define SIZE
我有一台服务器已经将近 4 年了,直到现在我都没有遇到任何问题(主机端)。我一直在更换主机,因为 ddos 的东西试图找到最适合我的东西。现在我买了一个 VPS(这不是我的第一个)并尝试运行我的服
所以我有两个内部平行区域的外部平行区域。是否可以将 2 个线程放入外部平行线,将 4 个线程放入每个内部平行线?我做了这样的东西,但它似乎无法按照我想要的方式工作。有什么建议吗? start_r =
我希望有人指出我们遇到的问题或解决方法。 使用/MP 编译项目时,似乎只有同一文件夹中的文件会同时编译。我使用 Process Explorer 滑动命令行并确认行为。 项目过滤器似乎对并发编译的内容
本文整理了Java中me.chanjar.weixin.mp.api.WxMpMessageRouter类的一些代码示例,展示了WxMpMessageRouter类的具体用法。这些代码示例主要来源于G
我正在监视 Stata/MP(Stata/SE 的多核版本)的 CPU 和内存使用情况,但我不是 Stata 程序员(更像是 Perl 人)。 任何人都可以发布一些代码,利用公共(public)数据集
我是一名优秀的程序员,十分优秀!