/* GEM-View 3.00 SAVING Modul: Bild als IFF-Bild speichern (c) 22.10.1993 by Dieter Fiebelkorn Grner Weg 29a D-45768 Marl (GERMANY) */ #include #include "image.h" #include "moduls.h" #include "iff.h" #define Write(a,b,c,d) write(d,c,a) #define TRUE 1 #define FALSE 0 void Save_iff (SAVE_Structure *saveS, unsigned int verbose) { Image *image; char *filename; unsigned int windepth; int fd; char *data, out, mask, set; long col, line, plane, RealLine, i; unsigned char *raster[24]; IFF_HEADER iff_header; CHUNK_HEADER chunk_header; BITMAP_HEADER bitmap_header; long width, height, num_colors; short planes; image = saveS->image; filename = saveS->out_filename; windepth = saveS->screen_depth; width = image->width; height = image->height; planes = image->depth; num_colors = (image->rgb.used < (1UL << planes)) ? image->rgb.used : (1UL << planes); *(long*)&iff_header.form_id = 'FORM'; iff_header.lenght = 2 * sizeof(CHUNK_HEADER) + sizeof(BITMAP_HEADER) + width * height * planes / 8L + 4L; if (num_colors) iff_header.lenght += sizeof(CHUNK_HEADER) + num_colors * 3L; *(long*)&iff_header.file_id = 'ILBM'; bitmap_header.width = image->unalignwidth ? image->unalignwidth : image->width; bitmap_header.height = (unsigned int) height; bitmap_header.off_x = 0; bitmap_header.off_y = 0; bitmap_header.planes = planes; bitmap_header.mask = 0; bitmap_header.compressed = 0; bitmap_header.unused = 0; bitmap_header.transparent_color = 0; bitmap_header.x_aspect = 0; bitmap_header.y_aspect = 0; bitmap_header.page_width = bitmap_header.width; bitmap_header.page_height = (unsigned int)height; saveS->print.printout (" Saving IFF Imagefile '%s' ... ", filename); if ((fd = saveS->output.open(filename)) > 0) { if (saveS->output.Write(&iff_header, 1L, sizeof(iff_header), fd) != sizeof(iff_header)) goto CloseAndRemove; *(long*)&chunk_header.chunk_id = 'BMHD'; chunk_header.lenght = sizeof(bitmap_header); if (saveS->output.Write(&chunk_header, 1L, sizeof(chunk_header), fd) != sizeof(chunk_header)) goto CloseAndRemove; if (saveS->output.Write(&bitmap_header, 1L, sizeof(bitmap_header), fd) != sizeof(bitmap_header)) goto CloseAndRemove; if (num_colors) { *(long*)&chunk_header.chunk_id = 'CMAP'; chunk_header.lenght = num_colors * 3L; if (saveS->output.Write(&chunk_header, 1L, sizeof(chunk_header), fd) != sizeof(chunk_header)) goto CloseAndRemove; for (col = 0; col < num_colors; col++) { out = (char)(image->rgb.red[col] >> 8); if (saveS->output.Write(&out, 1L, 1L, fd) != 1L) goto CloseAndRemove; out = (char)(image->rgb.green[col] >> 8); if (saveS->output.Write(&out, 1L, 1L, fd) != 1L) goto CloseAndRemove; out = (char)(image->rgb.blue[col] >> 8); if (saveS->output.Write(&out, 1L, 1L, fd) != 1L) goto CloseAndRemove; } } *(long*)&chunk_header.chunk_id = 'BODY'; chunk_header.lenght = width * height * planes / 8L; if (saveS->output.Write(&chunk_header, 1L, sizeof(chunk_header), fd) != sizeof(chunk_header)) goto CloseAndRemove; if (MONOCHROMEP(image)) { RealLine = (image->width >> 4) + ((image->width & 0x000F) ? 1 : 0); RealLine += RealLine; for (line = 0; line < height; line++) { raster[0] = image->data + ((long)line * RealLine); if (saveS->output.Write(raster[0], 1L, RealLine, fd) != RealLine) goto CloseAndRemove; } } if (ATARI_RGBP(image)) { RealLine = (image->width >> 4) + ((image->width & 0x000F) ? 1 : 0); RealLine += RealLine; for (line = 0; line < height; line++) { raster[0] = image->data + ((long)line * RealLine); for (plane = 1; plane < planes; plane++) raster[plane] = raster[plane-1] + (long)RealLine * height; for (plane = 0; plane < planes; plane++) if (saveS->output.Write(raster[plane], 1L, RealLine, fd) != RealLine) goto CloseAndRemove; } } #if 1 if (RGBP(image)) { RealLine = (image->width >> 4) + ((image->width & 0x000F) ? 1 : 0); RealLine <<= 4; for (line = 0; line < image->height; line++) { data = image->data + ((long)line * RealLine); for (plane = 0; plane < planes; plane++) { mask = 1U << plane; out = 0; set = 0x80; for (i = 0; i < RealLine; i++) { if (data[i] & mask) out |= set; if ((set >>= 1) == 0) { if (saveS->output.Write(&out, 1L, 1L, fd) != 1L) goto CloseAndRemove; out = 0; set = 0x80; } } } } } #endif #if 1 if (TRUECOLORP(image)) { saveS->error.printerr("not supported TrueColor IFF imagefiles.\n"); saveS->output.close (fd); return; } #endif if (saveS->output.close(fd) != 0) { fd = 0; goto CloseAndRemove; } saveS->print.printout ("done.\n"); return; } CloseAndRemove: saveS->events.alert(1, "[3][ | Error in writing! | | Disk full ? ][ OK ]"); if (fd > 0) saveS->output.close(fd); saveS->output.delete(filename); saveS->print.printout ("error.\n"); return; }