FUNC_HOOK(ULONG, readclut, struct Hook *, hook, APTR, buffer, struct RND_LineMessage *, msg) { struct readclutdata *data = hook->h_Data; if (msg->RND_LMsg_type == LMSGTYPE_LINE_FETCH) { if (data->lastline != msg->RND_LMsg_row) { data->lastline = msg->RND_LMsg_row; ReadPixelLine8(data->rp, data->sourcex, data->sourcey + msg->RND_LMsg_row, data->sourcewidth, buffer, data->temprp); } } return TRUE; }
FUNC_HOOK(ULONG, readham, struct Hook *, hook, APTR, buffer, struct RND_LineMessage *, msg) { struct readhamdata *data = hook->h_Data; if (msg->RND_LMsg_type == LMSGTYPE_LINE_FETCH) { if (data->lastline != msg->RND_LMsg_row) { data->lastline = msg->RND_LMsg_row; ReadPixelLine8(data->rp, 0, data->sourcey + msg->RND_LMsg_row, data->sourcewidth+data->sourcex, data->linebuffer, data->temprp); Chunky2RGB(data->linebuffer, data->sourcewidth, 1, buffer, data->palette, RND_ColorMode, data->colormode, RND_LeftEdge, data->sourcex, TAG_DONE); } } return TRUE; }
/************* * DESCRIPTION: Loads a image with the datatypes. * INPUT: filename name of picture to load * OUTPUT: FALSE if failed *************/ BOOL IMAGE::LoadAsDatatype(char *filename) { struct Library *PictureDTBase; BOOL pic24bit; // TRUE for new 24bit picture.datatype (V43) Object *obj; struct BitMapHeader *bmhd; struct BitMap *bitmap, *tempbitmap; int x,y; SMALL_COLOR *c; UBYTE *colreg, *buffer; int color; ULONG modeid; struct DisplayInfo dispinfo; UBYTE r,g,b; struct RastPort rp, temprp; struct gpBlitPixelArray arg; DataTypesBase = OpenLibrary((unsigned char*)"datatypes.library", 39); if(!DataTypesBase) return FALSE; // try to open the 24bit picture datatype PictureDTBase = OpenLibrary("datatypes/picture.datatype", 43L); if(PictureDTBase) { // we only need the picture.datatype to test the version, therefore // close it now CloseLibrary(PictureDTBase); pic24bit = TRUE; } else pic24bit = FALSE; if(!pic24bit) { // no 24bit version available // get the picture object obj = NewDTObject(filename, DTA_SourceType, DTST_FILE, DTA_GroupID, GID_PICTURE, PDTA_Remap, FALSE, TAG_DONE); if(!obj) { CloseLibrary(DataTypesBase); return FALSE; } } else { // get the picture object obj = NewDTObject(filename, DTA_SourceType, DTST_FILE, DTA_GroupID, GID_PICTURE, PDTA_Remap, FALSE, PDTA_DestMode, MODE_V43, TAG_DONE); if(!obj) { CloseLibrary(DataTypesBase); return FALSE; } } // get the bitmap header if(GetDTAttrs(obj, PDTA_ColorRegisters, &colreg, PDTA_BitMap, &bitmap, PDTA_ModeID, &modeid, PDTA_BitMapHeader, &bmhd, TAG_DONE) != 4) { DisposeDTObject(obj); CloseLibrary(DataTypesBase); return FALSE; } if(!bmhd || !bitmap) { DisposeDTObject(obj); CloseLibrary(DataTypesBase); return FALSE; } width = bmhd->bmh_Width; height = bmhd->bmh_Height; if(!GetDisplayInfoData(NULL, (UBYTE*)&dispinfo, sizeof(struct DisplayInfo), DTAG_DISP, modeid)) { DisposeDTObject(obj); CloseLibrary(DataTypesBase); return FALSE; } colormap = (SMALL_COLOR*)malloc(sizeof(SMALL_COLOR)*width*height); if(!colormap) { DisposeDTObject(obj); CloseLibrary(DataTypesBase); return FALSE; } c = colormap; if((bmhd->bmh_Depth > 8) && pic24bit) { // true color picture buffer = (UBYTE*)AllocVec(3*width, MEMF_PUBLIC); if(!buffer) { DisposeDTObject(obj); CloseLibrary(DataTypesBase); return FALSE; } for(y=0; y<height; y++) { arg.MethodID = DTM_READPIXELARRAY; arg.PixelArray = buffer; arg.PixelArrayMode = RECTFMT_RGB; arg.PixelArrayMod = 3*width; arg.LeftEdge = 0; arg.TopEdge = y; arg.Width = width; arg.Height = 1; #ifdef __PPC__ ppc_DoMethodA(obj, (Msg)&arg); #else DoMethodA(obj, (Msg)&arg); #endif for(x=0; x<width; x++) { c->r = buffer[x*3]; c->g = buffer[x*3+1]; c->b = buffer[x*3+2]; c++; } } FreeVec(buffer); } else { // normal picture // planar to chunky conversion InitRastPort(&rp); rp.BitMap = bitmap; tempbitmap = AllocBitMap(width, 1, bmhd->bmh_Depth, BMF_CLEAR, NULL); if(!tempbitmap) { DisposeDTObject(obj); CloseLibrary(DataTypesBase); return FALSE; } InitRastPort(&temprp); temprp.BitMap = tempbitmap; buffer = (UBYTE*)AllocVec((width+15)&(~15), MEMF_PUBLIC); if(!buffer) { FreeBitMap(tempbitmap); DisposeDTObject(obj); CloseLibrary(DataTypesBase); return FALSE; } if(dispinfo.PropertyFlags & DIPF_IS_HAM) { // Simulate HAM mode if(bmhd->bmh_Depth == 8) { // Super HAM for(y=0; y<height; y++) { r = g = b = 0; ReadPixelLine8(&rp, 0, y, width, buffer, &temprp); for(x=0; x<width; x++) { color = buffer[x]; switch(color & 0xc0) { case 0x00: // Take it from color registers color *= 3; r = colreg[color]; g = colreg[color+1]; b = colreg[color+2]; break; case 0x40: // modify blue b = color << 2; break; case 0x80: // modify red r = color << 2; break; case 0xc0: // modify green g = color << 2; break; } c->r = r; c->g = g; c->b = b; c++; } } } else { // Normal HAM for(y=0; y<height; y++) { r = g = b = 0; ReadPixelLine8(&rp, 0, y, width, buffer, &temprp); for(x=0; x<width; x++) { color = buffer[x]; switch(color & 0x30) { case 0x00: // Take it from color registers color *= 3; r = colreg[color]; g = colreg[color+1]; b = colreg[color+2]; break; case 0x40: // modify blue b = color << 4; break; case 0x80: // modify red r = color << 4; break; case 0xc0: // modify green g = color << 4; break; } c->r = r; c->g = g; c->b = b; c++; } } } } else { for(y=0; y<height; y++) { ReadPixelLine8(&rp, 0, y, width, buffer, &temprp); for(x=0; x<width; x++) { color = buffer[x]; color *= 3; c->r = colreg[color]; c->g = colreg[color+1]; c->b = colreg[color+2]; c++; } } } FreeVec(buffer); FreeBitMap(tempbitmap); } DisposeDTObject(obj); CloseLibrary(DataTypesBase); return TRUE; }
APTR ReadBitMapA(struct BitMap *bm, UWORD displayID, PALETTE palette, int *ptr_pixelformat, int *ptr_width, int *ptr_height, TAGLIST tags) { APTR array = NULL; if (bm) { BOOL success; int sourcex, sourcey, sourcewidth, sourceheight, destwidth, destheight; int width, height, flags, depth, iscyber, bmapformat, pixelformat; int bufsize; APTR scaleengine = NULL; struct RastPort rp, temprp; sourcex = GetTagData(GGFX_SourceX, 0, tags); sourcey = GetTagData(GGFX_SourceY, 0, tags); GetBitMapInfo(bm, displayID, BMAPATTR_Width, &width, BMAPATTR_Height, &height, BMAPATTR_Depth, &depth, BMAPATTR_Flags, &flags, BMAPATTR_CyberGFX, &iscyber, BMAPATTR_BitMapFormat, &bmapformat, BMAPATTR_PixelFormat, &pixelformat, TAG_DONE); sourcewidth = GetTagData(GGFX_SourceWidth, width, tags); sourceheight = GetTagData(GGFX_SourceHeight, height, tags); destwidth = GetTagData(GGFX_DestWidth, width, tags); destheight = GetTagData(GGFX_DestHeight, height, tags); success = TRUE; // insert bitmap into rastport, create temp rastport InitRastPort(&rp); rp.BitMap = bm; TurboCopyMem(&rp, &temprp, sizeof(struct RastPort)); temprp.Layer = NULL; if (!(temprp.BitMap = AllocBitMap(width, 1, depth, flags, bm))) { success = FALSE; } // create scale engine if (success) { if (sourcewidth != destwidth || sourceheight != destheight) { if (!(scaleengine = CreateScaleEngine( sourcewidth, sourceheight, destwidth, destheight, RND_RMHandler, MemHandler, RND_PixelFormat, pixelformat, TAG_DONE))) { success = FALSE; } } } // get buffer if (success) { if (pixelformat == PIXFMT_0RGB_32) { bufsize = destwidth * destheight * PIXELSIZE(pixelformat); } else { bufsize = ((destwidth+15) & ~15) * destheight; } DB(kprintf("!readbitmap alloc\n")); if (!(array = AllocRenderVec(MemHandler, bufsize))) { success = FALSE; } } // convert data if (success) { success = FALSE; if (scaleengine) { // with scaling switch (bmapformat) { case PIXFMT_BITMAP_RGB: { ULONG *linebuffer; DB(kprintf("~reading/scaling RGB bitmap\n")); if (linebuffer = AllocRenderVec(MemHandler, sourcewidth * 4)) { struct Hook readhook; struct readrgbdata hookdata; hookdata.rp = &rp; hookdata.sourcex = sourcex; hookdata.sourcey = sourcey; hookdata.sourcewidth = sourcewidth; hookdata.lastline = -1; readhook.h_Data = &hookdata; readhook.h_Entry = HOOKENTRY(readrgb); Scale(scaleengine, linebuffer, array, RND_SourceWidth, 0, RND_LineHook, &readhook, TAG_DONE); FreeRenderVec(linebuffer); success = TRUE; } break; } case PIXFMT_BITMAP_CLUT: { UBYTE *linebuffer; DB(kprintf("~reading/scaling CLUT bitmap\n")); if (linebuffer = AllocRenderVec(MemHandler, ((sourcewidth+15) & ~15))) { struct Hook readhook; struct readclutdata hookdata; hookdata.rp = &rp; hookdata.temprp = &temprp; hookdata.sourcex = sourcex; hookdata.sourcey = sourcey; hookdata.sourcewidth = sourcewidth; hookdata.lastline = -1; readhook.h_Data = &hookdata; readhook.h_Entry = HOOKENTRY(readclut); Scale(scaleengine, linebuffer, array, RND_SourceWidth, 0, RND_LineHook, &readhook, TAG_DONE); FreeRenderVec(linebuffer); success = TRUE; } break; } case PIXFMT_BITMAP_HAM6: case PIXFMT_BITMAP_HAM8: { UBYTE *linebuffer; ULONG *rgbbuffer; DB(kprintf("~reading/scaling HAM bitmap\n")); if (linebuffer = AllocRenderVec(MemHandler, ((sourcewidth + sourcex + 15) & ~15))) { if (rgbbuffer = AllocRenderVec(MemHandler, sourcewidth * 4)) { struct Hook readhook; struct readhamdata hookdata; hookdata.rp = &rp; hookdata.temprp = &temprp; hookdata.sourcex = sourcex; hookdata.sourcey = sourcey; hookdata.sourcewidth = sourcewidth; hookdata.linebuffer = linebuffer; hookdata.palette = palette; hookdata.colormode = (depth == 8) ? COLORMODE_HAM8 : COLORMODE_HAM6; hookdata.lastline = -1; readhook.h_Data = &hookdata; readhook.h_Entry = HOOKENTRY(readham); Scale(scaleengine, rgbbuffer, array, RND_SourceWidth, 0, RND_LineHook, &readhook, TAG_DONE); FreeRenderVec(rgbbuffer); success = TRUE; } FreeRenderVec(linebuffer); } break; } } } else { // no scaling switch (bmapformat) { case PIXFMT_BITMAP_RGB: { DB(kprintf("~reading RGB bitmap\n")); ReadPixelArray(array, 0,0, destwidth * 4, &rp, sourcex, sourcey, destwidth, destheight, RECTFMT_ARGB); success = TRUE; break; } case PIXFMT_BITMAP_CLUT: { int i; char *p = array; DB(kprintf("~reading CLUT bitmap\n")); for(i = 0; i < destheight; ++i) { ReadPixelLine8(&rp, sourcex, sourcey + i, destwidth, p, &temprp); p += destwidth; } success = TRUE; break; } case PIXFMT_BITMAP_HAM6: case PIXFMT_BITMAP_HAM8: { UBYTE *linebuffer; DB(kprintf("~reading HAM bitmap\n")); if (linebuffer = AllocRenderVec(MemHandler, ((destwidth+15) & ~15) )) { int i; ULONG *p = array; for(i = 0; i < destheight; ++i) { ReadPixelLine8(&rp, sourcex, sourcey + i, destwidth, linebuffer, &temprp); Chunky2RGB(linebuffer, destwidth, 1, p, palette, RND_ColorMode, ((depth == 8) ? COLORMODE_HAM8 : COLORMODE_HAM6), TAG_DONE); p += destwidth; } FreeRenderVec(linebuffer); success = TRUE; } break; } } } } // close down if (success) { *ptr_pixelformat = pixelformat; *ptr_width = destwidth; *ptr_height = destheight; } else { if (array) { FreeRenderVec(array); array = NULL; } } if (scaleengine) { DeleteScaleEngine(scaleengine); } if (temprp.BitMap) { FreeBitMap(temprp.BitMap); } } return array; }