forgotten commit. disabled until egl is adapted.
[AROS-Contrib.git] / gfx / lunapaint / src / app / export_import.c
blob25464b0b4598ae51404db222c48539520f679453
1 /****************************************************************************
2 * *
3 * export_import.c -- Lunapaint, *
4 * http://developer.berlios.de/projects/lunapaintami/ *
5 * Copyright (C) 2006, 2007, Hogne Titlestad <hogga@sub-ether.org> *
6 * Copyright (C) 2009-2011 LunaPaint Development Team *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the Free Software Foundation, *
20 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 * *
22 ****************************************************************************/
23 #include <SDI_hook.h>
24 #include "export_import.h"
26 Object *exportCycDT;
27 Object *exportBtnCancel;
28 Object *exportBtnExport;
29 Object *exportPopFilename;
30 Object *exportMode;
32 Object *exportAnimMethod;
33 Object *exportAnimMode;
34 Object *exportAnimRangeStart;
35 Object *exportAnimRangeEnd;
36 Object *exportAnimBtnExport;
37 Object *exportAnimBtnCancel;
39 Object *importCycDT;
40 Object *importBtnCancel;
41 Object *importBtnImport;
42 Object *importPopFilename;
44 Object *exportWindow;
45 Object *importWindow;
47 struct Hook export_hook;
48 struct Hook import_hook;
49 struct Hook exportanimation_hook;
51 static STRPTR exp_datatypes[] = { NULL, NULL, NULL, NULL, NULL };
52 static STRPTR exp_mode[] = { NULL, NULL, NULL };
53 static STRPTR exp_titles[] = { NULL, NULL, NULL };
54 static STRPTR exp_anim_mode[] = { NULL, NULL, NULL };
55 static STRPTR exp_anim_method[] = { NULL, NULL, NULL };
56 static STRPTR imp_datatypes[] = { NULL, NULL };
58 HOOKPROTONHNO(exportanimation_func, void, int *param)
61 int datatype = 0;
62 unsigned char *filename = NULL;
63 get ( exportCycDT, MUIA_Cycle_Active, &datatype );
64 get ( exportPopFilename, MUIA_String_Contents, &filename );
66 if ( filename == NULL )
67 return;
69 createImageFromAnimation ( globalActiveCanvas, datatype, filename );
75 HOOKPROTONHNO(export_func, void, int *param)
78 int mode = 0, datatype = 0;
79 unsigned char *filename = NULL;
80 get ( exportMode, MUIA_Cycle_Active, &mode );
81 get ( exportCycDT, MUIA_Cycle_Active, &datatype );
82 get ( exportPopFilename, MUIA_String_Contents, &filename );
84 if ( filename == NULL )
85 return;
87 unsigned int *buffer = generateExportableBuffer ( globalActiveCanvas, mode, datatype );
89 // Export with the JPEG datatype
90 if ( datatype == 0 )
92 exportDT ( globalActiveCanvas->width, globalActiveCanvas->height, buffer, filename, "jpeg" );
94 // Export with PNG code
95 else if ( datatype == 1 )
97 exportPNG ( globalActiveCanvas->width, globalActiveCanvas->height, buffer, filename );
99 // Save in RAW (64-bit) format
100 else if ( datatype == 2 )
102 /*BPTR myfile;
103 if ( ( myfile = Open ( filename, MODE_READWRITE ) ) != NULL )
105 Write ( myfile, globalActiveCanvas->activebuffer, sizeof ( unsigned long long int ) * ( globalActiveCanvas->width * globalActiveCanvas->height ) );
106 Close ( myfile );
108 else printf ( "Failed to save image raw..\n" );*/
109 printf ( "64-bit export temporarily disabled.\n" );
111 // Save another in raw format
112 else if ( datatype == 3 )
114 BPTR myfile;
115 if ( ( myfile = Open ( filename, MODE_NEWFILE ) ) != BNULL )
117 Write ( myfile, buffer, sizeof ( unsigned int ) * ( globalActiveCanvas->width * globalActiveCanvas->height ) );
118 Close ( myfile );
120 else printf ( "Failed to save image raw..\n" );
123 FreeVec ( buffer );
126 HOOKPROTONHNO(import_func, void, int *param)
129 int datatype = 0;
130 unsigned char *filename = NULL;
131 get ( importCycDT, MUIA_Cycle_Active, &datatype );
132 get ( importPopFilename, MUIA_String_Contents, &filename );
134 switch ( datatype )
136 case 0:
137 // We have a filename!!
138 if ( filename != NULL )
140 BPTR myfile;
141 if ( ( myfile = Open ( filename, MODE_OLDFILE ) ) != BNULL )
143 Read (
144 myfile, globalActiveCanvas->activebuffer,
145 8 * globalActiveCanvas->width * globalActiveCanvas->height
147 Close ( myfile );
148 globalActiveCanvas->winHasChanged = TRUE;
149 DoMethod ( globalActiveWindow->area, MUIM_Draw, FALSE );
150 set ( importWindow, MUIA_Window_Open, FALSE );
152 else printf ( "Failed to load image raw..\n" );
154 break;
155 default: break;
159 unsigned int *generateExportableBuffer ( struct oCanvas *canvas, int mode, int datatype )
161 unsigned int *buffer = NULL;
163 if ( mode == 0 )
165 if ( ( buffer = AllocVec ( 4 * canvas->width * canvas->height, MEMF_ANY|MEMF_CLEAR ) ) == NULL )
166 return 0;
168 int size = canvas->width * canvas->height;
169 int i = 0; for ( ; i < size; i++ )
171 struct rgba64 c64 = *( struct rgba64 *)&canvas->activebuffer[ i ];
173 // Align the colors reverse
174 c64 = ( struct rgba64 ){ c64.a, c64.b, c64.g, c64.r };
176 // Set the colors in 32-but order
177 // datatype 0 is JPEG
178 if ( datatype == 0 )
180 buffer[ i ] = *( unsigned int *)&( ( struct rgba32 ){
181 ( double )c64.a / 256, ( double )c64.r / 256,
182 ( double )c64.g / 256, ( double )c64.b / 256
183 } );
185 // If datatype is png, include all channels
186 else if ( datatype == 1 )
188 buffer[ i ] = *( unsigned int *)&( ( struct rgba32 ){
189 ( double )c64.r / 256, ( double )c64.g / 256,
190 ( double )c64.b / 256, ( double )c64.a / 256
191 } );
193 // Others
194 else
196 buffer[ i ] = *( unsigned int *)&( ( struct rgba32 ){
197 ( double )c64.b / 256, ( double )c64.g / 256,
198 ( double )c64.r / 256, ( double )c64.a / 256
199 } );
203 else if ( mode == 1 )
205 // Remove tool graphic that's overlayn
206 removePrevToolPreview ( );
207 ULONG tool = globalCurrentTool;
208 globalCurrentTool = -1;
210 // Get flattened layers without tool preview
211 buffer = renderCanvas ( canvas, 0, 0, canvas->width, canvas->height, TRUE );
213 // Reset tool setting
214 globalCurrentTool = tool;
216 // Fix color order for different storage formats
217 int size = canvas->width * canvas->height;
218 int i = 0; for ( ; i < size; i++ )
220 struct rgba32 c = *( struct rgba32 *)&buffer[ i ];
222 // Set the colors in 32-bit order
223 // datatype 0 is JPEG
224 if ( datatype == 0 )
225 c = ( struct rgba32 ){ c.a, c.r, c.g, c.b };
226 else if ( datatype == 1 )
227 c = ( struct rgba32 ){ c.r, c.g, c.b, c.a };
228 else
229 c = ( struct rgba32 ){ c.b, c.g, c.r, c.a };
231 buffer[ i ] = *( unsigned int *)&c;
234 return buffer;
237 void makeExportWindow ( )
239 exp_datatypes[0] = _(MSG_EXPORT_JPEG);
240 exp_datatypes[1] = _(MSG_EXPORT_PNG);
241 exp_datatypes[2] = _(MSG_EXPORT_RAW64);
242 exp_datatypes[3] = _(MSG_EXPORT_RAW32);
244 exp_mode[0] = _(MSG_EXPORT_ACTIV_LAYER);
245 exp_mode[1] = _(MSG_EXPORT_FLAT_LAYER);
247 exp_titles[0] = _(MSG_EXPORT_ONE_FRAME);
248 exp_titles[1] = _(MSG_EXPORT_FRAMES);
250 exp_anim_mode[0] = _(MSG_EXPORT_ACTIV_LAYER);
251 exp_anim_mode[1] = _(MSG_EXPORT_FLAT_LAYER);
253 exp_anim_method[0] = _(MSG_EXPORT_FILEPERFRAME);
254 exp_anim_method[1] = _(MSG_EXPORT_STRIP);
256 exportWindow = WindowObject,
257 MUIA_Window_ScreenTitle, __(MSG_EXPORT_SCR),
258 MUIA_Window_Title, __(MSG_EXPORT_WIN),
259 MUIA_Window_CloseGadget, TRUE,
260 MUIA_Window_Screen, ( IPTR )lunaPubScreen,
261 MUIA_Window_ID, MAKE_ID('L','P','W','E'),
262 WindowContents, VGroup,
263 Child, GroupObject,
264 MUIA_Frame, MUIV_Frame_Group,
265 Child, TextObject,
266 MUIA_Text_Contents, _(MSG_EXPORT_FILENAME),
267 End,
268 Child, HGroup,
269 Child, PopaslObject,
270 ASLFR_DoSaveMode, TRUE,
271 MUIA_Popstring_String, exportPopFilename = MUI_MakeObject (
272 MUIO_String, NULL, 200
274 MUIA_Popstring_Button, PopButton ( MUII_PopFile ),
275 MUIA_CycleChain, 1,
276 End,
277 End,
278 Child, VGroup,
279 Child, TextObject,
280 MUIA_Text_Contents, _(MSG_EXPORT_DT),
281 End,
282 Child, exportCycDT = CycleObject,
283 MUIA_Cycle_Entries, exp_datatypes,
284 MUIA_CycleChain, 1,
285 End,
286 End,
287 End,
288 Child, RegisterObject,
289 MUIA_Register_Titles, exp_titles,
290 MUIA_Register_Frame, MUIV_Frame_Group,
292 Image export
294 Child, GroupObject,
295 Child, GroupObject,
296 MUIA_Frame, MUIV_Frame_Group,
297 MUIA_CycleChain, 1,
298 Child, VGroup,
299 Child, exportMode = CycleObject,
300 MUIA_Cycle_Entries, exp_mode,
301 MUIA_CycleChain, 1,
302 End,
303 End,
304 Child, HGroup,
305 Child, exportBtnExport = SimpleButton ( __(MSG_EXPORT_EXPORT) ),
306 Child, exportBtnCancel = SimpleButton ( __(MSG_EXPORT_CANCEL) ),
307 End,
308 End,
309 End,
311 Animation export
313 Child, GroupObject,
314 Child, GroupObject,
315 MUIA_Frame, MUIV_Frame_Group,
316 MUIA_CycleChain, 1,
317 Child, VGroup,
318 Child, exportAnimMode = CycleObject,
319 MUIA_Cycle_Entries, exp_anim_mode,
320 MUIA_CycleChain, 1,
321 End,
322 Child, exportAnimMethod = CycleObject,
323 MUIA_Cycle_Entries, exp_anim_method,
324 MUIA_CycleChain, 1,
325 End,
326 End,
327 Child, VGroup,
328 Child, HGroup,
329 Child, TextObject,
330 MUIA_Text_Contents, __(MSG_EXPORT_FRAMERANGE),
331 End,
332 Child, exportAnimRangeStart = StringObject,
333 MUIA_String_Accept, ( IPTR )"0123456789",
334 MUIA_String_Format, MUIV_String_Format_Right,
335 MUIA_String_Integer, 1,
336 MUIA_String_MaxLen, 10,
337 MUIA_Frame, MUIV_Frame_String,
338 MUIA_CycleChain, 1,
339 End,
340 Child, TextObject,
341 MUIA_Text_Contents, " - ",
342 End,
343 Child, exportAnimRangeEnd = StringObject,
344 MUIA_String_Accept, ( IPTR )"0123456789",
345 MUIA_String_Format, MUIV_String_Format_Right,
346 MUIA_String_Integer, 1,
347 MUIA_String_MaxLen, 10,
348 MUIA_Frame, MUIV_Frame_String,
349 MUIA_CycleChain, 1,
350 End,
351 End,
352 Child, HGroup,
353 Child, exportAnimBtnExport = SimpleButton ( __(MSG_EXPORT_FRAMES) ),
354 Child, exportAnimBtnCancel = SimpleButton ( __(MSG_EXPORT_CANCEL) ),
355 End,
356 End,
357 End,
358 End,
359 End,
360 End,
361 End;
363 DoMethod (
364 exportWindow, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
365 ( IPTR )exportWindow, 2, MUIM_Set, MUIA_Window_Open
367 DoMethod (
368 exportBtnCancel, MUIM_Notify, MUIA_Pressed, FALSE,
369 ( IPTR )exportWindow, 2, MUIM_Set, MUIA_Window_Open
371 DoMethod (
372 exportAnimBtnCancel, MUIM_Notify, MUIA_Pressed, FALSE,
373 ( IPTR )exportWindow, 2, MUIM_Set, MUIA_Window_Open
376 // Setup hook
377 MakeStaticHook(export_hook, &export_func);
378 DoMethod (
379 exportBtnExport, MUIM_Notify, MUIA_Pressed, FALSE,
380 ( IPTR )exportWindow, 2, MUIM_CallHook, &export_hook
382 MakeStaticHook(exportanimation_hook, &exportanimation_func);
383 DoMethod (
384 exportAnimBtnExport, MUIM_Notify, MUIA_Pressed, FALSE,
385 ( IPTR )exportWindow, 2, MUIM_CallHook, &exportanimation_hook
389 void makeImportWindow ( )
391 imp_datatypes[0] = _(MSG_EXPORT_RAW64);
393 importWindow = WindowObject,
394 MUIA_Window_ScreenTitle, __(MSG_IMPORT_SCR),
395 MUIA_Window_Title, __(MSG_IMPORT_WIN),
396 MUIA_Window_CloseGadget, TRUE,
397 MUIA_Window_Screen, ( IPTR )lunaPubScreen,
398 MUIA_Window_ID, MAKE_ID('L','P','W','I'),
399 WindowContents, VGroup,
400 Child, GroupObject,
401 MUIA_Frame, MUIV_Frame_Group,
402 Child, VGroup,
403 Child, TextObject,
404 MUIA_Text_Contents, __(MSG_IMPORT_FILENAME),
405 End,
406 Child, HGroup,
407 Child, PopaslObject,
408 ASLFR_DoSaveMode, TRUE,
409 MUIA_Popstring_String, importPopFilename = MUI_MakeObject ( MUIO_String, NULL, 200 ),
410 MUIA_CycleChain, 1,
411 MUIA_Popstring_Button, PopButton ( MUII_PopFile ),
412 End,
413 End,
414 Child, TextObject,
415 MUIA_Text_Contents, __(MSG_IMPORT_ACTIV_LAYER),
416 End,
417 Child, TextObject,
418 MUIA_Text_Contents, __(MSG_IMPORT_DT),
419 End,
420 Child, importCycDT = CycleObject,
421 MUIA_Cycle_Entries, imp_datatypes,
422 MUIA_CycleChain, 1,
423 End,
424 End,
425 End,
426 Child, GroupObject,
427 MUIA_Frame, MUIV_Frame_Group,
428 Child, HGroup,
429 Child, importBtnImport = SimpleButton ( __(MSG_IMPORT_IMPORT) ),
430 Child, importBtnCancel = SimpleButton ( __(MSG_IMPORT_CANCEL) ),
431 End,
432 End,
433 End,
434 End;
436 DoMethod (
437 importWindow, MUIM_Notify, MUIA_Window_CloseRequest, TRUE,
438 ( IPTR )importWindow, 3, MUIM_Set, MUIA_Window_Open, FALSE
440 DoMethod (
441 importBtnCancel, MUIM_Notify, MUIA_Pressed, FALSE,
442 ( IPTR )importWindow, 3, MUIM_Set, MUIA_Window_Open, FALSE
445 // Setup hook
446 MakeStaticHook(import_hook, &import_func);
447 DoMethod (
448 importBtnImport, MUIM_Notify, MUIA_Pressed, FALSE,
449 ( IPTR )importWindow, 3, MUIM_CallHook, &import_hook
453 void createImageFromAnimation ( struct oCanvas *canv, int datatype, char *filename )
455 // Get some rules
456 int AnimMode = 0, AnimMethod = 0, FrameStart = 0, FrameEnd = 0;
457 get ( exportAnimMode, MUIA_Cycle_Active, &AnimMode );
458 get ( exportAnimMethod, MUIA_Cycle_Active, &AnimMethod );
459 get ( exportAnimRangeStart, MUIA_String_Integer, &FrameStart );
460 get ( exportAnimRangeEnd, MUIA_String_Integer, &FrameEnd );
462 // Restrict the export frame range
463 if ( FrameStart < 1 ) FrameStart = 1;
464 if ( FrameEnd < 1 ) FrameEnd = 1;
465 if ( FrameStart > FrameEnd )
467 int tmp = FrameStart;
468 FrameStart = FrameEnd;
469 FrameEnd = tmp;
471 if ( FrameEnd > canv->totalFrames )
472 FrameEnd = canv->totalFrames;
474 // One vertical strip
475 if ( AnimMethod == 1 )
477 // Make room for buffer
478 int framecount = 1 + FrameEnd - FrameStart;
479 int framesize = canv->width * canv->height * 4;
480 int framelength = canv->width * canv->height;
481 int bufsize = framesize * framecount;
482 int tmpFrame = canv->currentFrame;
483 int offset = 0;
485 unsigned int *animBuf = NULL;
486 // not enough mem?
487 if ( ( animBuf = AllocVec ( bufsize, MEMF_ANY|MEMF_CLEAR ) ) == NULL )
488 return;
490 int f = FrameStart; for ( ; f <= FrameEnd; f++ )
492 canv->currentFrame = f - 1;
493 setActiveBuffer ( canv );
495 unsigned int *buf = NULL;
496 if ( ( buf = generateExportableBuffer ( canv, AnimMode, datatype ) ) == 0 )
498 // not enough memory...
499 FreeVec ( animBuf );
500 return;
503 // Copy pixels from buf to animbuf
504 int i = 0; for ( ; i < framelength; i++ )
506 animBuf[ offset + i ] = buf[ i ];
508 FreeVec ( buf );
510 offset += framelength;
513 // Export with the JPEG datatype
514 if ( datatype == 0 )
516 exportDT (
517 canv->width,
518 canv->height * framecount, animBuf, filename, "jpeg"
521 // Export with png export code
522 else if ( datatype == 1 )
524 exportPNG ( canv->width, canv->height * framecount, animBuf, filename );
526 // Save in RAW (64-bit) format
527 else if ( datatype == 2 )
529 // NOT YET IMPLEMENTED!
530 printf ( "64-bit animation export is not yet implemented!\n" );
532 // Save another in raw format
533 else if ( datatype == 3 )
535 BPTR myfile;
536 if ( ( myfile = Open ( filename, MODE_NEWFILE ) ) != BNULL )
538 Write ( myfile, animBuf, bufsize );
539 Close ( myfile );
541 else printf ( "Failed to save image raw..\n" );
544 // Free memory
545 FreeVec ( animBuf );
547 // Reset the currentframe to where it was
548 canv->currentFrame = tmpFrame;
549 setActiveBuffer ( canv );
551 // One image pr frame
552 else
554 // Make room for buffer
555 int framesize = canv->width * canv->height * 4;
556 int tmpFrame = canv->currentFrame;
558 unsigned int *buf = NULL;
560 int f = FrameStart;
562 for ( ; f <= FrameEnd; f++ )
564 char *tmpFilename = AllocVec ( 255, MEMF_ANY|MEMF_CLEAR );
565 sprintf ( tmpFilename, "%s%04d", filename, ( f - FrameStart + 1 ) );
567 canv->currentFrame = f - 1;
568 setActiveBuffer ( canv );
570 buf = generateExportableBuffer ( canv, AnimMode, datatype );
572 // Export with the JPEG datatype
573 if ( datatype == 0 )
575 exportDT ( canv->width, canv->height, buf, tmpFilename, "jpeg" );
577 else if ( datatype == 1 )
579 exportPNG ( canv->width, canv->height, buf, tmpFilename );
581 // Save in RAW (64-bit) format
582 else if ( datatype == 2 )
584 // NOT YET IMPLEMENTED!
585 printf ( "64-bit animation export is not yet implemented!\n" );
587 // Save another in raw format
588 else if ( datatype == 3 )
590 BPTR myfile;
591 if ( ( myfile = Open ( tmpFilename, MODE_NEWFILE ) ) != BNULL )
593 Write ( myfile, buf, framesize );
594 Close ( myfile );
596 else printf ( "Failed to save image raw..\n" );
599 FreeVec ( tmpFilename );
600 FreeVec ( buf );
603 // Reset the currentframe to where it was
604 canv->currentFrame = tmpFrame;
605 setActiveBuffer ( canv );
609 void exportDT ( int w, int h, unsigned int *buffer, unsigned char *filename, const char *format )
611 if ( filename != NULL )
613 // Generate a datatype object
614 Object *DTImage = NewDTObject (
615 ( APTR )NULL,
616 DTA_SourceType, DTST_RAM,
617 DTA_BaseName, ( IPTR )format,
618 PDTA_DestMode, PMODE_V43,
619 TAG_DONE
621 // Return if this doesn't work
622 if ( !DTImage )
623 return;
625 // Make a header
626 struct BitMapHeader *bmhdr;
627 if ( !( GetDTAttrs ( DTImage, PDTA_BitMapHeader, ( IPTR )&bmhdr, TAG_DONE ) ) )
628 return;
630 // Write the data in memory
631 struct pdtBlitPixelArray dtObj;
633 dtObj.MethodID = PDTM_WRITEPIXELARRAY;
634 dtObj.pbpa_PixelFormat = PBPAFMT_ARGB;
635 dtObj.pbpa_PixelArrayMod = w;
636 dtObj.pbpa_Left = 0;
637 dtObj.pbpa_Width = w;
638 dtObj.pbpa_Height = 1;
640 bmhdr->bmh_Width = w;
641 bmhdr->bmh_Height = h;
642 bmhdr->bmh_Depth = 24;
643 bmhdr->bmh_PageWidth = 320;
644 bmhdr->bmh_PageHeight = 240;
646 int y = 0; for ( ; y < h; y++ )
648 dtObj.pbpa_Top = y;
649 dtObj.pbpa_PixelData = ( APTR )( buffer + ( y * w ) );
650 DoMethodA ( DTImage, ( Msg )&dtObj );
653 // Write the data to disk
654 BPTR filehandle;
655 if ( ( filehandle = Open ( filename, MODE_NEWFILE ) ) )
657 struct dtWrite dtwObj;
658 dtwObj.MethodID = DTM_WRITE;
659 dtwObj.dtw_GInfo = NULL;
660 dtwObj.dtw_FileHandle = filehandle;
661 dtwObj.dtw_Mode = DTWM_RAW;
662 dtwObj.dtw_AttrList = NULL;
663 DoMethodA ( DTImage, ( Msg )&dtwObj );
664 Close ( filehandle );
667 // Clean up
668 DisposeDTObject ( DTImage );
672 static void png_user_write( png_structp png_ptr, png_bytep data, png_size_t length )
674 Write ( png_get_io_ptr(png_ptr), data, length );
676 static void png_user_flush( png_structp png_ptr )
678 // do nothing - nothing to flush!
680 void exportPNG ( int w, int h, unsigned int *buffer, unsigned char *filename )
682 png_structp png_ptr;
683 png_infop info_ptr;
684 BPTR file;
685 int i;
687 // Create a write struct.
688 if ( !(png_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL ) ) )
689 return;
691 // Create an info struct.
692 if ( !( info_ptr = png_create_info_struct( png_ptr ) ) )
694 // Free the unused write struct.
695 png_destroy_write_struct ( &png_ptr, ( png_infopp )NULL );
696 return;
699 // Open file for writing
700 if ( ( file = Open ( filename, MODE_NEWFILE ) ) == BNULL )
701 return;
703 // Register the write function.
704 png_set_write_fn ( png_ptr, (APTR) file, png_user_write, png_user_flush );
706 // Create the info header.
707 png_set_IHDR (
708 png_ptr, info_ptr, w, h, 8,
709 PNG_COLOR_TYPE_RGBA,
710 PNG_INTERLACE_NONE,
711 PNG_COMPRESSION_TYPE_DEFAULT,
712 PNG_FILTER_TYPE_DEFAULT
715 // Write the info header.
716 png_write_info ( png_ptr, info_ptr );
718 // Write image rows
719 for ( i = 0; i < h ; i++ )
720 png_write_row( png_ptr, ( png_bytep )&buffer[ i * w ] );
722 // Write file end and clean up
723 png_write_end( png_ptr, info_ptr );
724 png_destroy_write_struct( &png_ptr, &info_ptr );
726 // Close file and done!
727 Close ( file );