2 *----------------------------------------------------------------------------
3 * Pencam Tool for Poseidon
4 *----------------------------------------------------------------------------
5 * By Chris Hodges <chrisly@platon42.de>
10 #include <proto/dos.h>
11 #include <proto/exec.h>
12 #include <proto/poseidon.h>
13 #include <proto/intuition.h>
14 #include <proto/graphics.h>
15 #include <proto/diskfont.h>
17 #include "PencamTool.h"
24 #define ARGS_INTERVAL 2
28 #define ARGS_SHARPEN 6
31 #define ARGS_FONTSIZE 9
33 #define ARGS_SIZEOF 11
35 const char PencamTool_prgname
[] = "PencamTool";
36 static const char *template = "TO/A,PICNUM/N,INTERVAL/N,UPTO/N/K,NOBEEP/S,GAMMA/K,SHARPEN/S,TEXT/K,FONT/K,FONTSIZE/N/K,UNIT/N/K";
37 const char PencamTool_version
[] = "$VER: PencamTool 1.7 (12.06.09) by Chris Hodges <chrisly@platon42.de>";
38 static IPTR ArgsArray
[ARGS_SIZEOF
];
39 static struct RDArgs
*ArgsHook
= NULL
;
41 static UWORD gammaredtab
[256];
42 static UWORD gammagreentab
[256];
43 static UWORD gammabluetab
[256];
45 struct RastPort fontrp
;
46 struct RastPort picrp
;
47 struct TextAttr avenirta
;
48 struct TextFont
*avenirfont
= NULL
;
49 struct BitMap
*fontbm
= NULL
;
50 ULONG tlength
, theight
;
54 AROS_UFP3(void, releasehook
,
55 AROS_UFPA(struct Hook
*, hook
, A0
),
56 AROS_UFPA(APTR
, pab
, A2
),
57 AROS_UFPA(struct NepClassPencam
*, nch
, A1
));
59 struct NepClassPencam
* SetupPencam(void);
60 struct NepClassPencam
* AllocPencam(struct NepClassPencam
*nch
);
61 void FreePencam(struct NepClassPencam
*nch
);
66 void CreateGammaTab(void)
69 UWORD red
, green
, blue
;
72 if(!ArgsArray
[ARGS_GAMMA
])
76 gamma
= atof((char *) ArgsArray
[ARGS_GAMMA
]);
77 gammaredtab
[0] = gammagreentab
[0] = gammabluetab
[0] = 0;
86 y
= pow((x
/256.0), gamma
)*255.0;
87 red
= (UWORD
) (y
*1.08);
89 blue
= (UWORD
) (y
*0.95);
90 gammaredtab
[i
] = red
< 256 ? red
: 255;
91 gammagreentab
[i
] = green
;
92 gammabluetab
[i
] = blue
;
96 AROS_UFH3(void, releasehook
,
97 AROS_UFHA(struct Hook
*, hook
, A0
),
98 AROS_UFHA(APTR
, pab
, A2
),
99 AROS_UFHA(struct NepClassPencam
*, nch
, A1
))
102 /*psdAddErrorMsg(RETURN_WARN, (STRPTR) prgname,
104 Signal(nch
->nch_Task
, SIGBREAKF_CTRL_C
);
108 struct NepClassPencam
* SetupPencam(void)
110 struct NepClassPencam
*nch
;
111 struct PsdDevice
*pd
= NULL
;
112 struct PsdAppBinding
*pab
;
115 if(ArgsArray
[ARGS_UNIT
])
117 unit
= *((ULONG
*) ArgsArray
[ARGS_UNIT
]);
125 pd
= psdFindDevice(pd
,
127 DA_ProductID
, 0x0202,
129 } while(pd
&& (unit
--));
133 PutStr("No Pencam found!\n");
136 if((nch
= psdAllocVec(sizeof(struct NepClassPencam
))))
138 nch
->nch_Device
= pd
;
139 nch
->nch_ReleaseHook
.h_Entry
= (APTR
) releasehook
;
141 pab
= psdClaimAppBinding(ABA_Device
, pd
,
142 ABA_ReleaseHook
, &nch
->nch_ReleaseHook
,
151 PutStr("Couldn't allocate Pencam...\n");
153 psdReleaseAppBinding(pab
);
155 PutStr("Couldn't claim binding!\n");
159 PutStr("Hohum...\n");
164 struct RastPort
* SetupText(void)
166 STRPTR text
= (STRPTR
) ArgsArray
[ARGS_TEXT
];
167 InitRastPort(&fontrp
);
168 if(ArgsArray
[ARGS_FONT
])
170 avenirta
.ta_Name
= (STRPTR
) ArgsArray
[ARGS_FONT
];
171 if(ArgsArray
[ARGS_FONTSIZE
])
173 avenirta
.ta_YSize
= *((ULONG
*) ArgsArray
[ARGS_FONTSIZE
]);
175 avenirta
.ta_YSize
= 8;
177 avenirta
.ta_Style
= 0L;
178 avenirta
.ta_Flags
= 0L;
179 if(!(avenirfont
= OpenDiskFont(&avenirta
)))
181 Printf("Couldn't open font!\n");
183 SetFont(&fontrp
, avenirfont
);
186 tlength
= TextLength(&fontrp
, text
, (ULONG
) strlen(text
));
187 theight
= fontrp
.Font
->tf_YSize
;
188 if(!(fontbm
= AllocBitMap(tlength
, theight
, 1L, BMF_CLEAR
, NULL
)))
190 Printf("Couldn't allocate font bitmap memory (%ldx%ld)", tlength
, theight
);
193 fontrp
.BitMap
= fontbm
;
194 //printf("String: %s\nLength: %d\n",(char *)argsarray[ARGS_TEXT], tlength);
195 Move(&fontrp
, 0, (LONG
) fontrp
.Font
->tf_Baseline
);
196 Text(&fontrp
, text
, (ULONG
) strlen(text
));
209 CloseFont(avenirfont
);
214 void PasteText(struct PCImageHeader
*pcih
, UBYTE
*output
)
218 LONG vw
= pcih
->pcih_ImgWidth
;
224 tarx
= (vw
-tlength
) >> 1;
228 tary
= (pcih
->pcih_ImgHeight
-theight
-theight
);
229 for(y
= 0; y
< theight
; y
++)
231 for(x
= 0; (x
< tlength
) && (x
+tarx
+2 < vw
); x
++)
233 pix
= ReadPixel(&fontrp
, x
, y
);
236 op
= &output
[((tary
+y
)*vw
+tarx
+x
)*3];
252 for(y
= 0; y
< theight
; y
++)
254 for(x
= 0; (x
< tlength
) && (x
+tarx
+2 < vw
); x
++)
256 pix
= ReadPixel(&fontrp
, x
, y
);
259 op
= &output
[((tary
+y
)*vw
+tarx
+x
)*3];
268 struct NepClassPencam
* AllocPencam(struct NepClassPencam
*nch
)
270 struct List
*cfglist
;
272 struct List
*altiflist
;
277 nch
->nch_Task
= FindTask(NULL
);
279 psdGetAttrs(PGA_DEVICE
, nch
->nch_Device
,
280 DA_ConfigList
, &cfglist
,
283 if(!cfglist
->lh_Head
->ln_Succ
)
285 PutStr("No configs?\n");
289 nch
->nch_Config
= (struct PsdConfig
*) cfglist
->lh_Head
;
291 psdGetAttrs(PGA_CONFIG
, nch
->nch_Config
,
292 CA_InterfaceList
, &iflist
,
295 if(!iflist
->lh_Head
->ln_Succ
)
297 PutStr("No interfaces?\n");
301 nch
->nch_Interface
= (struct PsdInterface
*) iflist
->lh_Head
;
302 psdGetAttrs(PGA_INTERFACE
, nch
->nch_Interface
,
303 IFA_InterfaceNum
, &ifnum
,
304 IFA_AlternateNum
, &altnum
,
305 IFA_AlternateIfList
, &altiflist
,
306 IFA_EndpointList
, &eplist
,
309 if((nch
->nch_TaskMsgPort
= CreateMsgPort()))
311 if((nch
->nch_EP0Pipe
= psdAllocPipe(nch
->nch_Device
, nch
->nch_TaskMsgPort
, NULL
)))
313 if((ifnum
== 0) && (altnum
== 0))
315 psdSetAltInterface(nch
->nch_EP0Pipe
, altiflist
->lh_Head
);
317 psdGetAttrs(PGA_CONFIG
, nch
->nch_Config
,
318 CA_InterfaceList
, &iflist
,
320 nch
->nch_Interface
= (struct PsdInterface
*) iflist
->lh_Head
;
321 psdGetAttrs(PGA_INTERFACE
, nch
->nch_Interface
,
322 IFA_InterfaceNum
, &ifnum
,
323 IFA_AlternateNum
, &altnum
,
324 IFA_EndpointList
, &eplist
,
326 if(eplist
->lh_Head
->ln_Succ
)
328 nch
->nch_BulkEP
= (struct PsdEndpoint
*) eplist
->lh_Head
;
329 psdGetAttrs(PGA_ENDPOINT
, nch
->nch_BulkEP
,
330 EA_MaxPktSize
, &nch
->nch_BulkPktSize
,
332 if((nch
->nch_BulkPipe
= psdAllocPipe(nch
->nch_Device
, nch
->nch_TaskMsgPort
, nch
->nch_BulkEP
)))
334 psdSetAttrs(PGA_PIPE
, nch
->nch_BulkPipe
,
335 PPA_AllowRuntPackets
, TRUE
,
336 PPA_NakTimeout
, TRUE
,
337 PPA_NakTimeoutTime
, 5000,
341 PutStr("Couldn't allocate bulk pipe.\n");
344 PutStr("No bulk endpoint?\n");
346 psdFreePipe(nch
->nch_EP0Pipe
);
348 PutStr("Couldn't allocate default pipe\n");
350 DeleteMsgPort(nch
->nch_TaskMsgPort
);
356 void FreePencam(struct NepClassPencam
*nch
)
360 psdGetAttrs(PGA_DEVICE
, nch
->nch_Device
,
363 psdReleaseAppBinding(pab
);
364 psdFreePipe(nch
->nch_BulkPipe
);
365 psdFreePipe(nch
->nch_EP0Pipe
);
366 DeleteMsgPort(nch
->nch_TaskMsgPort
);
370 /**************************************************************************/
372 void bayer_unshuffle(struct PCImageHeader
*pcih
, UBYTE
*raw
, UBYTE
*output
)
375 ULONG w
= pcih
->pcih_ImgWidth
>>1;
376 ULONG vw
= pcih
->pcih_ImgWidth
;
377 ULONG vh
= pcih
->pcih_ImgHeight
;
382 for(y
= 0; y
< vh
; y
++)
385 raweven
= &rawodd
[w
];
406 void bayer_demosaic(struct PCImageHeader
*pcih
, UBYTE
*output
)
409 LONG vw
= pcih
->pcih_ImgWidth
;
411 LONG vh
= pcih
->pcih_ImgHeight
;
413 for(y
= 1; y
< vh
-1; y
++)
415 op
= &output
[(y
*vw
+ 1)*3];
416 for(x
= 1; x
< vw
-1; x
++) /* work out pixel type */
418 switch(((y
+ y
) & 2) + (x
& 1))
420 case 0: /* green. red lr, blue tb */
421 *op
= (((UWORD
) op
[-3]) + ((UWORD
) op
[3])) >> 1; /* Set red */
422 op
[2] = (((UWORD
) op
[2-vw3
]) + ((UWORD
) op
[2+vw3
]) + 1) >> 1; /* Set blue */
424 case 1: /* red. green lrtb, blue diagonals */
425 op
[1] = (((UWORD
) op
[-2]) + ((UWORD
) op
[4]) +
426 ((UWORD
) op
[1-vw3
]) + ((UWORD
) op
[1+vw3
]) + 2) >> 2; /* Set green */
427 op
[2] = (((UWORD
) op
[-1-vw3
]) + ((UWORD
) op
[5-vw3
]) +
428 ((UWORD
) op
[-1+vw3
]) + ((UWORD
) op
[5+vw3
]) + 2) >> 2; /* Set blue */
430 case 2: /* blue. green lrtb, red diagonals */
431 op
[1] = (((UWORD
) op
[-2]) + ((UWORD
) op
[4]) +
432 ((UWORD
) op
[1-vw3
]) + ((UWORD
) op
[1+vw3
]) + 2) >> 2; /* Set green */
433 *op
= (((UWORD
) op
[-3-vw3
]) + ((UWORD
) op
[3-vw3
]) +
434 ((UWORD
) op
[-3+vw3
]) + ((UWORD
) op
[3+vw3
]) + 2) >> 2; /* Set red */
436 case 3: /* green. blue lr, red tb */
437 op
[2] = (((UWORD
) op
[-1]) + ((UWORD
) op
[5]) + 1) >> 1; /* Set blue */
438 *op
= (((UWORD
) op
[-vw3
]) + ((UWORD
) op
[vw3
]) + 1) >> 1; /* Set red */
446 void gammacorrection(struct PCImageHeader
*pcih
, UBYTE
*output
)
448 ULONG cnt
= pcih
->pcih_ImgWidth
*pcih
->pcih_ImgHeight
;
451 *output
= gammaredtab
[*output
];
453 *output
= gammagreentab
[*output
];
455 *output
= gammabluetab
[*output
];
460 void sharpen5x5(struct PCImageHeader
*pcih
, UBYTE
*input
, UBYTE
*output
)
463 LONG vw
= pcih
->pcih_ImgWidth
;
466 LONG vh
= pcih
->pcih_ImgHeight
;
475 for(y
= 2; y
< vh
-2; y
++)
477 op
= &input
[((y
-2)*vw
)*3];
478 linem2
[0] = *op
++; // -2
481 linem2
[0] += *op
++; // -1
484 linem2
[0] += *op
++; // 0
487 linem2
[0] += *op
++; // 1
490 linem2
[0] += *op
++; // 2
494 op
= &input
[((y
-1)*vw
+1)*3];
495 linem1
[0] = *op
++; // -1
498 linem1
[0] += *op
++; // 0
501 linem1
[0] += *op
++; // 1
504 linem1
[0] += linem1
[0]+linem1
[0];
505 linem1
[1] += linem1
[1]+linem1
[1];
506 linem1
[2] += linem1
[2]+linem1
[2];
507 linem1
[0] += *op
++; // 2
510 linem1
[0] += op
[-15]; // -2
511 linem1
[1] += op
[-14];
512 linem1
[2] += op
[-13];
514 op
= &input
[((y
+1)*vw
+1)*3];
515 linep1
[0] = *op
++; // -1
518 linep1
[0] += *op
++; // 0
521 linep1
[0] += *op
++; // 1
524 linep1
[0] += linep1
[0]+linep1
[0];
525 linep1
[1] += linep1
[1]+linep1
[1];
526 linep1
[2] += linep1
[2]+linep1
[2];
527 linep1
[0] += *op
++; // 2
530 linep1
[0] += op
[-15]; // -2
531 linep1
[1] += op
[-14];
532 linep1
[2] += op
[-13];
534 op
= &input
[((y
+2)*vw
)*3];
535 linep2
[0] = *op
++; // -2
538 linep2
[0] += *op
++; // -1
541 linep2
[0] += *op
++; // 0
544 linep2
[0] += *op
++; // 1
547 linep2
[0] += *op
++; // 2
551 op
= &input
[(y
*vw
+ 2)*3];
552 oop
= &output
[(y
*vw
+ 2)*3];
553 for(x
= 2; x
< vw
-2; x
++) /* work out pixel type */
556 val
[0] = op
[-3] + op
[3];
557 val
[1] = op
[-2] + op
[4];
558 val
[2] = op
[-1] + op
[5];
559 val
[0] += val
[0] + val
[0] + op
[-6] + op
[6] + linem2
[0] + linem1
[0] + linep1
[0] + linep2
[0];
560 val
[1] += val
[1] + val
[1] + op
[-5] + op
[7] + linem2
[1] + linem1
[1] + linep1
[1] + linep2
[1];
561 val
[2] += val
[2] + val
[2] + op
[-4] + op
[8] + linem2
[2] + linem1
[2] + linep1
[2] + linep2
[2];
562 val
[0] -= op
[0] * 56;
563 val
[1] -= op
[1] * 56;
564 val
[2] -= op
[2] * 56;
567 *oop
++ = (val
[0] > 0) ? 0 : ((val
[0] < -MAXVAL
) ? 255 : (-val
[0]+8)>>4);
568 *oop
++ = (val
[1] > 0) ? 0 : ((val
[1] < -MAXVAL
) ? 255 : (-val
[1]+8)>>4);
569 *oop
++ = (val
[2] > 0) ? 0 : ((val
[2] < -MAXVAL
) ? 255 : (-val
[2]+8)>>4);
571 /* Update line y-2 */
572 linem2
[0] -= op
[-vw6
-6];
573 linem2
[0] += op
[-vw6
+9];
574 linem2
[1] -= op
[-vw6
-5];
575 linem2
[1] += op
[-vw6
+10];
576 linem2
[2] -= op
[-vw6
-4];
577 linem2
[2] += op
[-vw6
+11];
579 /* Update line y-1 */
580 linem1
[0] -= op
[-vw3
-6];
581 linem1
[0] -= op
[-vw3
-3]<<1;
582 linem1
[0] += op
[-vw3
+6]<<1;
583 linem1
[0] += op
[-vw3
+9];
584 linem1
[1] -= op
[-vw3
-5];
585 linem1
[1] -= op
[-vw3
-2]<<1;
586 linem1
[1] += op
[-vw3
+7]<<1;
587 linem1
[1] += op
[-vw3
+10];
588 linem1
[2] -= op
[-vw3
-4];
589 linem1
[2] -= op
[-vw3
-1]<<1;
590 linem1
[2] += op
[-vw3
+8]<<1;
591 linem1
[2] += op
[-vw3
+11];
593 /* Update line y+1 */
594 linep1
[0] -= op
[vw3
-6];
595 linep1
[0] -= op
[vw3
-3]<<1;
596 linep1
[0] += op
[vw3
+6]<<1;
597 linep1
[0] += op
[vw3
+9];
598 linep1
[1] -= op
[vw3
-5];
599 linep1
[1] -= op
[vw3
-2]<<1;
600 linep1
[1] += op
[vw3
+7]<<1;
601 linep1
[1] += op
[vw3
+10];
602 linep1
[2] -= op
[vw3
-4];
603 linep1
[2] -= op
[vw3
-1]<<1;
604 linep1
[2] += op
[vw3
+8]<<1;
605 linep1
[2] += op
[vw3
+11];
607 /* Update line y-2 */
608 linep2
[0] -= op
[vw6
-6];
609 linep2
[0] += op
[vw6
+9];
610 linep2
[1] -= op
[vw6
-5];
611 linep2
[1] += op
[vw6
+10];
612 linep2
[2] -= op
[vw6
-4];
613 linep2
[2] += op
[vw6
+11];
620 APTR
TransferImage(struct NepClassPencam
*nch
, struct PCImageHeader
*pcih
)
627 rawbuf
= psdAllocVec(pcih
->pcih_ImgSize
);
630 Printf("Couldn't allocate %ld bytes of memory.\n", pcih
->pcih_ImgSize
);
633 /* Workaround for a firmware bug */
634 ioerr
= psdDoPipe(nch
->nch_BulkPipe
, rawbuf
, 64);
637 if(((ULONG
*) rawbuf
)[0] == AROS_LONG2BE(0xed15ed15))
639 /* Junk packet at the beginning! */
640 ioerr
= psdDoPipe(nch
->nch_BulkPipe
, rawbuf
, pcih
->pcih_ImgSize
);
642 ioerr
= psdDoPipe(nch
->nch_BulkPipe
, &rawbuf
[64], pcih
->pcih_ImgSize
-64);
647 imgbuf
= psdAllocVec((ULONG
) pcih
->pcih_ImgWidth
* (ULONG
) pcih
->pcih_ImgHeight
* 3);
650 bayer_unshuffle(pcih
, rawbuf
, imgbuf
);
652 bayer_demosaic(pcih
, imgbuf
);
653 if(ArgsArray
[ARGS_SHARPEN
])
655 newimgbuf
= psdAllocVec((ULONG
) pcih
->pcih_ImgWidth
* (ULONG
) pcih
->pcih_ImgHeight
* 3);
658 sharpen5x5(pcih
, imgbuf
, newimgbuf
);
663 if(ArgsArray
[ARGS_GAMMA
])
665 gammacorrection(pcih
, imgbuf
);
667 if(ArgsArray
[ARGS_TEXT
])
669 PasteText(pcih
, imgbuf
);
673 Printf("Couldn't allocate %ld bytes of memory.\n", pcih
->pcih_ImgSize
);
676 Printf("Bulk transfer failed: %s (%ld)\n",
677 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
683 APTR
GetPicture(struct NepClassPencam
*nch
, ULONG picnum
, struct PCImageHeader
*pcih
)
688 pp
= nch
->nch_EP0Pipe
;
689 psdPipeSetup(pp
, URTF_IN
|URTF_VENDOR
|URTF_DEVICE
,
690 CMDID_GET_IMAGE_HEADER
, picnum
, 0);
691 ioerr
= psdDoPipe(pp
, pcih
, sizeof(struct PCImageHeader
));
694 Printf("GET_IMAGE_HEADER failed: %s (%ld)\n",
695 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
699 psdPipeSetup(pp
, URTF_OUT
|URTF_VENDOR
|URTF_DEVICE
,
700 CMDID_UPLOAD_IMAGE
, picnum
, 0);
701 ioerr
= psdDoPipe(pp
, pcih
, sizeof(struct PCImageHeader
));
704 /* endianess conversion */
705 pcih
->pcih_ImgSize
= AROS_BE2LONG(pcih
->pcih_ImgSize
);
706 pcih
->pcih_ImgWidth
= AROS_BE2WORD(pcih
->pcih_ImgWidth
);
707 pcih
->pcih_ImgHeight
= AROS_BE2WORD(pcih
->pcih_ImgHeight
);
708 pcih
->pcih_FineExp
= AROS_BE2WORD(pcih
->pcih_FineExp
);
709 pcih
->pcih_CoarseExp
= AROS_BE2WORD(pcih
->pcih_CoarseExp
);
711 return(TransferImage(nch
, pcih
));
713 Printf("UPLOAD_IMAGE failed: %s (%ld)\n",
714 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
719 APTR
GetVideoSnap(struct NepClassPencam
*nch
, struct PCImageHeader
*pcih
)
724 pp
= nch
->nch_EP0Pipe
;
725 psdPipeSetup(pp
, URTF_IN
|URTF_VENDOR
|URTF_DEVICE
,
726 CMDID_GRAB_UPLOAD
, ArgsArray
[ARGS_NOBEEP
] ? 0x6000L
: 0x2000L
, 0);
727 ioerr
= psdDoPipe(pp
, pcih
, 8);
730 Printf("GRAB_UPLOAD failed: %s (%ld)\n",
731 psdNumToStr(NTS_IOERR
, ioerr
, "unknown"), ioerr
);
735 /* endianess conversion */
736 pcih
->pcih_ImgSize
= AROS_BE2LONG(pcih
->pcih_ImgSize
);
737 pcih
->pcih_ImgWidth
= AROS_BE2WORD(pcih
->pcih_ImgWidth
);
738 pcih
->pcih_ImgHeight
= AROS_BE2WORD(pcih
->pcih_ImgHeight
);
739 pcih
->pcih_FineExp
= AROS_BE2WORD(pcih
->pcih_FineExp
);
740 pcih
->pcih_CoarseExp
= AROS_BE2WORD(pcih
->pcih_CoarseExp
);
742 return(TransferImage(nch
, pcih
));
745 int main(int argc
, char *argv
[])
747 struct NepClassPencam
*nch
;
748 struct PCImageHeader pcih
;
756 if(!(ArgsHook
= ReadArgs(template, ArgsArray
, NULL
)))
758 PutStr("Wrong arguments!\n");
761 ps
= OpenLibrary("poseidon.library", 1);
767 if(ArgsArray
[ARGS_TEXT
])
773 return(RETURN_ERROR
);
776 if(!(nch
= SetupPencam()))
781 return(RETURN_ERROR
);
785 if(ArgsArray
[ARGS_PICNUM
])
787 picnum
= *((ULONG
*) ArgsArray
[ARGS_PICNUM
]);
794 if(ArgsArray
[ARGS_PICNUM
])
796 imgbuf
= GetPicture(nch
, picnum
, &pcih
);
798 imgbuf
= GetVideoSnap(nch
, &pcih
);
802 psdSafeRawDoFmt(buf
, 256, (STRPTR
) ArgsArray
[ARGS_TO
], imgcount
);
803 outfile
= Open(buf
, MODE_NEWFILE
);
807 ULONG h
= pcih
.pcih_ImgHeight
;
809 ULONG w
= pcih
.pcih_ImgWidth
*3;
811 for(y
= 0; y
< vh
; y
++)
813 memcpy(imgbuf
+y
*vw
, imgbuf
+(y
+2)*w
+6, (size_t) vw
);
815 FPrintf(outfile
, "P6\n%ld %ld\n255\n", vw
/3, vh
);
817 Write(outfile
, imgbuf
, vw
*vh
);
819 Printf("Wrote image into '%s'.\n", buf
);
822 Printf("Could not open file '%s' for writing!\n", buf
);
828 sigs
= SetSignal(0, 0);
829 if(sigs
& SIGBREAKF_CTRL_C
)
833 if(ArgsArray
[ARGS_INTERVAL
])
835 if((!ArgsArray
[ARGS_PICNUM
]) && ArgsArray
[ARGS_UPTO
])
837 if(imgcount
> *((ULONG
*) ArgsArray
[ARGS_UPTO
]))
842 Delay(*((ULONG
*) ArgsArray
[ARGS_INTERVAL
]));
844 if(ArgsArray
[ARGS_UPTO
])
846 if(picnum
< *((ULONG
*) ArgsArray
[ARGS_UPTO
]))
856 sigs
= SetSignal(0, 0);
857 if(sigs
& SIGBREAKF_CTRL_C
)