赞
踩
Mipiraw和unpackraw区别
传感器采集的RAW数据通常为10bit,存储RAW数据需要两个Byte,而其中有6个bit位是空着的,这样就有存储空间浪费。MIPI RAW数据充分利用了这个特性,采用5个Byte,共40bit存储4个RAW数据。大部分UnpackRaw图都是以小端模式存储,MipiRaw则是大端存储。Raw图只有数据,没有其他属性信息。
下面依次详细解释raw图存储格式 和 MSB、LSB的排列方式 以及 转换方法。
上图:
.对应MiPiRaw的十六进制
.对应UnpackRaw的十六进制
UnpackRaw:
从UnpackRaw的十六进制看,前两个字节为 5D 00,像素值为93,而十六进制0x5D对应的十进制就是93。从结果推理前两个字节标识的像素字节为单位排列应该是 00 5D,从而判断是小端模式存储。
小端模式:高有效位在高地址,低有效在低地址,从右向左读就是正确的数据排列。
大端模式:高有效位在低地址,低有效位在高地址,从左向右都就是正确的数据排列。
注意大小端模式以字节为单位。
MIpiRaw:
从上面MipiRaw的十六进制来看是大端模式,将两个最低有效位存储到公共字节中,如下图:
0x17 << 2 + 0x39 & 0x03 = 0x0001011101,即0x00 5D,即93
首先看一张图片:
大端模式和小端模式字节内均有两种存储方式。
UnpackRaw:
从1.3的图中可以看出
UnpackRaw是小端模式 + 字节内MSB优先的存储方式
MipiRaw是大端模式 + 字节内MSB优先的存储方式
结论:UnpackRaw是小端模式 + 字节内MSB优先的存储方式。
MipiRaw是大端模式 + 字节内MSB优先的存储方式。
10 Bpp:
Unpackraw
4个像素占用8个字节。灰色是空置未使用的bit位。
MipiRaw
4个像素占用5个字节
代码实现将MipiRaw的排列改为UnpackRaw的排列,代码实现如下:
参数:
pIn:指源文件指针
pOut:指输出文件指针
number:指MipiRaw的像素个数,即宽*高
代码实现将MipiRaw的排列改为UnpackRaw的排列,代码实现如下:
1.0版本
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <iostream>
-
- typedef unsigned char BYTE; // 定义BYTE类型,占1个字节
-
- void MipiRaw10ToP10(BYTE* pIn, BYTE* pOut, long number)
- {
- printf("enter MipiRaw10ToP10\n");
- int index = 0;
- // 5个字节4个像素
- // 前面4个字节都是对应像素的高8位,最后一个字(第五个)每个像素的低2位
- // MIPIRaw 大端模式
- // BYTE0 :P1[0:7]
- // BYTE1 :P2[0:7]
- // BYTE2 :P3[0:7]
- // BYTE3 :P4[0:7]
- // BYTE4 :P4[8:9]P3[8:9]P2[8:9]P1[8:9]
- // UnpackRaw 小端模式
- // Pix1: BYTE0:[2:9], BYTE1:[0:1] == BYTE0:(P1[0:7]<< 2 + P1[8:9]), BYTE1:(P1[0:7] >> 6)
- // Pix2: 上同
- // Pix3: 上同
- // Pix4: 上同
- // Big endian
- for (long i = 0; i < (number * 5) / 4; i = i + 5)
- {
- pOut[index++] = ((pIn[i] << 2) & 0xfc) | (pIn[i + 4] & 0x03);
- pOut[index++] = (pIn[i] >> 6) & 0x03;
-
- //pIn[i+4] >>= 2;
- pOut[index++] = ((pIn[i + 1] << 2) & 0xfc) | ((pIn[i + 4] >> 2) & 0x03);
- pOut[index++] = (pIn[i + 1] >> 6) & 0x03;
-
- //pIn[i+4] >>= 2;
- pOut[index++] = ((pIn[i + 2] << 2) & 0xfc) | ((pIn[i + 4] >> 4) & 0x03);
- pOut[index++] = (pIn[i + 2] >> 6) & 0x03;
-
- //pIn[i+4] >>= 2;
- pOut[index++] = ((pIn[i + 3] << 2) & 0xfc) | ((pIn[i + 4] >> 6) & 0x03);
- pOut[index++] = (pIn[i + 3] >> 6) & 0x03;
- }
- printf("MipiRaw10ToP10 over\n");
- }
一个像素占用12个bit,两个字节空置4个bit未使用。MipiRaw则是3个字节存储两个像素,最后一个字节保留两个像素最低四位的有效位数据。
MipiRaw:
Unpackraw:
根据十六进制上示意图:
根据像素值,然后从十六进制就可以看出Unpack是小端模式。根据如上示意图,看出字节内是MSB优先。
从示意图看出,MipiRaw是大端存储方式,最低四位有效位放在公共字节。
结论:UnpackRaw是小端模式 + 字节内MSB优先的存储方式。
MipiRaw是大端模式 + 字节内MSB优先的存储方式。
12Bpp:
UnpackRaw
2个像素占用4个字节
MipiRaw
2个像素占用3个字节
1.0版本
代码实现:
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <iostream>
-
- typedef unsigned char BYTE; // 定义BYTE类型,占1个字节
-
- void MipiRaw12ToP12(BYTE* pIn, BYTE* pOut, long number)
- {
- printf("enter MipiRaw12ToP12\n");
- int index = 0;
- // 3个字节2个像素
- // 前面2个字节都是对应像素的高8位,最后一个字(第3个)每个像素的低4位
- // MIPIRaw 大端模式
- // BYTE0 :P1[0:7]
- // BYTE1 :P2[0:7]
- // BYTE2 :P2[8:11]P1[8:11]
- // UnpackRaw 小端模式
- // Pix1: BYTE0:[4:11], BYTE1:[0:3] == BYTE0:(P1[0:7]<< 4 + P1[8:11]), BYTE1:(P1[0:7] >> 4)
- // Pix2: 上同
- // Big endian
- for (long i = 0; i < (number * 3) / 2; i = i + 3)
- {
- pOut[index++] = ((pIn[i] << 4) & 0xf0) | (pIn[i + 2] & 0x0f);
- pOut[index++] = (pIn[i] >> 4) & 0x0f;
-
- //pIn[i+2] >>= 4;
- pOut[index++] = ((pIn[i + 1] << 4) & 0xf0) | ((pIn[i + 2] >> 4) & 0x0f);
- pOut[index++] = (pIn[i + 1] >> 4) & 0x0f;
- }
- printf("MipiRaw12ToP12 over\n");
- }
一个像素占用14个bit,两个字节空置2个bit未使用。MipiRaw则是7个字节存储4个像素,最后3个字节保留四个像素最低6位的有效位数据。
MipiRaw
UnpackRaw
根据像素值,然后从十六进制就可以看出Unpack是小端模式。根据如上示意图,看出字节内是MSB优先。
从示意图看出,MipiRaw是大端存储方式,最低6位有效位放在公共字节。
结论:UnpackRaw是小端模式 + 字节内MSB优先的存储方式。
MipiRaw是大端模式 + 字节内MSB优先的存储方式。
1.0版本
- void MipiRaw14ToP14(BYTE* pIn, BYTE* pOut, long number)
- {
- printf("enter MipiRaw14ToP14\n");
- int index = 0;
- // 7个字节4个像素
- // 前面4个字节都是对应像素的高8位,最后3个字对应每个像素的低6位
- // BYTE0 :P1[0:7]
- // BYTE1 :P2[0:7]
- // BYTE2 :P3[0:7]
- // BYTE3 :P4[0:7]
- // BYTE4 :P1[8:13]P2[8:9]
- // BYTE5 :P2[10:13]P3[8:11]
- // BYTE6 :P3[12:13]P4[8:13]
- // Big endian
- for (long i = 0; i < (number * 7) / 4; i = i + 7)
- {
- // Pix1
- pOut[index++] = ((pIn[i] << 6) & 0xc0) | ((pIn[i + 4] >> 2) & 0xcf);
- pOut[index++] = (pIn[i] >> 2) & 0x3f;
-
- // Pix2
- pOut[index++] = ((pIn[i + 1] << 6) & 0xc0) | ((pIn[i + 4] << 4) & 0x30) + ((pIn[i + 5] >> 4) & 0x0f);
- pOut[index++] = (pIn[i + 1] >> 2) & 0x3f;
-
- // Pix3
- pOut[index++] = ((pIn[i + 2] << 6) & 0xc0) | ((pIn[i + 5] << 2) & 0x3c) + ((pIn[i + 6] >> 6) & 0x03);
- pOut[index++] = (pIn[i + 2] >> 2) & 0x3f;
-
- // Pix4
- pOut[index++] = ((pIn[i + 3] << 6) & 0xc0) | ((pIn[i + 6]) & 0x3f);
- pOut[index++] = (pIn[i + 3] >> 2) & 0x3f;
- }
- printf("MipiRaw14ToP14 over\n");
- }
这里是单纯的转换,需要输入正确的宽高。
10bit计算公式
文件大小 = width * height * 5 / 4
12bit
文件大小 = width * height * 3 / 2
14bit
文件大小 = width * height * 7 / 4
如果dump出来的文件大小比算出来的大小大,那应该是stride和width不一致,这是如果使用1.0的话,那么输入的width就是stride的大小了,不然转化可能会有问题。14bit的除外,14bit转化1.0和2.0一致,输入width即width不是stride,其余照旧。
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <iostream>
-
- typedef unsigned char BYTE; // 定义BYTE类型,占1个字节
-
- void MipiRaw10ToP10(BYTE* pIn, BYTE* pOut, long number)
- {
- printf("enter MipiRaw10ToP10\n");
- int index = 0;
- // 5个字节4个像素
- // 前面4个字节都是对应像素的高8位,最后一个字(第五个)每个像素的低2位
- // MIPIRaw 大端模式
- // BYTE0 :P1[0:7]
- // BYTE1 :P2[0:7]
- // BYTE2 :P3[0:7]
- // BYTE3 :P4[0:7]
- // BYTE4 :P4[8:9]P3[8:9]P2[8:9]P1[8:9]
- // UnpackRaw 小端模式
- // Pix1: BYTE0:[2:9], BYTE1:[0:1] == BYTE0:(P1[0:7]<< 2 + P1[8:9]), BYTE1:(P1[0:7] >> 6)
- // Pix2: 上同
- // Pix3: 上同
- // Pix4: 上同
- // Big endian
- for (long i = 0; i < (number * 5) / 4; i = i + 5)
- {
- pOut[index++] = ((pIn[i] << 2) & 0xfc) | (pIn[i + 4] & 0x03);
- pOut[index++] = (pIn[i] >> 6) & 0x03;
-
- //pIn[i+4] >>= 2;
- pOut[index++] = ((pIn[i + 1] << 2) & 0xfc) | ((pIn[i + 4] >> 2) & 0x03);
- pOut[index++] = (pIn[i + 1] >> 6) & 0x03;
-
- //pIn[i+4] >>= 2;
- pOut[index++] = ((pIn[i + 2] << 2) & 0xfc) | ((pIn[i + 4] >> 4) & 0x03);
- pOut[index++] = (pIn[i + 2] >> 6) & 0x03;
-
- //pIn[i+4] >>= 2;
- pOut[index++] = ((pIn[i + 3] << 2) & 0xfc) | ((pIn[i + 4] >> 6) & 0x03);
- pOut[index++] = (pIn[i + 3] >> 6) & 0x03;
- }
- printf("MipiRaw10ToP10 over\n");
- }
-
- void MipiRaw12ToP12(BYTE* pIn, BYTE* pOut, long number)
- {
- printf("enter MipiRaw12ToP12\n");
- int index = 0;
- // 3个字节2个像素
- // 前面2个字节都是对应像素的高8位,最后一个字(第3个)每个像素的低4位
- // MIPIRaw 大端模式
- // BYTE0 :P1[0:7]
- // BYTE1 :P2[0:7]
- // BYTE2 :P2[8:11]P1[8:11]
- // UnpackRaw 小端模式
- // Pix1: BYTE0:[4:11], BYTE1:[0:3] == BYTE0:(P1[0:7]<< 4 + P1[8:11]), BYTE1:(P1[0:7] >> 4)
- // Pix2: 上同
- // Big endian
- for (long i = 0; i < (number * 3) / 2; i = i + 3)
- {
- pOut[index++] = ((pIn[i] << 4) & 0xf0) | (pIn[i + 2] & 0x0f);
- pOut[index++] = (pIn[i] >> 4) & 0x0f;
-
- //pIn[i+2] >>= 4;
- pOut[index++] = ((pIn[i + 1] << 4) & 0xf0) | ((pIn[i + 2] >> 4) & 0x0f);
- pOut[index++] = (pIn[i + 1] >> 4) & 0x0f;
- }
- printf("MipiRaw12ToP12 over\n");
- }
-
- void MipiRaw14ToP14(BYTE* pIn, BYTE* pOut, long number)
- {
- printf("enter MipiRaw14ToP14\n");
- int index = 0;
- // 7个字节4个像素
- // 前面4个字节都是对应像素的高8位,最后3个字对应每个像素的低6位
- // BYTE0 :P1[0:7]
- // BYTE1 :P2[0:7]
- // BYTE2 :P3[0:7]
- // BYTE3 :P4[0:7]
- // BYTE4 :P1[8:13]P2[8:9]
- // BYTE5 :P2[10:13]P3[8:11]
- // BYTE6 :P3[12:13]P4[8:13]
- // Big endian
- for (long i = 0; i < (number * 7) / 4; i = i + 7)
- {
- // Pix1
- pOut[index++] = ((pIn[i] << 6) & 0xc0) | ((pIn[i + 4] >> 2) & 0xcf);
- pOut[index++] = (pIn[i] >> 2) & 0x3f;
-
- // Pix2
- pOut[index++] = ((pIn[i + 1] << 6) & 0xc0) | ((pIn[i + 4] << 4) & 0x30) + ((pIn[i + 5] >> 4) & 0x0f);
- pOut[index++] = (pIn[i + 1] >> 2) & 0x3f;
-
- // Pix3
- pOut[index++] = ((pIn[i + 2] << 6) & 0xc0) | ((pIn[i + 5] << 2) & 0x3c) + ((pIn[i + 6] >> 6) & 0x03);
- pOut[index++] = (pIn[i + 2] >> 2) & 0x3f;
-
- // Pix4
- pOut[index++] = ((pIn[i + 3] << 6) & 0xc0) | ((pIn[i + 6]) & 0x3f);
- pOut[index++] = (pIn[i + 3] >> 2) & 0x3f;
- }
- printf("MipiRaw14ToP14 over\n");
- }
-
- int main(int argc, char* argv[])
- {
- FILE* fp = NULL;
- BYTE* ptr;
- BYTE* outptr = NULL;
- int err = 0;
- if (argc < 6) {
- return -1;
- }
- const char* filepath = argv[1];
- const char* height_str = argv[2];
- const char* width_str = argv[3];
- const char* bpp_str = argv[4];
- const char* outfilepath = argv[5];
- int width = 0;
- int height = 0;
- int bpp = 0;
- width = atoi(width_str);
- height = atoi(height_str);
- bpp = atoi(bpp_str);
- printf("width: %d, height: %d, bpp: %d\n", width, height, bpp);
-
- // 输入源路径并打开raw图像文件
- printf("=======raw image process===========\n");
- err = fopen_s(&fp, filepath, "rb");
- if (NULL == fp)
- {
- printf("can not open the raw image ");
- return 0;
- }
- else
- {
- printf("read OK\n");
- }
- //Sleep(1000); /* windows 使用Sleep,参数为毫秒 */
- // 分配内存并将图像读到二维数组中
- fseek(fp, 0, SEEK_END);
- unsigned long fsize = ftell(fp);
- rewind(fp);
- ptr = (BYTE*)malloc(fsize * sizeof(BYTE));
- if (ptr == NULL) {
- printf("ptr malloc fail\n");
- return -2;
- }
- if (fread(ptr, 1, fsize, fp) != fsize) {
- printf("read file error.\n");
- return -1;
- }
- fclose(fp);
-
- unsigned long outsize = width * height * 2;
- outptr = (BYTE*)malloc(outsize * sizeof(BYTE));
- if (outptr == NULL) {
- printf("outptr malloc fail\n");
- return -2;
- }
- if (10 == bpp) {
- MipiRaw10ToP10(ptr, outptr, (width * height));
- }
- else if (12 == bpp) {
- MipiRaw12ToP12(ptr, outptr, (width * height));
- }
- else if (14 == bpp) {
- MipiRaw14ToP14(ptr, outptr, (width * height));
- }
-
- free(ptr);
- ptr = NULL;
- // 将处理后的图像数据保存
- printf("Input the raw_image path for save: \n");
- FILE* outfp = NULL;
- err = fopen_s(&outfp, outfilepath, "wb");
- if (outfp == NULL) {
- printf("can not create the raw_image\n");
- return 0;
- }
- else {
- printf("fopen OK\n");
- }
- printf("creat file OK\n");
- if (fwrite(outptr, 1, outsize, outfp) != outsize) {
- printf("outptr write fail");
- return -3;
- }
- printf("write OK\n");
- fclose(outfp);
- free(outptr);
- outptr = NULL;
- return 0;
- }
加了一个升级版的,可以兼顾stride和width不同时,把stride和width之间的像素裁剪掉,防止出现绿边的情况。
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <iostream>
-
- typedef unsigned char BYTE; // 定义BYTE类型,占1个字节
-
- void MipiRaw10ToP10(BYTE* pIn, unsigned long fsize, BYTE* pOut, unsigned long outsize, int width, int height, int stride)
- {
- printf("enter MipiRaw10ToP10\n");
- int index = 0;
- // 5个字节4个像素
- // 前面4个字节都是对应像素的高8位,最后一个字(第五个)每个像素的低2位
- // MIPIRaw 大端模式
- // BYTE0 :P1[0:7]
- // BYTE1 :P2[0:7]
- // BYTE2 :P3[0:7]
- // BYTE3 :P4[0:7]
- // BYTE4 :P4[8:9]P3[8:9]P2[8:9]P1[8:9]
- // UnpackRaw 小端模式
- // Pix1: BYTE0:[2:9], BYTE1:[0:1] == BYTE0:(P1[0:7]<< 2 + P1[8:9]), BYTE1:(P1[0:7] >> 6)
- // Pix2: 上同
- // Pix3: 上同
- // Pix4: 上同
- // Big endian
- int count = 0;
- bool unjustified = false;
- if (stride - width > 0) {
- unjustified = true;
- }
- for (long i = 0; i < fsize; i = i + 5)
- {
- if (unjustified) {
- // 一次转化4个像素,需要5个字节,转化后为8个字节
- if (count > width - 1) {
- // 偏移时按照stride和width的差值 * 1.25,即width和stride差的像素实际占用的字节数
- i = i + int((stride - width) * 1.25);
- count = 0;
- }
- }
- if (i > fsize || index > outsize) {
- break;
- }
- pOut[index++] = ((pIn[i] << 2) & 0xfc) | (pIn[i + 4] & 0x03);
- pOut[index++] = (pIn[i] >> 6) & 0x03;
-
- //pIn[i+4] >>= 2;
- pOut[index++] = ((pIn[i + 1] << 2) & 0xfc) | ((pIn[i + 4] >> 2) & 0x03);
- pOut[index++] = (pIn[i + 1] >> 6) & 0x03;
-
- //pIn[i+4] >>= 2;
- pOut[index++] = ((pIn[i + 2] << 2) & 0xfc) | ((pIn[i + 4] >> 4) & 0x03);
- pOut[index++] = (pIn[i + 2] >> 6) & 0x03;
-
- //pIn[i+4] >>= 2;
- pOut[index++] = ((pIn[i + 3] << 2) & 0xfc) | ((pIn[i + 4] >> 6) & 0x03);
- pOut[index++] = (pIn[i + 3] >> 6) & 0x03;
- count = count + 4;
- }
- printf("MipiRaw10ToP10 over\n");
- }
-
- void MipiRaw12ToP12(BYTE* pIn, unsigned long fsize, BYTE* pOut, unsigned long outsize, int width, int height, int stride)
- {
- printf("enter MipiRaw12ToP12\n");
- int index = 0;
- int count = 0;
- bool unjustified = false;
- if (stride - width > 0) {
- unjustified = true;
- }
- // 3个字节2个像素
- // 前面2个字节都是对应像素的高8位,最后一个字(第3个)每个像素的低4位
- // MIPIRaw 大端模式
- // BYTE0 :P1[0:7]
- // BYTE1 :P2[0:7]
- // BYTE2 :P2[8:11]P1[8:11]
- // UnpackRaw 小端模式
- // Pix1: BYTE0:[4:11], BYTE1:[0:3] == BYTE0:(P1[0:7]<< 4 + P1[8:11]), BYTE1:(P1[0:7] >> 4)
- // Pix2: 上同
- // Big endian
- for (long i = 0; i < fsize; i = i + 3)
- {
- if (unjustified) {
- // 一次转化2个像素,需要3个字节,转化后为4个字节
- if (count > width - 1) {
- // 偏移时按照stride和width的差值 * 1.5,即width和stride差的像素实际占用的字节数
- i = i + int((stride - width) * 1.5);
- count = 0;
- }
- }
- if (i > fsize || index > outsize) {
- break;
- }
- pOut[index++] = ((pIn[i] << 4) & 0xf0) | (pIn[i + 2] & 0x0f);
- pOut[index++] = (pIn[i] >> 4) & 0x0f;
-
- //pIn[i+2] >>= 4;
- pOut[index++] = ((pIn[i + 1] << 4) & 0xf0) | ((pIn[i + 2] >> 4) & 0x0f);
- pOut[index++] = (pIn[i + 1] >> 4) & 0x0f;
- count = count + 2;
- }
- printf("MipiRaw12ToP12 over\n");
- }
-
- void MipiRaw14ToP14(BYTE* pIn, BYTE* pOut, long number)
- {
- printf("enter MipiRaw14ToP14\n");
- int index = 0;
- // 7个字节4个像素
- // 前面4个字节都是对应像素的高8位,最后3个字对应每个像素的低6位
- // BYTE0 :P1[0:7]
- // BYTE1 :P2[0:7]
- // BYTE2 :P3[0:7]
- // BYTE3 :P4[0:7]
- // BYTE4 :P1[8:13]P2[8:9]
- // BYTE5 :P2[10:13]P3[8:11]
- // BYTE6 :P3[12:13]P4[8:13]
- // Big endian
- for (long i = 0; i < (number * 7) / 4; i = i + 7)
- {
- // Pix1
- pOut[index++] = ((pIn[i] << 6) & 0xc0) | ((pIn[i + 4] >> 2) & 0xcf);
- pOut[index++] = (pIn[i] >> 2) & 0x3f;
-
- // Pix2
- pOut[index++] = ((pIn[i + 1] << 6) & 0xc0) | ((pIn[i + 4] << 4) & 0x30) + ((pIn[i + 5] >> 4) & 0x0f);
- pOut[index++] = (pIn[i + 1] >> 2) & 0x3f;
-
- // Pix3
- pOut[index++] = ((pIn[i + 2] << 6) & 0xc0) | ((pIn[i + 5] << 2) & 0x3c) + ((pIn[i + 6] >> 6) & 0x03);
- pOut[index++] = (pIn[i + 2] >> 2) & 0x3f;
-
- // Pix4
- pOut[index++] = ((pIn[i + 3] << 6) & 0xc0) | ((pIn[i + 6]) & 0x3f);
- pOut[index++] = (pIn[i + 3] >> 2) & 0x3f;
- }
- printf("MipiRaw14ToP14 over\n");
- }
-
- int main(int argc, char* argv[])
- {
- FILE* fp = NULL;
- BYTE* ptr;
- BYTE* outptr = NULL;
- int err = 0;
- if (argc < 6) {
- return -1;
- }
- const char* filepath = argv[1];
- const char* height_str = argv[2];
- const char* width_str = argv[3];
- //const char* stride_str = argv[4];
- const char* bpp_str = argv[4];
- const char* outfilepath = argv[5];
- int width = 0;
- int height = 0;
- int stride = 0;
- int bpp = 0;
- width = atoi(width_str);
- height = atoi(height_str);
- bpp = atoi(bpp_str);
- //stride = atoi(stride_str);
- printf("width: %d, height: %d, bpp: %d, stride: %d\n", width, height, bpp, stride);
-
- // 输入源路径并打开raw图像文件
- printf("=======raw image process===========\n");
- err = fopen_s(&fp, filepath, "rb");
- if (NULL == fp)
- {
- printf("can not open the raw image ");
- return 0;
- }
- else
- {
- printf("read OK\n");
- }
- //Sleep(1000); /* windows 使用Sleep,参数为毫秒 */
- // 分配内存并将图像读到二维数组中
- fseek(fp, 0, SEEK_END);
- unsigned long fsize = ftell(fp);
- rewind(fp);
- // 根据raw图实际大小,计算raw的stride
- if (10 == bpp) {
- stride = int(fsize * 4 / 5 / height);
- if (stride % 64 > 0) {
- stride = 0;
- }
- } else if (12 == bpp) {
- stride = int(fsize * 2 / 3 / height);
- if (stride % 64 > 0) {
- stride = 0;
- }
- } else if (14 == bpp) {
- stride = int(fsize * 4 / 7 / height);
- if (stride % 64 > 0) {
- stride = 0;
- }
- }
- ptr = (BYTE*)malloc(fsize * sizeof(BYTE));
- if (ptr == NULL) {
- printf("ptr malloc fail\n");
- return -2;
- }
- if (fread(ptr, 1, fsize, fp) != fsize) {
- printf("read file error.\n");
- return -1;
- }
- fclose(fp);
-
- unsigned long outsize = width * height * 2;
- outptr = (BYTE*)malloc(outsize * sizeof(BYTE));
- if (outptr == NULL) {
- printf("outptr malloc fail\n");
- return -2;
- }
- if (10 == bpp) {
- MipiRaw10ToP10(ptr, fsize, outptr, outsize, width, height, stride);
- }
- else if (12 == bpp) {
- MipiRaw12ToP12(ptr, fsize, outptr, outsize, width, height, stride);
- }
- else if (14 == bpp) {
- MipiRaw14ToP14(ptr, outptr, width * height);
- }
-
- free(ptr);
- ptr = NULL;
- // 这里可以对二维数组中的图像数据进行处理
- // 将处理后的图像数据输出至文件
- printf("Input the raw_image path for save: \n");
- //scanf("%s",outpath);
- FILE* outfp = NULL;
- err = fopen_s(&outfp, outfilepath, "wb");
- if (outfp == NULL) {
- printf("can not create the raw_image\n");
- return 0;
- }
- else {
- printf("fopen OK\n");
- }
- printf("creat file OK\n");
- if (fwrite(outptr, 1, outsize, outfp) != outsize) {
- printf("outptr write fail");
- return -3;
- }
- printf("write OK\n");
- fclose(outfp);
- free(outptr);
- outptr = NULL;
- return 0;
- }
注意:这里的存储方式是UnpackRaw是小端模式 + MSB优先的存储方式,MipiRaw是大端模式 + MSB优先的存储方式。可能还有别的存储方式,大家在转换的时候,先搞明白UnpackRaw和MipiRaw的存储方式再写具体代码。共勉!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。