作業日記@HatenaBlog

各種の作業メモ

参考にしたソース

すでに消滅したサイト↓
http://web.archive.org/web/20031204181630/http://junkun.vbl.tsukuba.ac.jp/~junkun/capture.html
そのソース↓
http://web.archive.org/web/20031204181630/http://junkun.vbl.tsukuba.ac.jp/~junkun/DWNLD/cap.tgz

/* 画像を1枚 jpeg 形式で保存する */
/* $Id: cap.c,v 1.3 1998/01/22 15:50:16 junkun Exp $ */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/fcntl.h>
#include <machine/ioctl_meteor.h>

#include "jpeglib.h"

extern int errno;

#define ROWS 120
#define COLS 160
#define SIZE (ROWS * COLS * 4)

JSAMPLE * image_buffer;/* Points to large array of R,G,B-order data */
char *optarg; /* for getopt */
char *mmbuf;
int verv=0; /* for debug mode */

void save(char*);
void usage(){exit(1);}

void
main(int argc, char* argv[])
{
struct meteor_geomet geo;
char *fname="now.jpg";
int iport=METEOR_INPUT_DEV0; /* コネクタ番号 */
int ch;
int i,c;

while( (ch=getopt(argc, argv, "i:o:v") )!=EOF){
switch(ch){
case 'i':
/* 入力端子の設定 */
i=atoi(optarg);
if(i!=0&&i!=1)
usage();
iport=(i==0?METEOR_INPUT_DEV0:METEOR_INPUT_DEV1);
break;
case 'o':
/* 出力ファイル名の設定 */
fname=optarg;
break;
case 'v':
/* 冗長モード */
verv=1;
break;
case '?':
default:
usage();
}
}

if ( (i = open("/dev/bktr0", O_RDONLY) ) < 0) {
printf("open failed");
exit(1);
}

geo.rows = ROWS;
geo.columns = COLS;
geo.frames = 1;
geo.oformat = METEOR_GEO_RGB24; /* 24bit mode */

/* 画像のサイズを決定 */
if (ioctl(i, METEORSETGEO, &geo) < 0) {
printf("ioctl failed: %d", errno);
exit(1);
}

/* 入力画像フォーマットを決定 */
c = METEOR_FMT_NTSC;
if (ioctl(i, METEORSFMT, &c) < 0) {
printf("ioctl failed: %d", errno);
exit(1);
}

/* 入力端子を決定 */
if (ioctl(i, METEORSINPUT, &iport) < 0) {
printf("ioctl failed: %d", errno);
exit(1);
}

/* コントラスト */
c = 80;
ioctl(i, METEORSCONT, &c);
ioctl(i, METEORGCONT, &c);
if(verv)
printf ("contrast %d\n",c);

/* 明るさ */
c = 80;
ioctl(i, METEORSBRIG, &c);
ioctl(i, METEORGBRIG, &c);
if(verv)
printf ("bright %d\n",c);

mmbuf=(char *)mmap( (caddr_t)0, SIZE, PROT_READ, MAP_SHARED, i, (off_t)0);

/* single frame capture */
/* c = METEOR_CAP_SINGLE ;*/
/*
* 取り込みを開始してから安定するまでしばらく時間がかかるので、一画
* 面のみの取り込みは現実的ではないようだ。
*/
c = METEOR_CAP_CONTINOUS;
ioctl(i, METEORCAPTUR, &c); /* wait for the frame */

/* 画像が安定するのを待つ */
sleep(1);

/* 画像を jpeg 形式で保存 */
save(fname);

/* 連続取り込みの中止 */
c = METEOR_CAP_STOP_CONT ;
ioctl(i, METEORCAPTUR, &c);

close(i);
exit(0);
}

void save(char *fname)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
FILE *of;
JSAMPROW row_pointer;
char buf[SIZE];
int row_stride;
int i,j;

for (i = 0, j=0; i < SIZE; i +=4){
buf[j++] = mmbuf[i+2];
buf[j++] = mmbuf[i+1];
buf[j++] = mmbuf[i];
}

cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);

if( (of=fopen(fname, "w") )==NULL){
fprintf(stderr, "can't open %s\n", fname);
exit(1);
}
jpeg_stdio_dest(&cinfo, of);

cinfo.image_width = COLS; /* image width and height, in pixels */
cinfo.image_height = ROWS;
cinfo.input_components = 3;/* # of color components per pixel */
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, 80, TRUE /* limit to baseline-JPEG values */);
jpeg_start_compress(&cinfo, TRUE);
row_stride = COLS * 3;/* JSAMPLEs per row in image_buffer */

while (cinfo.next_scanline < cinfo.image_height) {
row_pointer = (unsigned char*)& buf[cinfo.next_scanline * row_stride];
(void) jpeg_write_scanlines(&cinfo, &row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
fclose(of);
jpeg_destroy_compress(&cinfo);
}