tim@hoptoad.uucp (Tim Maroney) (04/09/90)
In article <2105@mit-amt.MEDIA.MIT.EDU> jow@mit-amt.MEDIA.MIT.EDU (Joel Wachman) writes: >Hi, can someone please help me out? I am trying to write a program >that converts a bitmap stored as ASCII data (actually, an X11 icon) >into a PICT. I figured I could do this by putting the bitmap data >into a BitMap structure, then doing an OpenPicture(),CopyBits(), >ClosePicture(), but instead of seeing my bitmap, I see garbage. >Furthermore, the garbage is different every time I run the program. > >It might just be that somewhere else, my code is broken, but I have >checked the BitMap just before the CopyBits() and the baseAddr, rowBytes and >bounds fields are all correct. The data pointed to by baseAddr is >also correct. Seems like that's a little difficult to check other than by drawing the thing. I recommend doing so in a test version. > (SETRECT() is a macro to set the fields of a Rect) Why? The overhead of calling the trap is trivial unless you're doing it many, many, many times inside a loop. > unsigned char *imagedata,*GetImageData(); > short xsize,ysize; > Window newwindow; > Rect pictureRect; > PicHandle picture; > BitMap bitMap; > > window = GetNewWindow(PICT_WINDOW_ID,nil,(WindowPtr)-1); It would be better if you would give us your actual code rather than fixing it up, as the use of "window" rather than "newwindow" here shows. You may be hiding the bug in the process of editing. > imagedata = GetImageData(iconFile,&xsize,&ysize); For obvious reasons (namely, that I can't see it), I'm suspicious of the GetImageData call! Draw what it returns to make sure it's OK. > SETRECT(&pictureRect,0,0,xsize,ysize); > SETRECT(&bitMap.bounds,0,0,xsize,ysize); > bitMap.baseAddr = imagedata; > /* make sure rowBytes is even */ > bitMap.rowBytes = (xsize & 1 ? xsize - 1 : xsize); I think this could be a big part of the problem. First of all, you're using xsize as a pixel measurement in the SetRect calls, but here, you're using it as a byte measurement. There's a factor of eight difference between the two. Furthermore, you're trimming rowBytes when you should be growing it. This strategy would lead to losing your last byte from each row, which would cause a sort of progressive horizontal drift in the bitmap. The statement should read something like: bitMap.rowBytes = ((xsize / 8) & 1 ? (xsize / 8) + 1 : (xsize / 8)); Not sure that's exactly correct, but it should be closer to it. You may also have to wind up doing some sort of data conversion on the bitmap data, if the X11 bitmap data doesn't live up to the Mac's somewhat restrictive requirements. That is, it may be leaving off the padding from the end of each row, so that you need to do a row-by-row copy of the X11 bitmap into the Mac bitmap. > /* draw the bitmap into the window while the picture recorder is on */ > picture = OpenPicture(&pictureRect); OK, but first, do a ClipRect to the picture rectangle. > CopyBits(&bitMap,(BitMap *)(&(newwindow->portBits)), Why the conversion? It is redundant and misleading. > &pictureRect,&pictureRect,0,NULL); The CopyBits looks OK, so your bitmap must be set up wrong. > ClosePicture(); > DrawPicture(picture,&pictureRect); Looks OK. Again, try drawing your bitmap correctly first, without drawing it into a picture. If you can do that, then the rest of this should work (provided you put in the ClipRect). I use fairly similar code to turn bitmaps into PICTs myself. Interestingly, a PICT of a bitmap of any significant size is often smaller than the bitmap; it appears that the QD picture code compresses saved bitmaps using the usual MacPaintish PackBits and UnpackBits calls. -- Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com "The Diabolonian position is new to the London playgoer of today, but not to lovers of serious literature. From Prometheus to the Wagnerian Siegfried, some enemy of the gods, unterrified champion of those oppressed by them, has always towered among the heroes of the loftiest poetry." - Shaw, "On Diabolonian Ethics"