The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/fb/splash_pcx.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * Copyright (c) 1999 Michael Smith <msmith@freebsd.org>
    3  * Copyright (c) 1999 Kazutaka YOKOTA <yokota@freebsd.org>
    4  * Copyright (c) 1999 Dag-Erling Coïdan Smørgrav
    5  * All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer
   12  *    in this position and unchanged.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  * 3. The name of the author may not be used to endorse or promote products
   17  *    derived from this software without specific prior written permission
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   29  *
   30  * $FreeBSD: releng/11.1/sys/dev/fb/splash_pcx.c 230132 2012-01-15 13:23:18Z uqs $
   31  */
   32 
   33 #include <sys/param.h>
   34 #include <sys/systm.h>
   35 #include <sys/kernel.h>
   36 #include <sys/linker.h>
   37 #include <sys/module.h>
   38 #include <sys/fbio.h>
   39 
   40 #include <dev/fb/fbreg.h>
   41 #include <dev/fb/splashreg.h>
   42 
   43 static int splash_mode = -1;
   44 static int splash_on = FALSE;
   45 
   46 static int pcx_start(video_adapter_t *adp);
   47 static int pcx_end(video_adapter_t *adp);
   48 static int pcx_splash(video_adapter_t *adp, int on);
   49 static int pcx_init(void *data, int sdepth);
   50 static int pcx_draw(video_adapter_t *adp);
   51 
   52 static splash_decoder_t pcx_decoder = {
   53         .name = "splash_pcx",
   54         .init = pcx_start,
   55         .term = pcx_end,
   56         .splash = pcx_splash,
   57         .data_type = SPLASH_IMAGE,
   58 };
   59 
   60 SPLASH_DECODER(splash_pcx, pcx_decoder);
   61 
   62 static struct {
   63         int              width;
   64         int              height;
   65         int              bpsl;
   66         int              bpp;
   67         int              planes;
   68         int              zlen;
   69         const uint8_t   *zdata;
   70         uint8_t         *palette;
   71 } pcx_info;
   72 
   73 static int
   74 pcx_start(video_adapter_t *adp)
   75 {
   76         static int modes[] = {
   77                 M_VGA_CG320,
   78                 M_VESA_CG640x480,
   79                 M_VESA_CG800x600,
   80                 M_VESA_CG1024x768,
   81                 -1,
   82         };
   83         video_info_t info;
   84         int i;
   85 
   86         if (pcx_decoder.data == NULL ||
   87             pcx_decoder.data_size <= 0 ||
   88             pcx_init(pcx_decoder.data, pcx_decoder.data_size))
   89                 return (ENODEV);
   90 
   91         if (bootverbose)
   92                 printf("splash_pcx: image good:\n"
   93                     "  width = %d\n"
   94                     "  height = %d\n"
   95                     "  depth = %d\n"
   96                     "  planes = %d\n",
   97                     pcx_info.width, pcx_info.height,
   98                     pcx_info.bpp, pcx_info.planes);
   99 
  100         for (i = 0; modes[i] >= 0; ++i) {
  101                 if (vidd_get_info(adp, modes[i], &info) != 0)
  102                         continue;
  103                 if (bootverbose)
  104                         printf("splash_pcx: considering mode %d:\n"
  105                             "  vi_width = %d\n"
  106                             "  vi_height = %d\n"
  107                             "  vi_depth = %d\n"
  108                             "  vi_planes = %d\n",
  109                             modes[i],
  110                             info.vi_width, info.vi_height,
  111                             info.vi_depth, info.vi_planes);
  112                 if (info.vi_width >= pcx_info.width
  113                     && info.vi_height >= pcx_info.height
  114                     && info.vi_depth == pcx_info.bpp
  115                     && info.vi_planes == pcx_info.planes)
  116                         break;
  117         }
  118 
  119         splash_mode = modes[i];
  120         if (splash_mode == -1)
  121                 return (ENODEV);
  122         if (bootverbose)
  123                 printf("splash_pcx: selecting mode %d\n", splash_mode);
  124         return (0);
  125 }
  126 
  127 static int
  128 pcx_end(video_adapter_t *adp)
  129 {
  130         /* nothing to do */
  131         return (0);
  132 }
  133 
  134 static int
  135 pcx_splash(video_adapter_t *adp, int on)
  136 {
  137         if (on) {
  138                 if (!splash_on) {
  139                         if (vidd_set_mode(adp, splash_mode) || pcx_draw(adp))
  140                                 return 1;
  141                         splash_on = TRUE;
  142                 }
  143                 return (0);
  144         } else {
  145                 splash_on = FALSE;
  146                 return (0);
  147         }
  148 }
  149 
  150 struct pcx_header {
  151         uint8_t          manufactor;
  152         uint8_t          version;
  153         uint8_t          encoding;
  154         uint8_t          bpp;
  155         uint16_t         xmin;
  156         uint16_t         ymin;
  157         uint16_t         xmax;
  158         uint16_t         ymax;
  159         uint16_t         hres;
  160         uint16_t         vres;
  161         uint8_t          colormap[48];
  162         uint8_t          rsvd;
  163         uint8_t          nplanes;
  164         uint16_t         bpsl;
  165         uint16_t         palinfo;
  166         uint16_t         hsize;
  167         uint16_t         vsize;
  168 };
  169 
  170 #define MAXSCANLINE 1024
  171 
  172 static int
  173 pcx_init(void *data, int size)
  174 {
  175         const struct pcx_header *hdr = data;
  176 
  177         if (size < 128 + 1 + 1 + 768 ||
  178             hdr->manufactor != 10 ||
  179             hdr->version != 5 ||
  180             hdr->encoding != 1 ||
  181             hdr->nplanes != 1 ||
  182             hdr->bpp != 8 ||
  183             hdr->bpsl > MAXSCANLINE ||
  184             ((uint8_t *)data)[size - 769] != 12) {
  185                 printf("splash_pcx: invalid PCX image\n");
  186                 return (1);
  187         }
  188         pcx_info.width = hdr->xmax - hdr->xmin + 1;
  189         pcx_info.height = hdr->ymax - hdr->ymin + 1;
  190         pcx_info.bpsl = hdr->bpsl;
  191         pcx_info.bpp = hdr->bpp;
  192         pcx_info.planes = hdr->nplanes;
  193         pcx_info.zlen = size - (128 + 1 + 768);
  194         pcx_info.zdata = (uint8_t *)data + 128;
  195         pcx_info.palette = (uint8_t *)data + size - 768;
  196         return (0);
  197 }
  198 
  199 static int
  200 pcx_draw(video_adapter_t *adp)
  201 {
  202         uint8_t *vidmem;
  203         int swidth, sheight, sbpsl, sdepth, splanes;
  204         int banksize, origin;
  205         int c, i, j, pos, scan, x, y;
  206         uint8_t line[MAXSCANLINE];
  207 
  208         if (pcx_info.zlen < 1)
  209                 return (1);
  210 
  211         vidd_load_palette(adp, pcx_info.palette);
  212 
  213         vidmem = (uint8_t *)adp->va_window;
  214         swidth = adp->va_info.vi_width;
  215         sheight = adp->va_info.vi_height;
  216         sbpsl = adp->va_line_width;
  217         sdepth = adp->va_info.vi_depth;
  218         splanes = adp->va_info.vi_planes;
  219         banksize = adp->va_window_size;
  220 
  221         for (origin = 0; origin < sheight*sbpsl; origin += banksize) {
  222                 vidd_set_win_org(adp, origin);
  223                 bzero(vidmem, banksize);
  224         }
  225 
  226         x = (swidth - pcx_info.width) / 2;
  227         y = (sheight - pcx_info.height) / 2;
  228         origin = 0;
  229         pos = y * sbpsl + x;
  230         while (pos > banksize) {
  231                 pos -= banksize;
  232                 origin += banksize;
  233         }
  234         vidd_set_win_org(adp, origin);
  235 
  236         for (scan = i = 0; scan < pcx_info.height; ++scan, ++y, pos += sbpsl) {
  237                 for (j = 0; j < pcx_info.bpsl && i < pcx_info.zlen; ++i) {
  238                         if ((pcx_info.zdata[i] & 0xc0) == 0xc0) {
  239                                 c = pcx_info.zdata[i++] & 0x3f;
  240                                 if (i >= pcx_info.zlen)
  241                                         return (1);
  242                         } else {
  243                                 c = 1;
  244                         }
  245                         if (j + c > pcx_info.bpsl)
  246                                 return (1);
  247                         while (c--)
  248                                 line[j++] = pcx_info.zdata[i];
  249                 }
  250 
  251                 if (pos > banksize) {
  252                         origin += banksize;
  253                         pos -= banksize;
  254                         vidd_set_win_org(adp, origin);
  255                 }
  256 
  257                 if (pos + pcx_info.width > banksize) {
  258                         /* scanline crosses bank boundary */
  259                         j = banksize - pos;
  260                         bcopy(line, vidmem + pos, j);
  261                         origin += banksize;
  262                         pos -= banksize;
  263                         vidd_set_win_org(adp, origin);
  264                         bcopy(line + j, vidmem, pcx_info.width - j);
  265                 } else {
  266                         bcopy(line, vidmem + pos, pcx_info.width);
  267                 }
  268         }
  269 
  270         return (0);
  271 }

Cache object: dd851f83b8704c089a3e9eea31ac023d


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.