-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimg2fb.cpp
105 lines (89 loc) · 2.91 KB
/
img2fb.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/*
* img2fb Copyright (C) 2018 Daniel Mehrwald
*
* Display images on the OGST Gaming Kit LCD
*
* This program is free software and comes with ABSOLUTELY NO WARRANTY;
* you can redistribute it and/or modify it under the terms of the
* GNU General Public License as published by the Free Software Foundation;
* either version 3 of the License, or (at your option) any later version.
*
*/
#include <algorithm>
#include <string>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
char* getCmdOption(char ** begin, char ** end, const std::string & option)
{
char ** it = std::find(begin, end, option);
if (it != end && ++it != end) {
return *it;
}
static std::string empty_string("");
return (char*)empty_string.c_str();
}
bool cmdOptionExists(char** begin, char** end, const std::string& option)
{
return std::find(begin, end, option) != end;
}
int main(int argc, char *argv[])
{
int fd;
SDL_Rect dest = {0};
const char *opt = NULL;
std::string filename = "";
uint32_t rmask = 0x0000f800, gmask = 0x000007e0, bmask = 0x0000001f, amask = 0x00000000;
if(opt = getCmdOption(argv, argv+argc, "-i")) {
filename = std::string(opt);
}
if(cmdOptionExists(argv, argv+argc, "-h") || cmdOptionExists(argv, argv+argc, "-help") || argc < 2 || filename.empty()) {
fprintf(stderr, "Usage: %s [-i] <file> [-d]\n\t[-i] <file> valid image file types are JPG, PNG, TIF, WEBP\n\t[-d] disable aspect ratio\n", argv[0]);
exit(EXIT_FAILURE);
}
if ((fd = open("/dev/fb1", O_RDWR)) < 0) {
perror("can't open device");
abort();
}
SDL_Surface *image = IMG_Load(filename.c_str());
if(image == NULL) {
fprintf(stderr, "Can't open file\n");
exit(EXIT_FAILURE);
}
SDL_Surface *rgb565_surface = SDL_CreateRGBSurface(0, image->w, image->h, 16, rmask, gmask, bmask, amask);
SDL_Surface *surface = SDL_CreateRGBSurface(0, 320, 240, 16, rmask, gmask, bmask, amask);
if(!cmdOptionExists(argv, argv+argc, "-d")) {
dest.w = surface->w;
dest.h = (int)(float)image->h / (float)image->w * 320;
if(image->w < image->h) {
dest.w = (int)(float)image->w / (float)image->h * 320;
}
dest.x = (320 - dest.w) / 2;
dest.y = (240 - dest.h) / 2;
SDL_BlitSurface(image, NULL, rgb565_surface, NULL);
SDL_BlitScaled(rgb565_surface, NULL, surface, &dest);
} else {
SDL_BlitSurface(image, NULL, rgb565_surface, NULL);
SDL_BlitScaled(rgb565_surface, NULL, surface, NULL);
}
int pitch = surface->pitch;
int pxlength = pitch * surface->h;
unsigned char * pixels = (unsigned char*)surface->pixels;
uint8_t *fbp = (uint8_t*)mmap(0, pxlength, PROT_READ | PROT_WRITE, MAP_SHARED, fd, (off_t)0);
for (int it = 0; it < pxlength; it++) {
fbp[it] = pixels[it];
}
close(fd);
SDL_FreeSurface(image);
SDL_FreeSurface(rgb565_surface);
SDL_FreeSurface(surface);
IMG_Quit();
return 0;
}