Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ImageGfx.c

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission :
00003         Realtime Vision Processing System
00004 
00005     Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008 
00009     This file is part of Phission.
00010 
00011     Phission is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU Lesser General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     Phission is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU Lesser General Public License for more details.
00020 
00021     You should have received a copy of the GNU Lesser General Public License
00022     along with Phission; if not, write to the Free Software
00023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025  ---------------------------------------------------------------------------*/
00026 #ifdef HAVE_CONFIG_H
00027     #include <phissionconfig.h>
00028 #endif
00029 
00030 #include <phStandard.h>
00031 #include <phPrint.h>
00032 #include <phError.h>
00033 #include <ImageGfx.h>
00034 #include <phMemory.h>
00035 
00036 #ifdef __cplusplus
00037 extern "C" 
00038 {
00039 #endif
00040 /* ------------------------------------------------------------------------ */
00041 /* http://www.wol.net.pk/mtshome/cppComputerGraphics.html#Circle */
00042 /* ------------------------------------------------------------------------ */
00043 /*
00044  * PHAPI(int)      ph_set_pixel        ( phPoint       p,  phColor color );
00045  * PHAPI(phColor)  ph_get_pixel        ( phPoint       p );
00046  */
00047 /* ------------------------------------------------------------------------ */
00048 #define ph_put_pixel(s,x,y,w,d,c) \
00049     phMemcpy((void *)&(s[(((y * w) + x) * d)]),c,d);
00050 /*    if (d == 4) \
00051         (*(phPixel32 *)(&s[(((y * w) + x) * d)])) = *(phPixel32 *)c; \
00052     else if (d == 3) \
00053         (*(phPixel24 *)(&s[(((y * w) + x) * d)])) = *(phPixel24 *)c;
00054 */        
00055 
00056 /* ------------------------------------------------------------------------ */
00057 inline void ph_set_pixel( uint8_t  *s, 
00058                           int32_t   x, 
00059                           int32_t   y,
00060                           uint32_t  w,
00061                           uint32_t  h,
00062                           uint8_t   d,
00063                           uint8_t  *c)
00064 {
00065     if ((x >= 0) && (x < w) && (y >= 0) && (y < h)) ph_put_pixel(s,x,y,w,d,c)
00066 }       
00067 
00068 /* ------------------------------------------------------------------------ */
00069 /* this is an ineffcient function to call repeatedly */
00070 inline void ph_set_transparent_pixel( uint8_t   trans,
00071                                       uint8_t  *s, 
00072                                       int32_t   x, 
00073                                       int32_t   y,
00074                                       uint32_t  w,
00075                                       uint32_t  h,
00076                                       uint8_t   d,
00077                                       uint8_t  *c )
00078 {
00079     if ((x >= 0) && (x < w) && (y >= 0) && (y < h)) 
00080     {
00081         const float alpha     = (trans == 0) ? 0 : ((float)trans) / 100.0;
00082         const float alphainv  = 1.0 - alpha;
00083         
00084         uint32_t    i                       = 0;
00085         float       temp                    = 0.0;
00086         uint8_t     pixel[phCOLOR_MAXBYTES] = { 0 };
00087         uint8_t    *ptr = &(s[((y * w) + x) * d]);
00088 
00089         for ( i = 0; i < d; i++ )
00090         {
00091             temp = (alphainv * c[i]) + (alpha * ptr[i]);
00092             if (temp < 0) temp = 0;
00093             pixel[i] = (uint8_t)(temp > 255 ? 255 : temp);
00094         }
00095 
00096         phMemcpy(ptr,pixel,d);
00097     }
00098 }       
00099 
00100 /* ------------------------------------------------------------------------ */
00101 /* phMemcpy(&(s[(((y * w) + x) * d)]),c,d); \ */
00102 /* ------------------------------------------------------------------------ */
00103 #define ph_draw_check_coords(x,y,w,h) ((x > 0) && (y > 0) && (x < w) && (y < h))
00104 #define ph_draw_check_format(f,c) \
00105     ((f & phImagePackedFormatMask) && \
00106      ((c.type == phColorTypeArray) || \
00107       (phColorToFormat(c) == f)))
00108 
00109 /* ------------------------------------------------------------------------ */
00110 void ph_draw_horizline( phImageSurface *s,
00111                         phColor         c,
00112                         uint8_t         transp,
00113                         int32_t         x1, 
00114                         int32_t         x2,
00115                         int32_t         y )
00116 {
00117     uint8_t *color  = c.array.v;
00118     if (x1 < 0)     x1 = 0;
00119     if (x2 < 0)     x2 = 0;
00120     if (x1 >= s->w) x1 = s->w - 1;
00121     if (x2 >= s->w) x2 = s->w - 1;
00122     if (y < 0)      y = 0;
00123     if (y >= s->h)  y = s->h - 1;
00124     
00125     if (x1 == x2)
00126         ph_set_pixel(s->p,x1,y,s->w,s->h,s->d,color);
00127     else
00128     {   
00129         if (transp == 0)
00130         {
00131             uint8_t *p = &(s->p[(((y * s->w) + x1) * s->d)]);
00132 
00133             for ( ; x1 < x2; x1++ )
00134             {
00135                 phMemcpy(p,color,s->d);
00136                 p += s->d;
00137             }
00138         }
00139         else if (transp < 100)
00140         {
00141             const float alpha     = (transp == 0) ? 0 : ((float)transp) / 100.0;
00142             const float alphainv  = 1.0 - alpha;
00143 
00144             uint32_t i                       = 0;
00145             float    temp                    = 0.0;
00146             uint8_t  pixel[phCOLOR_MAXBYTES] = { 0 };
00147             
00148             uint8_t       *p = &(s->p[(((y * s->w) + x1) * s->d)]);
00149             const uint8_t *col       = c.array.v;
00150 
00151             for ( ; x1 < x2; x1++ )
00152             {
00153                 for ( i = 0; i < s->d; i++ )
00154                 {
00155                     temp = (alphainv * col[i]) + (alpha * p[i]);
00156                     if (temp < 0) temp = 0;
00157                     pixel[i] = (uint8_t)(temp > 255 ? 255 : temp);
00158                 }
00159 
00160                 phMemcpy(p,pixel,s->d);
00161                 p += s->d;
00162             }
00163         }
00164 
00165     }
00166 }
00167 
00168 /* ------------------------------------------------------------------------ */
00169 void ph_draw_vertline( phImageSurface *s,
00170                        phColor         c,
00171                        uint8_t         transp,
00172                        int32_t         y1, 
00173                        int32_t         y2,
00174                        int32_t         x )
00175 {
00176     uint8_t *color  = c.array.v;
00177     if (y1 < 0)     y1 = 0;
00178     if (y2 < 0)     y2 = 0;
00179     if (y1 >= s->h) y1 = s->h - 1;
00180     if (y2 >= s->h) y2 = s->h - 1;
00181     if (x < 0)      x = 0;
00182     if (x >= s->w)  x = s->w - 1;
00183     
00184     
00185     if (y1 == y2)
00186     {
00187         if (transp == 0)
00188         {
00189             ph_set_pixel(s->p,x,y1,s->w,s->h,s->d,color);
00190         }
00191         else if (transp < 100)
00192         {
00193             ph_set_transparent_pixel(transp,s->p,x,y1,s->w,s->h,s->d,color);
00194         }
00195     }
00196     else
00197     {
00198         if (transp == 0)
00199         {
00200             uint8_t *p = &(s->p[(((y1 * s->w) + x) * s->d)]);
00201        
00202             for ( ; y1 < y2; y1++ )
00203             {
00204                 phMemcpy((void *)p,color,s->d);
00205                 p += (s->w * s->d);
00206             }
00207         }
00208         else if (transp < 100)
00209         {
00210             const float alpha     = (transp == 0) ? 0 : ((float)transp) / 100.0;
00211             const float alphainv  = 1.0 - alpha;
00212 
00213             uint32_t i                       = 0;
00214             float    temp                    = 0.0;
00215             uint8_t  pixel[phCOLOR_MAXBYTES] = { 0 };
00216             
00217             uint8_t       *p = &(s->p[(((y1 * s->w) + x) * s->d)]);
00218             const uint8_t *col       = c.array.v;
00219 
00220             for ( ; y1 < y2; y1++ )
00221             {
00222                 for ( i = 0; i < s->d; i++ )
00223                 {
00224                     temp = (alphainv * col[i]) + (alpha * p[i]);
00225                     if (temp < 0) temp = 0;
00226                     pixel[i] = (uint8_t)(temp > 255 ? 255 : temp);
00227                 }
00228 
00229                 phMemcpy(p,pixel,s->d);
00230                 p += (s->w * s->d);
00231             }
00232         }
00233     }
00234 }
00235 
00236 /* ----------------------------------------------------------------------------
00237  * ph_drawline_bresenham -- draw a line from (x1,y1) to (x2,y2) using the
00238  *              Bresenham line algorithm
00239  * ------------------------------------------------------------------------- */
00240 /*---------------------------------------------------------------------------*/
00241 /* Originally written by John R. Watson (jwatson@cs.uml.edu) and modified
00242  * by Philip D.S. Thoren (pthoren@cs.uml.edu) for Phission */
00243 /*
00244  * This function will only work for pixels with contiguous component
00245  * byte values; For example, RGB, HSV, Grey; But not YUV. */
00246 /*---------------------------------------------------------------------------*/
00247 void ph_drawline_bresenham( phImageSurface *surface,
00248                             phColor         c,
00249                             uint8_t         transp,
00250                             int32_t         x1, 
00251                             int32_t         y1,
00252                             int32_t         x2,
00253                             int32_t         y2 )
00254 {
00255     /*phFUNCTION("ph_drawline_bresenham")*/
00256 
00257     int32_t  balance= 0;
00258     int32_t  incx   = 0;
00259     int32_t  incy   = 0;
00260     uint32_t dx     = 0;
00261     uint32_t dy     = 0;
00262     uint32_t x      = 0;
00263     uint32_t y      = 0;
00264     uint8_t *color  = c.array.v;
00265     
00266     const uint8_t   *s = surface->p;
00267     const uint32_t   d = surface->d;
00268     const uint32_t   w = surface->w;
00269     const uint32_t   h = surface->h;
00270 
00271     if (((x1 >= w) && (x2 >= w)) || ((y1 >= h) && (y2 >= h))) return;        
00272     if (((x1 < 0) && (x2 < 0)) || ((y1 < 0) && (y2 < 0))) return;        
00273 
00274     /* if w == 400, you can't write to 400, you must write to 399 */
00275     /* The same goes for height */
00276     if (x1 < 0) x1 = 0;
00277     if (x2 < 0) x2 = 0;
00278     if (y1 < 0) y1 = 0;
00279     if (y2 < 0) y2 = 0;
00280     if (x1 >= w) x1 = w - 1;
00281     if (x2 >= w) x2 = w - 1;
00282     if (y1 >= h) y1 = h - 1;
00283     if (y2 >= h) y2 = h - 1;
00284 
00285     if ((x1 == x2) && (y1 == y2))
00286     {
00287         ph_set_pixel(surface->p,
00288                      x1,
00289                      y1,
00290                      surface->w,
00291                      surface->h,
00292                      surface->d,
00293                      color);
00294         return;
00295     }
00296         
00297     /*phPROGRESS("(%d,%d):(%d,%d):(%d:%d:%d)\n", x1, y1, x2, y2,w,h,d );*/
00298 
00299     if (x2 >= x1)
00300     {
00301         dx   = x2 - x1;
00302         incx = 1;
00303     }
00304     else
00305     {
00306         dx   = x1 - x2;
00307         incx = -1;
00308     }
00309 
00310     if (y2 >= y1)
00311     {
00312         dy   = y2 - y1;
00313         incy = 1;
00314     }
00315     else
00316     {
00317         dy   = y1 - y2;
00318         incy = -1;
00319     }
00320 
00321     x = x1;
00322     y = y1;
00323 
00324     if (dx >= dy)
00325     {
00326         dy <<= 1;
00327         balance = dy - dx;
00328         dx <<= 1;
00329 
00330         while (incx == -1 ? x > x2 : x < x2)
00331         {
00332             if (transp == 0)
00333             {
00334                 ph_put_pixel(s,x,y,w,d,color);
00335             }
00336             else if (transp < 100)
00337                 ph_set_transparent_pixel(transp,s,x,y,w,h,d,color);
00338                 
00339             if (balance >= 0)
00340             {
00341                 y       += incy;
00342                 balance -= dx;
00343             }
00344             balance += dy;
00345             x       += incx;
00346         }
00347         if (transp == 0)
00348         {
00349             ph_put_pixel(s,x,y,w,d,color);
00350         }
00351         else if (transp < 100)
00352             ph_set_transparent_pixel(transp,s,x,y,w,h,d,color);
00353     }
00354     else
00355     {
00356         dx <<= 1;
00357         balance = dx - dy;
00358         dy <<= 1;
00359 
00360         while (incy == -1 ? y > y2 : y < y2)
00361         {
00362             if (transp == 0)
00363             {
00364                 ph_put_pixel(s,x,y,w,d,color);
00365             }
00366             else if (transp < 100)
00367                 ph_set_transparent_pixel(transp,s,x,y,w,h,d,color);
00368 
00369             if (balance >= 0)
00370             {
00371                 x       += incx;
00372                 balance -= dy;
00373             }
00374             balance += dx;
00375             y       += incy;
00376         }
00377         if (transp == 0)
00378         {
00379             ph_put_pixel(s,x,y,w,d,color);
00380         }
00381         else if (transp < 100)
00382             ph_set_transparent_pixel(transp,s,x,y,w,h,d,color);
00383     }
00384 
00385 }
00386 
00387 /*---------------------------------------------------------------------------*/
00388 /* 
00389  * Source : http://www.wol.net.pk/mtshome/cppComputerGraphics.html#Circle
00390  */
00391 void ph_drawcircle_midpoint( phImageSurface *s,
00392                              phColor         color,
00393                              uint8_t         transp,
00394                              int32_t         x0, 
00395                              int32_t         y0,
00396                              int32_t         radius )
00397 {
00398     int32_t f       = 1 - radius;
00399     int32_t ddF_x   = 0;
00400     int32_t ddF_y   = -2 * radius;
00401     int32_t x       = 0;
00402     int32_t y       = radius;
00403     uint8_t *c_array= color.array.v;
00404 
00405     if (transp == 0) 
00406     {
00407         //setPixel(x0, y0 + radius);
00408         ph_set_pixel( s->p, x0,          y0 + radius, s->w, s->h, s->d, c_array);
00409         //setPixel(x0, y0 - radius);
00410         ph_set_pixel( s->p, x0,          y0 - radius, s->w, s->h, s->d, c_array);
00411         //setPixel(x0 + radius, y0);
00412         ph_set_pixel( s->p, x0 + radius, y0, s->w, s->h, s->d, c_array);
00413         //setPixel(x0 - radius, y0);
00414         ph_set_pixel( s->p, x0 - radius, y0, s->w, s->h, s->d, c_array);
00415 
00416         while(x < y) 
00417         {
00418             if(f >= 0) 
00419             {
00420                 y--;
00421                 ddF_y += 2;
00422                 f += ddF_y;
00423             }
00424             x++;
00425             ddF_x += 2;
00426             f += ddF_x + 1;    
00427             ph_set_pixel( s->p, x0 + x, y0 + y, s->w, s->h, s->d, c_array);
00428             ph_set_pixel( s->p, x0 - x, y0 + y, s->w, s->h, s->d, c_array);
00429             ph_set_pixel( s->p, x0 + x, y0 - y, s->w, s->h, s->d, c_array);
00430             ph_set_pixel( s->p, x0 - x, y0 - y, s->w, s->h, s->d, c_array);
00431             ph_set_pixel( s->p, x0 + y, y0 + x, s->w, s->h, s->d, c_array);
00432             ph_set_pixel( s->p, x0 - y, y0 + x, s->w, s->h, s->d, c_array);
00433             ph_set_pixel( s->p, x0 + y, y0 - x, s->w, s->h, s->d, c_array);
00434             ph_set_pixel( s->p, x0 - y, y0 - x, s->w, s->h, s->d, c_array);
00435         }
00436     }
00437     else if (transp < 100)
00438     {
00439         //setPixel(x0, y0 + radius);
00440         ph_set_transparent_pixel( transp, s->p, x0,          y0 + radius, s->w, s->h, s->d, c_array);
00441         //setPixel(x0, y0 - radius);
00442         ph_set_transparent_pixel( transp, s->p, x0,          y0 - radius, s->w, s->h, s->d, c_array);
00443         //setPixel(x0 + radius, y0);
00444         ph_set_transparent_pixel( transp, s->p, x0 + radius, y0, s->w, s->h, s->d, c_array);
00445         //setPixel(x0 - radius, y0);
00446         ph_set_transparent_pixel( transp, s->p, x0 - radius, y0, s->w, s->h, s->d, c_array);
00447 
00448         while(x < y) 
00449         {
00450             if(f >= 0) 
00451             {
00452                 y--;
00453                 ddF_y += 2;
00454                 f += ddF_y;
00455             }
00456             x++;
00457             ddF_x += 2;
00458             f += ddF_x + 1;    
00459             ph_set_transparent_pixel( transp, s->p, x0 + x, y0 + y, s->w, s->h, s->d, c_array);
00460             ph_set_transparent_pixel( transp, s->p, x0 - x, y0 + y, s->w, s->h, s->d, c_array);
00461             ph_set_transparent_pixel( transp, s->p, x0 + x, y0 - y, s->w, s->h, s->d, c_array);
00462             ph_set_transparent_pixel( transp, s->p, x0 - x, y0 - y, s->w, s->h, s->d, c_array);
00463             ph_set_transparent_pixel( transp, s->p, x0 + y, y0 + x, s->w, s->h, s->d, c_array);
00464             ph_set_transparent_pixel( transp, s->p, x0 - y, y0 + x, s->w, s->h, s->d, c_array);
00465             ph_set_transparent_pixel( transp, s->p, x0 + y, y0 - x, s->w, s->h, s->d, c_array);
00466             ph_set_transparent_pixel( transp, s->p, x0 - y, y0 - x, s->w, s->h, s->d, c_array);
00467         }
00468     }
00469 }
00470 
00471 /* ----------------------------------------------------------------------------
00472  * ph_draw_hollow_rect -- draw a hollow rectangle
00473  *
00474  * IT is assumed that the phColor will match that of the surface color
00475  * type. Unexpected results may occur if they are not. It's left to the
00476  * coder to ensure these things because this function can't have heavy
00477  * error checking.
00478  * ------------------------------------------------------------------------- */
00479 void ph_draw_hollow_rect(phImageSurface    *s,
00480                          phColor            c,
00481                          uint8_t            transp,
00482                          uint32_t           x1, 
00483                          uint32_t           y1,
00484                          uint32_t           x2,
00485                          uint32_t           y2 )
00486 {
00487     /* const char *function = "ph_draw_hollow_rect"; */
00488    
00489     /* draw the top line */
00490     ph_draw_horizline( s, c, transp, x1, x2, y1 );
00491     /* draw the left side */
00492     ph_draw_vertline(s, c, transp, y1, y2, x1 );
00493     /* draw the right side */
00494     ph_draw_vertline(s, c, transp, y1, y2, x2 );
00495     /* draw the bottom line */
00496     ph_draw_horizline( s, c, transp, x1, x2, y2 );
00497     
00498 /* error: */
00499     return;
00500 }
00501 
00502 /* ------------------------------------------------------------------------ */
00503 void ph_draw_hollow_triangle(phImageSurface    *s,
00504                              phColor            c,
00505                              uint8_t            transp,
00506                              uint32_t           x1, 
00507                              uint32_t           y1, 
00508                              uint32_t           x2,
00509                              uint32_t           y2,
00510                              uint32_t           x3,
00511                              uint32_t           y3 )
00512 {
00513     ph_drawline_bresenham(s, c, transp, x1, y1, x2, y2 );
00514     ph_drawline_bresenham(s, c, transp, x2, y2, x3, y3 );
00515     ph_drawline_bresenham(s, c, transp, x3, y3, x1, y1 );
00516     
00517     return;
00518 }
00519 /* ------------------------------------------------------------------------ */
00520 /* 
00521  * Source: http://www-users.mat.uni.torun.pl/~wrona/3d_tutor/tri_fillers.html
00522  *         http://www.geocities.com/wronski12/3d_tutor/index.html
00523  *         http://www.geocities.com/wronski12/3d_tutor/tri_fillers.html
00524  */
00525 void ph_triangle_fill(phImageSurface  *s,
00526                       phColor          c,
00527                       uint8_t          transp,
00528                       int32_t          tx1, 
00529                       int32_t          ty1, 
00530                       int32_t          tx2,
00531                       int32_t          ty2,
00532                       int32_t          tx3,
00533                       int32_t          ty3 )
00534 {
00535     phFUNCTION("ph_triangle_fill")
00536 
00537     float dx1;
00538     float dx2;
00539     float dx3;
00540     
00541     float sx;
00542     float sy;
00543 
00544     float ex;
00545     float ey;
00546 
00547     float x1;
00548     float y1;
00549     float x2;
00550     float y2;
00551     float x3;
00552     float y3;
00553 
00554     /* Sort the coordinates based on the Y values */
00555     if (ty3 > ty2)
00556     {
00557         if (ty2 > ty1)
00558         {
00559             x1 = tx1; y1 = ty1;
00560             x2 = tx2; y2 = ty2;
00561             x3 = tx3; y3 = ty3;
00562         }
00563         else if (ty3 > ty1)
00564         {
00565             x1 = tx2; y1 = ty2;
00566             x2 = tx1; y2 = ty1;
00567             x3 = tx3; y3 = ty3;
00568         }
00569         else
00570         {
00571             x1 = tx2; y1 = ty2;
00572             x2 = tx3; y2 = ty3;
00573             x3 = tx1; y3 = ty1;
00574         }
00575     }
00576     else
00577     {
00578         if (ty3 > ty1)
00579         {
00580             x1 = tx1; y1 = ty1;
00581             x2 = tx3; y2 = ty3;
00582             x3 = tx2; y3 = ty2;
00583         }
00584         else if (ty2 > ty1)
00585         {
00586             x1 = tx3; y1 = ty3;
00587             x2 = tx1; y2 = ty1;
00588             x3 = tx2; y3 = ty2;
00589         }
00590         else
00591         {
00592             x1 = tx3; y1 = ty3;
00593             x2 = tx2; y2 = ty2;
00594             x3 = tx1; y3 = ty1;
00595         }
00596     }
00597 
00598     /* Figure out the stepping */
00599     if (y2 - y1 > 0) 
00600         dx1 = (x2 - x1) / (y2 - y1);
00601     else 
00602         dx1 = 0;
00603     
00604     if (y3 - y1 > 0)
00605         dx2 = (x3 - x1) / (y3 - y1);
00606     else
00607         dx2 = 0;
00608     
00609     if (y3 - y2 > 0)
00610         dx3 = (x3 - x2) / (y3 - y2);
00611     else
00612         dx3 = 0;
00613 
00614     sx = ex = x1;
00615     sy = ey = y1;
00616     
00617     if(dx1 > dx2) 
00618     {
00619         for ( ; sy <= y2; sy++, ey++, sx += dx2, ex += dx1)
00620         {
00621             ph_draw_horizline( s, c, transp, (int32_t)sx, (int32_t)ex, (int32_t)sy);
00622         }
00623         ex = x2;
00624         ey = y2;
00625         for ( ; sy <= y3; sy++, ey++, sx += dx2, ex += dx3 )
00626         {
00627             ph_draw_horizline( s, c, transp, (int32_t)sx, (int32_t)ex, (int32_t)sy);
00628         }
00629     }
00630     else 
00631     {
00632         for ( ; sy <= y2; sy++, ey++, sx += dx1, ex += dx2)
00633         {
00634             ph_draw_horizline( s, c, transp, (int32_t)sx, (int32_t)ex, (int32_t)sy );
00635         }
00636         sx = x2;
00637         sy = y2;
00638         for ( ; sy <= y3; sy++, ey++, sx += dx3, ex += dx2)
00639         {
00640             ph_draw_horizline( s, c, transp, (int32_t)sx, (int32_t)ex, (int32_t)sy );
00641         }
00642     }
00643     return;
00644 }                      
00645 
00646 /* ------------------------------------------------------------------------ */
00647 phImageSurface  phImageSurface_new  ( uint32_t  w,
00648                                       uint32_t  h,
00649                                       uint32_t  f,
00650                                       uint8_t  *p )
00651 {
00652     phImageSurface t = { w, h, f, phImageFormatToDepth(f),p };
00653     return t;
00654 }
00655 
00656 /* ------------------------------------------------------------------------ */
00657 phSize phSize_new( int32_t w,  int32_t h )
00658 {
00659     phSize t = { w, h };
00660     return t;
00661 }
00662 
00663 /* ------------------------------------------------------------------------ */
00664 phPoint phPoint_new( int32_t x,  int32_t y )
00665 {
00666     phPoint t = { x, y };    
00667     return t;
00668 }
00669 
00670 /* ------------------------------------------------------------------------ */
00671 phLine phLine_new( int32_t x1, int32_t y1,
00672                    int32_t x2, int32_t y2 )
00673 {
00674     phLine t = { x1, y1, x2, y2 };
00675     return t;
00676 }
00677 
00678 /* ------------------------------------------------------------------------ */
00679 phCircle phCircle_new( int32_t x,  int32_t y, int32_t r )
00680 {
00681     phCircle t = { x, y, r };
00682     return t;
00683 }
00684 
00685 /* ------------------------------------------------------------------------ */
00686 phRectangle phRectangle_new( int32_t x,  int32_t y, 
00687                              int32_t w,  int32_t h )
00688 {
00689     phRectangle t = { x, y, w, h };
00690     return t;
00691 }
00692 
00693 /* ------------------------------------------------------------------------ */
00694 phTriangle phTriangle_new( int32_t x1, int32_t y1,
00695                            int32_t x2, int32_t y2,
00696                            int32_t x3, int32_t y3 )
00697 {
00698     phTriangle t = {x1, y1, x2, y2, x3, y3 };
00699     return t;
00700 }
00701 
00702 /* ------------------------------------------------------------------------ */
00703 phCross phCross_new( int32_t x,  int32_t y,
00704                      int32_t xs, int32_t ys )
00705 {
00706     phCross t = {x,y,xs,ys};
00707     return t;
00708 }
00709 
00710 /* ------------------------------------------------------------------------ */
00711 void ph_draw_point( phImageSurface *s, phPoint p, phColor color,
00712                     uint8_t size, uint8_t transp )
00713 {
00714     if (s == NULL)
00715     {
00716         phPRINT_ERROR("(ph_draw_point) Invalid parameter : s == NULL\n");
00717         return;
00718     }
00719     if (!ph_draw_check_format(s->f,color))
00720     {
00721         phPRINT_ERROR("(ph_draw_point) Invalid parameter : "
00722                       "The surface format doesn't correspond"
00723                       " with the color parameter\n");
00724         phPRINT_ERROR("(ph_draw_point) surface format: %s\n",
00725                       phImageFormatToString(s->f));
00726         phPRINT_ERROR("(ph_draw_point) color type: %s\n",
00727                       phColorToString(color) );
00728         return;
00729     }
00730 
00731     if (ph_draw_check_coords(p.x,p.y,s->w,s->h))
00732     {
00733         uint8_t *c  = color.array.v;
00734         ph_put_pixel(s->p,p.x,p.y,s->w,s->d,c);
00735     }
00736 }
00737 
00738 /* ------------------------------------------------------------------------ */
00739 void ph_draw_line( phImageSurface *s, phLine l, phColor color,
00740                    uint8_t size, uint8_t transp )
00741 {
00742     if (s == NULL)
00743     {
00744         phPRINT_ERROR("(ph_draw_line) Invalid parameter : s == NULL\n");
00745         return;
00746     }
00747     if (!ph_draw_check_format(s->f,color))
00748     {
00749         phPRINT_ERROR("(ph_draw_line) Invalid parameter : "
00750                       "The surface format doesn't correspond"
00751                       " with the color parameter\n");
00752         phPRINT_ERROR("(ph_draw_line) surface format: %s\n",
00753                       phImageFormatToString(s->f));
00754         phPRINT_ERROR("(ph_draw_line) color type: %s\n",
00755                       phColorToString(color) );
00756         return;
00757     }
00758     
00759     ph_drawline_bresenham( s, color, transp, l.x1, l.y1, l.x2, l.y2 );
00760 }
00761 
00762 /* ------------------------------------------------------------------------ */
00763 void ph_draw_circle( phImageSurface *s, phCircle circ, phColor color,
00764                      uint8_t size, uint8_t fill, uint8_t transp )
00765 {
00766     int32_t     r = 0;
00767     uint8_t    *c = color.array.v;
00768     
00769     if (s == NULL) 
00770     {
00771         phPRINT_ERROR("(ph_draw_circle) Invalid parameter : s == NULL\n");
00772         return;
00773     }
00774     if (!ph_draw_check_format(s->f,color))
00775     {
00776         phPRINT_ERROR("(ph_draw_circle) Invalid parameter : "
00777                       "The surface format doesn't correspond"
00778                       " with the color parameter\n");
00779         phPRINT_ERROR("(ph_draw_circle) surface format: %s\n",
00780                       phImageFormatToString(s->f));
00781         phPRINT_ERROR("(ph_draw_circle) color type: %s\n",
00782                       phColorToString(color) );
00783         return;
00784     }
00785 
00786     ph_drawcircle_midpoint( s, color, transp, circ.x, circ.y, circ.r );
00787 
00788     if (fill == phDrawingFill)
00789     {
00790         for (r = circ.r-1; r > 2; r--)
00791         { 
00792             ph_drawcircle_midpoint( s, color, transp, circ.x, circ.y, r );
00793         }
00794         ph_set_pixel(s->p,circ.x,circ.y,s->w,s->h,s->d,c);
00795     }
00796 }
00797 
00798 /* ------------------------------------------------------------------------ */
00799 void ph_draw_rectangle( phImageSurface *s, phRectangle r, phColor color,
00800                         uint8_t size, uint8_t fill, uint8_t transp )
00801 {
00802     if (s == NULL)
00803     {
00804         phPRINT_ERROR("(ph_draw_rectangle) Invalid parameter : s == NULL\n");
00805         return;
00806     }
00807     if (!ph_draw_check_format(s->f,color))
00808     {
00809         phPRINT_ERROR("(ph_draw_rectangle) Invalid parameter : "
00810                       "The surface format doesn't correspond"
00811                       " with the color parameter\n");
00812         phPRINT_ERROR("(ph_draw_rectangle) surface format: %s\n",
00813                       phImageFormatToString(s->f));
00814         phPRINT_ERROR("(ph_draw_rectangle) color type: %s\n",
00815                       phColorToString(color) );
00816         return;
00817     }
00818 
00819     ph_draw_hollow_rect(s,color,transp, r.x,r.y,r.x+r.w,r.y+r.h);
00820     if (fill == phDrawingFill)
00821     {
00822         int32_t x1 = r.x+1;
00823         int32_t y1 = r.y+1;
00824         int32_t x2 = x1+(r.w-1);
00825         int32_t y2 = y1+(r.h-1);
00826         while ( y2 > y1 )
00827         {
00828             ph_draw_horizline( s, color, transp, x1, x2, y1);
00829             y1++;
00830         }
00831     }
00832 }
00833 
00834 /* ------------------------------------------------------------------------ */
00835 void ph_draw_triangle( phImageSurface *s, phTriangle t, phColor color,
00836                        uint8_t size, uint8_t fill, uint8_t transp )
00837 {
00838     if (s == NULL)
00839     {
00840         phPRINT_ERROR("(ph_draw_triangle) Invalid parameter : s == NULL\n");
00841         return;
00842     }
00843     if (!ph_draw_check_format(s->f,color))
00844     {
00845         phPRINT_ERROR("(ph_draw_triangle) Invalid parameter : "
00846                       "The surface format doesn't correspond"
00847                       " with the color parameter\n");
00848         phPRINT_ERROR("(ph_draw_triangle) surface format: %s\n",
00849                       phImageFormatToString(s->f));
00850         phPRINT_ERROR("(ph_draw_triangle) color type: %s\n",
00851                       phColorToString(color) );
00852         return;
00853     }
00854 
00855     if (fill == phDrawingFill)
00856         ph_triangle_fill(s,color,transp, t.x1,t.y1,t.x2,t.y2,t.x3,t.y3);
00857     else
00858         ph_draw_hollow_triangle(s,color,transp, t.x1,t.y1,t.x2,t.y2,t.x3,t.y3);
00859 }
00860 
00861 /* ------------------------------------------------------------------------ */
00862 void ph_draw_cross( phImageSurface *s, phCross x, phColor color,
00863                     uint8_t size, uint8_t transp )
00864 {
00865     if (s == NULL)
00866     {
00867         phPRINT_ERROR("(ph_draw_triangle) Invalid parameter : s == NULL\n");
00868         return;
00869     }
00870     if (!ph_draw_check_format(s->f,color))
00871     {
00872         phPRINT_ERROR("(ph_draw_cross) Invalid parameter : "
00873                       "The surface format doesn't correspond"
00874                       " with the color parameter\n");
00875         phPRINT_ERROR("(ph_draw_cross) surface format: %s\n",
00876                       phImageFormatToString(s->f));
00877         phPRINT_ERROR("(ph_draw_cross) color type: %s\n",
00878                       phColorToString(color) );
00879         return;
00880     }
00881 
00882     ph_draw_horizline( s, color, 
00883                        transp, 
00884                        x.x - x.xs, 
00885                        x.x + x.xs,
00886                        x.y );
00887     ph_draw_vertline( s, color, 
00888                       transp, 
00889                       x.y - x.ys, 
00890                       x.y + x.ys,
00891                       x.x );
00892 }
00893 
00894 /* ------------------------------------------------------------------------ */
00895 int phPoint_print( int fd, phPoint p )
00896 {
00897 #if !defined(__ADSPBLACKFIN__)
00898     phFUNCTION("phPoint_print")
00899     FILE    *fp = NULL;
00900    
00901     if ((fd < 0) || (fd == fileno(stdin))) fd = fileno(stdout);
00902     
00903     fp = fdopen(fd,"w");
00904     phCHECK_PTR(fp,"fdopen","fdopen failed(%d)",fd);
00905 
00906     fprintf(fp,"phPoint(x:%d,y:%d)\n", p.x,p.y);
00907     
00908     rc = fprintf(fp,"\n");
00909     if (rc == EOF) goto success;
00910 
00911     fflush(fp);
00912 
00913 success:
00914     return phSUCCESS;
00915     
00916 #endif /* #if !defined(__ADSPBLACKFIN__) */
00917 error:
00918     return phFAIL;
00919 }
00920 
00921 /* ------------------------------------------------------------------------ */
00922 int phLine_print( int fd, phLine l )
00923 {
00924 #if !defined(__ADSPBLACKFIN__)
00925     phFUNCTION("phLine_print")
00926     FILE    *fp = NULL;
00927    
00928     if ((fd < 0) || (fd == fileno(stdin))) fd = fileno(stdout);
00929     
00930     fp = fdopen(fd,"w");
00931     phCHECK_PTR(fp,"fdopen","fdopen failed(%d)",fd);
00932 
00933     fprintf(fp,"phLine(x1:%d,y1:%d,x2:%d,y2:%d)\n",l.x1,l.y1,l.x2,l.y2);
00934    
00935     rc = fprintf(fp,"\n");
00936     if (rc == EOF) goto success;
00937 
00938     fflush(fp);
00939 
00940 success:
00941     return phSUCCESS;
00942     
00943 #endif /* #if !defined(__ADSPBLACKFIN__) */
00944 error:
00945     return phFAIL;
00946 }
00947 
00948 /* ------------------------------------------------------------------------ */
00949 int phCircle_print( int fd, phCircle c )
00950 {
00951 #if !defined(__ADSPBLACKFIN__)
00952     phFUNCTION("phCircle_print")
00953     FILE    *fp = NULL;
00954    
00955     if ((fd < 0) || (fd == fileno(stdin))) fd = fileno(stdout);
00956     
00957     fp = fdopen(fd,"w");
00958     phCHECK_PTR(fp,"fdopen","fdopen failed(%d)",fd);
00959    
00960     fprintf(fp,"phCircle(x:%d,y:%d,r:%d)\n",c.x,c.y,c.r);
00961    
00962     rc = fprintf(fp,"\n");
00963     if (rc == EOF) goto success;
00964 
00965     fflush(fp);
00966 
00967 success:
00968     return phSUCCESS;
00969     
00970 #endif /* #if !defined(__ADSPBLACKFIN__) */
00971 error:
00972     return phFAIL;
00973 }
00974 
00975 /* ------------------------------------------------------------------------ */
00976 int phRectangle_print( int fd, phRectangle r )
00977 {
00978 #if !defined(__ADSPBLACKFIN__)
00979     phFUNCTION("phRectangle_print")
00980     FILE    *fp = NULL;
00981    
00982     if ((fd < 0) || (fd == fileno(stdin))) fd = fileno(stdout);
00983     
00984     fp = fdopen(fd,"w");
00985     phCHECK_PTR(fp,"fdopen","fdopen failed(%d)",fd);
00986    
00987     fprintf(fp,"phRectangle(x:%d,y:%d,w:%d,h%d)\n",
00988             r.x,r.y,r.w,r.h);
00989    
00990     rc = fprintf(fp,"\n");
00991     if (rc == EOF) goto success;
00992 
00993     fflush(fp);
00994 
00995 success:
00996     return phSUCCESS;
00997     
00998 #endif /* #if !defined(__ADSPBLACKFIN__) */
00999 error:
01000     return phFAIL;
01001 }
01002 
01003 /* ------------------------------------------------------------------------ */
01004 int phTriangle_print( int fd, phTriangle t )
01005 {
01006 #if !defined(__ADSPBLACKFIN__)
01007     phFUNCTION("phTriangle_print")
01008     FILE    *fp = NULL;
01009    
01010     if ((fd < 0) || (fd == fileno(stdin))) fd = fileno(stdout);
01011     
01012     fp = fdopen(fd,"w");
01013     phCHECK_PTR(fp,"fdopen","fdopen failed(%d)",fd);
01014    
01015     fprintf(fp,"phTriangle(x1:%d,y1:%d,x2:%d,y2:%d,x3:%d,y3:%d)\n",
01016             t.x1,t.y1,t.x2,t.y2,t.x3,t.y3);
01017    
01018     rc = fprintf(fp,"\n");
01019     if (rc == EOF) goto success;
01020 
01021     fflush(fp);
01022 
01023 success:
01024     return phSUCCESS;
01025     
01026 #endif /* #if !defined(__ADSPBLACKFIN__) */
01027 error:
01028     return phFAIL;
01029 }
01030 
01031 /* ------------------------------------------------------------------------ */
01032 int phCross_print( int fd, phCross c )
01033 {
01034 #if !defined(__ADSPBLACKFIN__)
01035     phFUNCTION("phCross_print")
01036     FILE    *fp = NULL;
01037    
01038     if ((fd < 0) || (fd == fileno(stdin))) fd = fileno(stdout);
01039     
01040     fp = fdopen(fd,"w");
01041     phCHECK_PTR(fp,"fdopen","fdopen failed(%d)",fd);
01042    
01043     fprintf(fp,"phCross(x:%d,y:%d,xs:%d,ys:%d)\n",c.x,c.y,c.xs,c.ys);
01044    
01045     rc = fprintf(fp,"\n");
01046     if (rc == EOF) goto success;
01047 
01048     fflush(fp);
01049 
01050 success:
01051     return phSUCCESS;
01052     
01053 #endif /* #if !defined(__ADSPBLACKFIN__) */
01054 error:
01055     return phFAIL;
01056 }
01057 
01058 /* ------------------------------------------------------------------------ */
01059 #define phNoneType         (0)
01060 #define phPointType        (1)
01061 #define phLineType         (2)
01062 #define phCircleType       (3)
01063 #define phRectangleType    (4)
01064 #define phTriangleType     (5)
01065 #define phCrossType        (6)
01066 
01067 #define phDrawingObjectNodeMAX (7)
01068 
01069 /* ------------------------------------------------------------------------ */
01077 typedef struct phDrawingObjectNode_t
01078 {
01083     uint8_t                         type;
01088     uint8_t                         size;
01095     uint8_t                         fill;
01100     uint8_t                         transp;
01102     void                           *object;
01104     phColor                        *color;
01106     struct phDrawingObjectNode_t   *next;
01107 
01108 } phDrawingObjectNode;
01109 
01110 /* ------------------------------------------------------------------------ */
01111 struct phDrawing_t
01112 {
01113     /* This is to keep track of the order in which the drawing objects were
01114      * added to the drawing to make sure we draw them correctly. 
01115      *
01116      * m_obj_count: the total number of drawing objects
01117      * m_obj_ptr:   the pointer to the first object node
01118      */
01119     uint32_t                m_obj_count;
01120     phDrawingObjectNode    *m_obj_ptr;
01121     phDrawingObjectNode    *m_obj_endptr;
01122     
01123     uint32_t    m_npoints;
01124     uint32_t    m_nlines;
01125     uint32_t    m_ncircles;
01126     uint32_t    m_nrectangles;
01127     uint32_t    m_ntriangles;
01128     uint32_t    m_ncrosses;
01129 };
01130 
01131 /* ------------------------------------------------------------------------ */
01132 int phDrawing_alloc(phDrawing *d )
01133 {
01134     if ((d == NULL) || (*d != NULL)) return phFAIL;
01135 
01136     *d = (phDrawing)phCalloc(1,sizeof(struct phDrawing_t));
01137 
01138     return phSUCCESS;
01139 }
01140 
01141 /* ------------------------------------------------------------------------ */
01142 void phDrawing_free( phDrawing *d )
01143 {
01144     if (d == NULL) return;
01145     phDrawing_clear(*d);
01146     phFree(*d);
01147 }
01148 
01149 /* ------------------------------------------------------------------------ */
01150 static int phDrawing_freeObjectNodes( phDrawing d )
01151 {
01152     /* phFUNCTION("phDrawing_freeObjectNodes") */
01153 
01154     phDrawingObjectNode *obj    = NULL;
01155     phDrawingObjectNode *next   = NULL;
01156 
01157     if (d == NULL) return phFAIL;
01158     
01159     obj = d->m_obj_ptr;
01160 
01161     /* Go through the entire list and free everything */
01162     while (obj != NULL)
01163     {
01164         next = obj->next;
01165         phFree(obj->object);
01166         phFree(obj->color);
01167         phFree(obj);
01168         obj = next;
01169     }
01170 
01171     /* Reset the drawing object's values */
01172     d->m_obj_ptr   = NULL;
01173     d->m_obj_endptr= NULL;
01174     d->m_obj_count = 0;
01175     
01176     return phSUCCESS;
01177 }
01178 
01179 /* ------------------------------------------------------------------------ */
01180 static int phDrawing_clearObjectNodeType( phDrawing d, uint32_t type )
01181 {
01182     phFUNCTION("phDrawing_copyObjectNodeType")
01183 
01184     phDrawingObjectNode *obj    = NULL;
01185     phDrawingObjectNode *prev   = NULL;
01186     phDrawingObjectNode *next   = NULL;
01187 
01188     if ((d == NULL) && (obj = d->m_obj_ptr) == NULL) 
01189     {
01190         return phFAIL;
01191     }
01192     
01193     while ((obj != NULL) && (d->m_obj_count > 0))
01194     {
01195         /* Get the next pointer */
01196         next = obj->next;
01197         
01198         /* if the type matches, then we're going to delete it */
01199         if (type == obj->type)
01200         {
01201             /* Make sure we keep the head of the list set...
01202              * If we're going to delete an object that is the first object in
01203              * the list, then we need to set the first node to the next node.
01204              * This might waste cycles in some cases, but let's keep the code
01205              * simple.
01206              */
01207             if (obj == d->m_obj_ptr) 
01208             {
01209                 d->m_obj_ptr = next;
01210             }
01211             /* if this was the end pointer, we need to set it to the previous
01212              * node now. We always have to perform this check because we aren't
01213              * looking two nodes ahead. This code is just simpler. */
01214             if (obj == d->m_obj_endptr)
01215             {
01216                 d->m_obj_endptr = prev;
01217             }
01218             
01219             /* Free the node */
01220             phFree(obj->object);
01221             phFree(obj->color);
01222             phFree(obj);
01223             
01224             /* Adjust the total object count */
01225             d->m_obj_count--;
01226             
01227             if (prev != NULL)
01228             {
01229                 /* Adjust the next pointer for the previous node */
01230                 prev->next = next;
01231             }
01232         }
01233         /* if we're not deleting the object then we can set the previous 
01234          * pointer */
01235         else
01236         {
01237             prev = obj;
01238         }
01239         
01240         /* Set the pointer for the next loop */
01241         obj = next;
01242     }
01243     
01244     return phSUCCESS;
01245 }
01246 
01247 /* ------------------------------------------------------------------------ */
01248 static int phDrawing_addObjectNodeType( phDrawing   d, 
01249                                         void       *object_ptr,
01250                                         phColor    *color_ptr,
01251                                         uint32_t    type,
01252                                         uint8_t     size, 
01253                                         uint8_t     fill, 
01254                                         uint8_t     transp )
01255 {
01256     phFUNCTION("phDrawing_addObjectNodeType")
01257 
01258     if ((type > phNoneType) && (type < phDrawingObjectNodeMAX) &&
01259         (d != NULL))
01260     {
01261         phDrawingObjectNode *newobj = NULL;
01262     
01263         newobj = (phDrawingObjectNode *)phMalloc(sizeof(phDrawingObjectNode));
01264         phCHECK_NULLPTR(newobj,"phMalloc",
01265                 "phMalloc: Error allocating memory\n");
01266 
01267         /* Set the type */
01268         newobj->type = type;
01269         /* Set the pointers to the drawing object */
01270         /* ... increment the counter into the object arrays */
01271         newobj->object      = object_ptr;
01272         newobj->color       = color_ptr;
01273         newobj->size        = size;
01274         newobj->fill        = fill;
01275         newobj->transp     = transp;
01276         newobj->next        = NULL;
01277 
01278         /* If this is the first node in the list, set the beginning pointer */
01279         if (d->m_obj_ptr == NULL)
01280         {
01281             d->m_obj_ptr = d->m_obj_endptr = newobj;
01282         }
01283         else
01284         {
01285             /* d->m_obj_endptr will not be NULL if we get here */
01286             
01287             /* Set the next pointer for the end pointer to the new object and ... */
01288             d->m_obj_endptr->next = newobj;
01289             
01290             /* .. then, Set the new end pointer */
01291             d->m_obj_endptr = newobj;
01292         }
01293         d->m_obj_count++;
01294     }
01295 
01296     return phSUCCESS;
01297 error:
01298     return phFAIL;
01299 }
01300 /* ------------------------------------------------------------------------ */
01301 static int phDrawing_copyObjectNodes( phDrawing d, phDrawing copy )
01302 {
01303     phFUNCTION("phDrawing_copyObjectNodes")
01304 
01305     if ((d != NULL) && (copy != NULL) && 
01306         (d->m_obj_ptr != NULL) && (d->m_obj_count > 0))
01307     {
01308         int     i   = 0;
01309         uint8_t type= 0;
01310         size_t  object_size[] = { sizeof(phPoint),
01311                                   sizeof(phLine),
01312                                   sizeof(phCircle),
01313                                   sizeof(phRectangle),
01314                                   sizeof(phTriangle),
01315                                   sizeof(phCross) };
01316             
01317 
01318         phDrawingObjectNode *obj        = d->m_obj_ptr;
01319         phDrawingObjectNode *newobj     = NULL;
01320         
01321         /* Allocate the first object pointer if there is any object in the other
01322          * drawing.
01323          */
01324         if (obj != NULL)
01325         {
01326             newobj = (phDrawingObjectNode *)phMalloc(sizeof(phDrawingObjectNode));
01327             phCHECK_NULLPTR(newobj,"phMalloc",
01328                     "phMalloc: Error allocating memory\n");
01329 
01330             /* Set the first node */
01331             copy->m_obj_ptr = newobj;
01332         }
01333 
01334         /* Go through all the pointers and allocate a node for each drawing 
01335          * object. Double check to make sure the obj isn't NULL.
01336          */
01337         for (i = 0; (i < d->m_obj_count) && (obj != NULL); i++ )
01338         {
01339             /* Copy the node information */
01340             /* .. this will also copy the pointer information which will get
01341              * changed later. */
01342             *newobj = *obj;
01343             type = newobj->type;
01344 
01345             /* Allocate the object */
01346             newobj->object = phMalloc(object_size[type]);
01347             phCHECK_PTR(newobj->object,"phMalloc","Allocating object failed.");
01348             
01349             /* Allocate the color */
01350             newobj->color = (phColor *)phMalloc(sizeof(phColor));
01351             phCHECK_PTR(newobj->color,"phMalloc","Allocating color failed.");
01352             
01353             /* Copy the object data */
01354             phMemcpy(newobj->object,obj->object,object_size[type]);
01355             /* Copy the color */
01356             phMemcpy(newobj->color,obj->color,sizeof(phColor));
01357             
01358             /* Get the next object to copy */
01359             obj = obj->next;
01360 
01361             /* make sure the next object isn't NULL */
01362             if (obj != NULL)
01363             {
01364                 /* allocate a newobj object if there will be another loop */
01365                 newobj->next = (phDrawingObjectNode *)phMalloc(sizeof(phDrawingObjectNode));
01366                 /* Make sure the allocated new object isn't NULL */
01367                 phCHECK_NULLPTR(newobj->next,"phMalloc",
01368                         "Failed to allocate the next pointer.");
01369                 /* Set the newobj pointer to the new empty object pointer */
01370                 newobj = newobj->next;
01371             }
01372             else
01373             {
01374                 /* Make sure the pointer is set to NULL */
01375                 newobj->next = NULL;
01376             }
01377         }
01378         /* Set the end pointer for the copy */
01379         copy->m_obj_endptr = newobj;
01380 
01381         /* Make sure we set the total number of objects in the new copy */
01382         copy->m_obj_count = d->m_obj_count;
01383     }
01384     else
01385     {
01386         return phFAIL;
01387     }
01388     return phSUCCESS;
01389 error:
01390     return phFAIL;
01391 }
01392 
01393 /* ------------------------------------------------------------------------ */
01394 int phDrawing_copy( phDrawing d, phDrawing copy )
01395 {
01396     phFUNCTION("phDrawing_copy")
01397         
01398     if ((d == NULL) || (copy == NULL)) 
01399     {
01400         phPRINT_ERROR("(phDrawing_copy) Invalid parameter"
01401                       " : d:%p or copy:%p is NULL.\n",
01402                       d,copy);
01403         return phFAIL;
01404     }
01405     
01406     phDrawing_clear(copy);
01407 
01408     copy->m_npoints         = d->m_npoints;
01409     copy->m_nlines          = d->m_nlines;
01410     copy->m_ncircles        = d->m_ncircles;
01411     copy->m_nrectangles     = d->m_nrectangles;
01412     copy->m_ntriangles      = d->m_ntriangles;
01413     copy->m_ncrosses        = d->m_ncrosses;
01414 
01415     rc = phDrawing_copyObjectNodes( d, copy );
01416     phPRINT_RC(rc,NULL,"phDrawing_copyObjectNodes");
01417 
01418     return phSUCCESS;
01419 }
01420 /* ------------------------------------------------------------------------ */
01421 void phDrawing_print( phDrawing d )
01422 {
01423     phFUNCTION("phDrawing_printObjectNodes")
01424         
01425     phDrawingObjectNode *obj    = NULL;
01426     phDrawingObjectNode *next   = NULL;
01427     phColor             *color  = NULL;
01428     phPoint             *p      = NULL;
01429     phLine              *l      = NULL;
01430     phCircle            *c      = NULL;
01431     phRectangle         *r      = NULL;
01432     phTriangle          *t      = NULL;
01433     phCross             *x      = NULL;
01434     
01435     if (d == NULL) return;
01436 
01437     obj = d->m_obj_ptr;
01438 
01439     while (obj != NULL)
01440     {
01441         color  = obj->color;
01442         switch (obj->type)
01443         {
01444             case phPointType:
01445             {
01446                 phPRINT("{\n\t");
01447                 p = (phPoint *)obj->object;
01448                 phPoint_print(fileno(stdout),*p);
01449                 phPRINT( "\tsize:%u transp:%u\n}\n",
01450                          obj->size, obj->transp );
01451             }
01452             break;
01453             case phLineType:
01454             {
01455                 phPRINT("{\n\t");
01456                 l = (phLine *)obj->object;
01457                 phLine_print(fileno(stdout),*l);
01458                 phPRINT( "\tsize:%u transp:%u\n}\n",
01459                          obj->size, obj->transp );
01460             }
01461             break;
01462             case phCircleType:
01463             {
01464                 phPRINT("{\n\t");
01465                 c = (phCircle *)obj->object;
01466                 phCircle_print(fileno(stdout),*c);
01467                 phPRINT( "\tsize:%u fill:%u transp:%u\n}\n",
01468                          obj->size, obj->fill, obj->transp );
01469             }
01470             break;
01471             case phRectangleType:
01472             {
01473                 phPRINT("{\n\t");
01474                 r = (phRectangle *)obj->object;
01475                 phRectangle_print(fileno(stdout),*r);
01476                 phPRINT( "\tsize:%u fill:%u transp:%u\n}\n",
01477                          obj->size, obj->fill, obj->transp );
01478             }
01479             break;
01480             case phTriangleType:
01481             {
01482                 phPRINT("{\n\t");
01483                 t = (phTriangle *)obj->object;
01484                 phTriangle_print(fileno(stdout),*t);
01485                 phPRINT( "\tsize:%u fill:%u transp:%u\n}\n",
01486                          obj->size, obj->fill, obj->transp );
01487             }
01488             break;
01489             case phCrossType:
01490             {
01491                 phPRINT("{\n\t");
01492                 x = (phCross *)obj->object;
01493                 phCross_print(fileno(stdout),*x);
01494                 phPRINT( "\tsize:%u transp:%u\n}\n",
01495                          obj->size, obj->transp );
01496             }
01497             break;
01498             default:
01499                 break;
01500         }
01501         next = obj->next;
01502         obj = next;
01503     }
01504 }
01505 
01506 /* ------------------------------------------------------------------------ */
01507 void phDrawing_draw( phDrawing d, phImageSurface *s )
01508 {
01509     phFUNCTION("phDrawing_draw")
01510         
01511     phDrawingObjectNode *obj    = NULL;
01512     phDrawingObjectNode *next   = NULL;
01513     phColor             *color  = NULL;
01514     phPoint             *p      = NULL;
01515     phLine              *l      = NULL;
01516     phCircle            *c      = NULL;
01517     phRectangle         *r      = NULL;
01518     phTriangle          *t      = NULL;
01519     phCross             *x      = NULL;
01520     
01521     if ((d == NULL) || 
01522         (s == NULL) || 
01523         (s->p == NULL) ||
01524         /* Check to make sure it is a raw packed format, i.e. not compressed
01525          * or planar */
01526         (!(s->f & phImagePackedFormatMask))) return;
01527 
01528     obj = d->m_obj_ptr;
01529 
01530     while (obj != NULL)
01531     {
01532         color  = obj->color;
01533         switch (obj->type)
01534         {
01535             case phPointType:
01536             {
01537                 /* phPROGRESS("Drawing phPointType\n"); */ 
01538                 p = (phPoint *)obj->object;
01539                 /* phPoint_print(fileno(stdout),*p); */
01540                 ph_draw_point( s, *p, *color, obj->size, obj->transp );
01541             }
01542             break;
01543             case phLineType:
01544             {
01545                 /* phPROGRESS("Drawing phLineType\n"); */ 
01546                 l = (phLine *)obj->object;
01547                 /* phLine_print(fileno(stdout),*l); */
01548                 ph_draw_line( s, *l, *color, obj->size, obj->transp );
01549             }
01550             break;
01551             case phCircleType:
01552             {
01553                 /* phPROGRESS("Drawing phCircleType\n"); */ 
01554                 c = (phCircle *)obj->object;
01555                 /* phCircle_print(fileno(stdout),*c); */
01556                 ph_draw_circle( s, *c, *color, 
01557                                 obj->size, obj->fill, obj->transp );
01558             }
01559             break;
01560             case phRectangleType:
01561             {
01562                 /* phPROGRESS("Drawing phRectangleType\n"); */ 
01563                 r = (phRectangle *)obj->object;
01564                 /* phRectangle_print(fileno(stdout),*r); */
01565                 ph_draw_rectangle( s, *r, *color, 
01566                                    obj->size, obj->fill, obj->transp );
01567             }
01568             break;
01569             case phTriangleType:
01570             {
01571                 /* phPROGRESS("Drawing phTriangleType\n"); */ 
01572                 t = (phTriangle *)obj->object;
01573                 /* phTriangle_print(fileno(stdout),*t); */
01574                 ph_draw_triangle( s, *t, *color, 
01575                                   obj->size, obj->fill, obj->transp );
01576             }
01577             break;
01578             case phCrossType:
01579             {
01580                 /* phPROGRESS("Drawing phCrossType\n"); */ 
01581                 x = (phCross *)obj->object;
01582                 /* phCross_print(fileno(stdout),*x); */
01583                 ph_draw_cross( s, *x, *color, obj->size, obj->transp );
01584             }
01585             break;
01586             default:
01587                 break;
01588         }
01589         next = obj->next;
01590         obj = next;
01591     }
01592 }
01593 
01594 /* ------------------------------------------------------------------------ */
01595 void phDrawing_clear( phDrawing d )
01596 {
01597     if (d == NULL)
01598     {
01599         phPRINT_ERROR("(phDrawing_clear) Invalid parameter: d == NULL\n");
01600         return;
01601     }
01602 
01603     /* if we're clearing the entire drawing, clean the object nodes before
01604      * calling the individual functions so we don't waste time setting
01605      * pointers and stuff */
01606     phDrawing_freeObjectNodes(d);
01607     
01608     phDrawing_clearPoints(d);
01609     phDrawing_clearLines(d);
01610     phDrawing_clearCircles(d);
01611     phDrawing_clearRectangles(d);
01612     phDrawing_clearTriangles(d);
01613     phDrawing_clearCrosses(d);
01614 }
01615 
01616 /* ------------------------------------------------------------------------ */
01617 void phDrawing_clearPoints( phDrawing d )
01618 {
01619     if (d == NULL)
01620     {
01621         phPRINT_ERROR("(phDrawing_clearPoints) Invalid parameter: d == NULL\n");
01622         return;
01623     }
01624     
01625     /* Remove all the nodes of this type from the list */
01626     phDrawing_clearObjectNodeType(d, phPointType );
01627         
01628     d->m_npoints = 0;
01629 }
01630 
01631 /* ------------------------------------------------------------------------ */
01632 void phDrawing_clearLines( phDrawing d )
01633 {
01634     if (d == NULL)
01635     {
01636         phPRINT_ERROR("(phDrawing_clearLines) Invalid parameter: d == NULL\n");
01637         return;
01638     }
01639 
01640     /* Remove all the nodes of this type from the list */
01641     phDrawing_clearObjectNodeType(d, phLineType );
01642     
01643     d->m_nlines = 0;
01644 }
01645 
01646 /* ------------------------------------------------------------------------ */
01647 void phDrawing_clearCircles( phDrawing d )
01648 {
01649     if (d == NULL)
01650     {
01651         phPRINT_ERROR("(phDrawing_clearCircles) Invalid parameter: d == NULL\n");
01652         return;
01653     }
01654     
01655     /* Remove all the nodes of this type from the list */
01656     phDrawing_clearObjectNodeType(d, phCircleType );
01657 
01658     d->m_ncircles = 0;
01659 }
01660 
01661 /* ------------------------------------------------------------------------ */
01662 void phDrawing_clearRectangles( phDrawing d )
01663 {
01664     if (d == NULL)
01665     {
01666         phPRINT_ERROR("(phDrawing_clearRectangles) Invalid parameter: d == NULL\n");
01667         return;
01668     }
01669     
01670     /* Remove all the nodes of this type from the list */
01671     phDrawing_clearObjectNodeType(d, phRectangleType );
01672 
01673     d->m_nrectangles = 0;
01674 }
01675 
01676 /* ------------------------------------------------------------------------ */
01677 void phDrawing_clearTriangles( phDrawing d )
01678 {
01679     if (d == NULL)
01680     {
01681         phPRINT_ERROR("(phDrawing_clearTriangles) Invalid parameter: d == NULL\n");
01682         return;
01683     }
01684 
01685     /* Remove all the nodes of this type from the list */
01686     phDrawing_clearObjectNodeType(d, phTriangleType );
01687     
01688     d->m_ntriangles = 0;
01689 }
01690 
01691 /* ------------------------------------------------------------------------ */
01692 void phDrawing_clearCrosses( phDrawing d )
01693 {
01694     if (d == NULL)
01695     {
01696         phPRINT_ERROR("(phDrawing_clearCrosses) Invalid parameter: d == NULL\n");
01697         return;
01698     }
01699 
01700     /* Remove all the nodes of this type from the list */
01701     phDrawing_clearObjectNodeType(d, phCrossType );
01702     
01703     d->m_ncrosses = 0;
01704 }
01705 
01706 /* ------------------------------------------------------------------------ */
01707 int phDrawing_addPoint( phDrawing d, phPoint p, phColor color,
01708                         uint8_t size, uint8_t transp )
01709 {
01710     phFUNCTION("phDrawing_addPoint")
01711     phPoint *obj        = NULL;
01712     phColor *colorptr   = NULL;
01713 
01714     if (d == NULL)
01715     {
01716         phPRINT_ERROR("(phDrawing_addPoint) Invalid parameter: d == NULL\n");
01717         return phFAIL;
01718     }
01719 
01720     /* phPROGRESS("Adding phPoint\n"); */
01721 
01722     obj = (phPoint *)phMalloc(sizeof(phPoint));
01723     phCHECK_PTR(obj,"phMalloc","Allocating object failed.");
01724     
01725     colorptr = (phColor *)phMalloc(sizeof(phColor));
01726     phCHECK_PTR(colorptr,"phMalloc","Allocating color failed.");
01727 
01728     *obj = p;
01729     *colorptr = color;
01730     
01731     /* This must be here because it looks at the new values for m_npoints, 
01732      * m_points, and m_point_colors when adding the object node */
01733     phDrawing_addObjectNodeType( d, obj, colorptr,
01734                                  phPointType, size, phDrawingNoFill, transp);
01735     
01736     d->m_npoints++;
01737 
01738     return phSUCCESS;
01739 error:
01740     return phFAIL;
01741 }
01742 
01743 /* ------------------------------------------------------------------------ */
01744 int phDrawing_addLine( phDrawing d, phLine l, phColor color,
01745                        uint8_t size, uint8_t transp )
01746 {
01747     phFUNCTION("phDrawing_addLine")
01748     phLine *obj        = NULL;
01749     phColor *colorptr   = NULL;
01750 
01751     if (d == NULL)
01752     {
01753         phPRINT_ERROR("(phDrawing_addLine) Invalid parameter: d == NULL\n");
01754         return phFAIL;
01755     }
01756     
01757     /* phPROGRESS("Adding phLine\n"); */
01758 
01759     obj = (phLine *)phMalloc(sizeof(phLine));
01760     phCHECK_PTR(obj,"phMalloc","Allocating object failed.");
01761     
01762     colorptr = (phColor *)phMalloc(sizeof(phColor));
01763     phCHECK_PTR(colorptr,"phMalloc","Allocating color failed.");
01764 
01765     *obj = l;
01766     *colorptr = color;
01767     
01768     /* This must be here because it looks at the new values for m_nlines, 
01769      * m_lines, and m_line_colors when adding the object node */
01770     phDrawing_addObjectNodeType(d, obj, colorptr,
01771                                 phLineType, size, phDrawingNoFill, transp);
01772     
01773     d->m_nlines++;
01774 
01775     return phSUCCESS;
01776 error:
01777     return phFAIL;
01778 }
01779 
01780 /* ------------------------------------------------------------------------ */
01781 int phDrawing_addCircle( phDrawing d, phCircle c, phColor color,
01782                          uint8_t size, uint8_t fill, uint8_t transp )
01783 {
01784     phFUNCTION("phDrawing_addCircle")
01785     phCircle *obj        = NULL;
01786     phColor *colorptr   = NULL;
01787 
01788     if (d == NULL) 
01789     {
01790         phPRINT_ERROR("(phDrawing_addCircle) Invalid parameter: d == NULL\n");
01791         return phFAIL;
01792     }
01793     
01794     /* phPROGRESS("Adding phCircle\n"); */
01795 
01796     obj = (phCircle *)phMalloc(sizeof(phCircle));
01797     phCHECK_PTR(obj,"phMalloc","Allocating object failed.");
01798     
01799     colorptr = (phColor *)phMalloc(sizeof(phColor));
01800     phCHECK_PTR(colorptr,"phMalloc","Allocating color failed.");
01801 
01802     *obj = c;
01803     *colorptr = color;
01804     
01805     /* This must be here because it looks at the new values for m_ncircles, 
01806      * m_circles, and m_circle_colors when adding the object node */
01807     phDrawing_addObjectNodeType( d, obj, colorptr,
01808                                  phCircleType, size, fill, transp);
01809     
01810     d->m_ncircles++;
01811 
01812     return phSUCCESS;
01813 error:
01814     return phFAIL;
01815 }
01816 
01817 /* ------------------------------------------------------------------------ */
01818 int phDrawing_addRectangle( phDrawing d, phRectangle r, phColor color,
01819                             uint8_t size, uint8_t fill, uint8_t transp )
01820 {
01821     phFUNCTION("phDrawing_addRectangle")
01822     phRectangle *obj        = NULL;
01823     phColor *colorptr   = NULL;
01824 
01825     if (d == NULL)
01826     {
01827         phPRINT_ERROR("(phDrawing_addRectangle) Invalid parameter: d == NULL\n");
01828         return phFAIL;
01829     }
01830     
01831     /* phPROGRESS("Adding phRectangle\n"); */
01832 
01833     obj = (phRectangle *)phMalloc(sizeof(phRectangle));
01834     phCHECK_PTR(obj,"phMalloc","Allocating object failed.");
01835     
01836     colorptr = (phColor *)phMalloc(sizeof(phColor));
01837     phCHECK_PTR(colorptr,"phMalloc","Allocating color failed.");
01838 
01839     *obj = r;
01840     *colorptr = color;
01841     
01842     /* This must be here because it looks at the new values for m_nrectangles, 
01843      * m_rectangles, and m_rectangle_colors when adding the object node */
01844     phDrawing_addObjectNodeType( d, obj, colorptr,
01845                                  phRectangleType, size, fill, transp );
01846     
01847     d->m_nrectangles++;
01848 
01849     return phSUCCESS;
01850 error:
01851     return phFAIL;
01852 }
01853 
01854 /* ------------------------------------------------------------------------ */
01855 int phDrawing_addTriangle( phDrawing d, phTriangle t, phColor color,
01856                            uint8_t size, uint8_t fill, uint8_t transp )
01857 {
01858     phFUNCTION("phDrawing_addTriangle")
01859     phTriangle *obj        = NULL;
01860     phColor *colorptr   = NULL;
01861 
01862     if (d == NULL)
01863     {
01864         phPRINT_ERROR("(phDrawing_addTriangle) Invalid parameter: d == NULL\n");
01865         return phFAIL;
01866     }
01867     
01868     /* phPROGRESS("Adding phTriangle\n"); */
01869 
01870     obj = (phTriangle *)phMalloc(sizeof(phTriangle));
01871     phCHECK_PTR(obj,"phMalloc","Allocating object failed.");
01872     
01873     colorptr = (phColor *)phMalloc(sizeof(phColor));
01874     phCHECK_PTR(colorptr,"phMalloc","Allocating color failed.");
01875 
01876     *obj = t;
01877     *colorptr = color;
01878     
01879     /* This must be here because it looks at the new values for m_ntriangles, 
01880      * m_triangles, and m_triangle_colors when adding the object node */
01881     phDrawing_addObjectNodeType( d, obj, colorptr,
01882                                  phTriangleType, size, fill, transp);
01883     
01884     d->m_ntriangles++;
01885 
01886     return phSUCCESS;
01887 error:
01888     return phFAIL;
01889 }
01890 
01891 /* ------------------------------------------------------------------------ */
01892 int phDrawing_addCross( phDrawing d, phCross x, phColor color,
01893                         uint8_t size, uint8_t transp )
01894 {
01895     phFUNCTION("phDrawing_addCross")
01896     phCross *obj        = NULL;
01897     phColor *colorptr   = NULL;
01898 
01899     if (d == NULL)
01900     {
01901         phPRINT_ERROR("(phDrawing_addCross) Invalid parameter: d == NULL\n");
01902         return phFAIL;
01903     }
01904     
01905     obj = (phCross *)phMalloc(sizeof(phCross));
01906     phCHECK_PTR(obj,"phMalloc","Allocating object failed.");
01907     
01908     colorptr = (phColor *)phMalloc(sizeof(phColor));
01909     phCHECK_PTR(colorptr,"phMalloc","Allocating color failed.");
01910 
01911     *obj = x;
01912     *colorptr = color;
01913     
01914     /* phPROGRESS("Adding phCross\n"); */
01915 
01916     phDrawing_addObjectNodeType( d, obj, colorptr,
01917                                  phCrossType, size, phDrawingNoFill, transp);
01918     
01919     d->m_ncrosses++;
01920 
01921     return phSUCCESS;
01922 error:
01923     return phFAIL;
01924 }
01925 
01926 
01927 
01928 
01929 #ifdef __cplusplus
01930 }
01931 #endif
01932 




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:02 2007 for phission by  doxygen 1.4.4