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


[ 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.