C言語の基本的なこと、入門サイトにのっているようなことは理解していると思っていますが
C言語での実装経験はほとんどありません。
主な実装経験はC#、C++です。
よろしくお願いします。
やりたい事
カメラのセンサーからYUV422形式で静止画データを読み込んでいます。
YUV422形式のデータをRGBに変換してポインタに一時格納
このデータをjpeg形式に落としたいと思っています。
動作環境
OS:Linux
ディストリビューション:debian etch
コンパイラ名 : gcc-4.1.2
API:l4v2
関係するライブラリ:jpeglib.h
l4v2の仕様は
http://v4l.videotechnology.com/dwg/v4l2 ... X-FMT-YUYV
になります。
以下はカメラからYUV422形式で取り込んだデータをバッファに格納してjpegに落とすところまでのソースになります。
#define CLIP(color) (unsigned char)(((color)>0xFF)?0xff:(((color)<0)?0:(color)))
static void
// pは入力データを格納しているポインタ
process_image (const void * p)
{
int i, j;
unsigned char *writer;
const unsigned char *reader;
unsigned char b, g1, g2, r;
unsigned char fname_jpeg[FILENAME_MAX];// FILENAME_MAXは50文字
unsigned char fname_ppm[FILENAME_MAX];
unsigned char ext[4+1]; // 拡張子4文字 + 終端文字
FILE *fp;
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
unsigned char *line;
reader = (unsigned char *)p;
unsigned int height = CAPTURE_HEIGHT; //480
unsigned int width = CAPTURE_WIDTH; //640
int u,v,u1,rg,v1;
// YUV形式→RGBに変換してポインタに格納します
// 計算式は抜粋してきたものを使用しています
for (j = height;j >= 0;j--) {
for (i = 0; i < width; i += 2) {
u = reader[1];
v = reader[3];
u1 = (((u - 128) << 7) + (u - 128)) >> 6;
rg = (((u - 128) << 1) + (u - 128) + ((v - 128) << 2) + ((v - 128) << 1)) >> 3;
v1 = (((v - 128) << 1) + (v - 128)) >> 1;
*writer++ = CLIP(reader[0] + u1);
*writer++ = CLIP(reader[0] - rg);
*writer++ = CLIP(reader[0] + v1);
*writer++ = CLIP(reader[2] + u1);
*writer++ = CLIP(reader[2] - rg);
*writer++ = CLIP(reader[2] + v1);
reader += 4;
}
}
// JPEG
if ( save_jpeg == 1 )
{
strcpy( ext, ".jpg" );
// 終端文字の付加
ext[4+1] = '\0';
sprintf( fname_jpeg, "out%05d%s", ImgNum, ext );
fp = fopen(fname_jpeg, "w");
if ( fp == NULL )
{
//Errno_Exit("Error: Save image file");
}
cinfo.err = jpeg_std_error( &jerr );
jpeg_create_compress( &cinfo );
jpeg_stdio_dest(&cinfo, fp);
cinfo.image_width = width;
cinfo.image_height = height;
cinfo.input_components = 3; // color component per pixel
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults( &cinfo );
jpeg_set_quality(&cinfo, 100, TRUE); // 品質 [0-100]
jpeg_start_compress(&cinfo, TRUE);
line = writer;
for (i=0;i < height; i++)
{
line += width * 3;
jpeg_write_scanlines(&cinfo, &line, 1); // ←ここでエラー
}
jpeg_finish_compress( &cinfo );
jpeg_destroy_compress( &cinfo );
fclose( fp );
}
ImgNum++;
}
実行しますとSegmentation faultとなります。jpeg_write_scanlines(&cinfo, &line, 1);
までは動作しています。
jpegデータは吐き出されますが空のデータになります。
Segmentation faultについて調べましたがアクセスしたアドレス範囲がおかしい時に
起こるエラーと認識しております。正しいでしょうか。
読み書きのポインタのアドレスがおかしいと思うのですが、この場合は
実際に読んできたデータ数より大きい値のアドレスにアクセスしてそれを書き出そうとしているから
エラーが発生するのでしょうか。
その場合はどのように修正したらよろしいでしょうか。
以上です。どうぞご教授よろしくお願いします。