1 /*
2     Musical Spectrum plugin for the DeaDBeeF audio player
3 
4     Copyright (C) 2015 Christian Boxdörfer <christian.boxdoerfer@posteo.de>
5 
6     Based on DeaDBeeFs stock spectrum.
7     Copyright (c) 2009-2015 Alexey Yakovenko <waker@users.sourceforge.net>
8     Copyright (c) 2011 William Pitcock <nenolod@dereferenced.org>
9 
10     This program is free software; you can redistribute it and/or
11     modify it under the terms of the GNU General Public License
12     as published by the Free Software Foundation; either version 2
13     of the License, or (at your option) any later version.
14 
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
19 
20     You should have received a copy of the GNU General Public License
21     along with this program; if not, write to the Free Software
22     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
23 */
24 
25 #include <sys/types.h>
26 #include <stdlib.h>
27 #include <assert.h>
28 #include <math.h>
29 #include <fcntl.h>
30 #include <gtk/gtk.h>
31 
32 #include "fastftoi.h"
33 #include "draw_utils.h"
34 #include "spectrum.h"
35 #include "utils.h"
36 
37 void
_draw_vline(uint8_t * data,int stride,int x0,int y0,int y1,uint32_t color)38 _draw_vline (uint8_t *data, int stride, int x0, int y0, int y1, uint32_t color) {
39     if (y0 > y1) {
40         int tmp = y0;
41         y0 = y1;
42         y1 = tmp;
43         y1--;
44     }
45     else if (y0 < y1) {
46         y0++;
47     }
48     uint32_t *ptr = (uint32_t*)&data[y0*stride+x0*4];
49     int line_size = stride/4;
50     while (y0 <= y1) {
51         *ptr = color;
52         ptr += line_size;
53         y0++;
54     }
55 }
56 
57 void
_draw_hline(uint8_t * data,int stride,int x0,int y0,int x1,uint32_t color)58 _draw_hline (uint8_t *data, int stride, int x0, int y0, int x1, uint32_t color) {
59     uint32_t *ptr = (uint32_t*)&data[y0*stride+x0*4];
60     while (x0 <= x1) {
61         *ptr++ = color;
62         x0++;
63     }
64 }
65 
66 void
_draw_background(uint8_t * data,int w,int h,uint32_t color)67 _draw_background (uint8_t *data, int w, int h, uint32_t color)
68 {
69     //uint32_t *ptr = (uint32_t*)&data[0];
70     //int i = 0;
71     //int size = w * h;
72     //while (i++ < size) {
73     //    *ptr++ = color;
74     //}
75     size_t fillLen = w * h * sizeof (uint32_t);
76     _memset_pattern ((char *)data, &color, fillLen, sizeof (uint32_t));
77 }
78 
79 void
_draw_bar(uint8_t * data,int stride,int x0,int y0,int w,int h,uint32_t color)80 _draw_bar (uint8_t *data, int stride, int x0, int y0, int w, int h, uint32_t color) {
81     int y1 = y0+h-1;
82     int x1 = x0+w-1;
83     uint32_t *ptr = (uint32_t*)&data[y0*stride+x0*4];
84     while (y0 <= y1) {
85         int x = x0;
86         while (x++ <= x1) {
87             *ptr++ = color;
88         }
89         y0++;
90         ptr += stride/4-w;
91     }
92 }
93 
94 void
_draw_bar_gradient_v(uint32_t * colors,uint8_t * data,int stride,int x0,int y0,int w,int h,int total_h)95 _draw_bar_gradient_v (uint32_t *colors, uint8_t *data, int stride, int x0, int y0, int w, int h, int total_h) {
96     int y1 = y0+h-1;
97     int x1 = x0+w-1;
98     uint32_t *ptr = (uint32_t*)&data[y0*stride+x0*4];
99     while (y0 <= y1) {
100         int x = x0;
101         int index = ftoi(((double)y0/(double)total_h) * (GRADIENT_TABLE_SIZE - 1));
102         index = CLAMP (index, 0, GRADIENT_TABLE_SIZE - 1);
103         while (x++ <= x1) {
104             *ptr++ = colors[index];
105         }
106         y0++;
107         ptr += stride/4-w;
108     }
109 }
110 
111 void
_draw_bar_gradient_h(uint32_t * colors,uint8_t * data,int stride,int x0,int y0,int w,int h,int total_w)112 _draw_bar_gradient_h (uint32_t *colors, uint8_t *data, int stride, int x0, int y0, int w, int h, int total_w) {
113     int y1 = y0+h-1;
114     int x1 = x0+w-1;
115     uint32_t *ptr = (uint32_t*)&data[y0*stride+x0*4];
116     while (y0 <= y1) {
117         int x = x0;
118         while (x++ <= x1) {
119             int index = ftoi(((double)x/(double)total_w) * (GRADIENT_TABLE_SIZE - 1));
120             index = CLAMP (index, 0, GRADIENT_TABLE_SIZE - 1);
121             *ptr++ = colors[index];
122         }
123         y0++;
124         ptr += stride/4-w;
125     }
126 }
127 
128 void
_draw_bar_gradient_bar_mode_v(uint32_t * colors,uint8_t * data,int stride,int x0,int y0,int w,int h,int total_h)129 _draw_bar_gradient_bar_mode_v (uint32_t *colors, uint8_t *data, int stride, int x0, int y0, int w, int h, int total_h) {
130     int y1 = y0+h-1;
131     int x1 = x0+w-1;
132     y0 -= y0 % 2;
133     uint32_t *ptr = (uint32_t*)&data[y0*stride+x0*4];
134     while (y0 <= y1) {
135         int x = x0;
136         int index = ftoi(((double)y0/(double)total_h) * (GRADIENT_TABLE_SIZE - 1));
137         index = CLAMP (index, 0, GRADIENT_TABLE_SIZE - 1);
138         while (x++ <= x1) {
139             *ptr++ = colors[index];
140         }
141         y0 += 2;
142         ptr += stride/2-w;
143     }
144 }
145 
146 void
_draw_bar_gradient_bar_mode_h(uint32_t * colors,uint8_t * data,int stride,int x0,int y0,int w,int h,int total_w)147 _draw_bar_gradient_bar_mode_h (uint32_t *colors, uint8_t *data, int stride, int x0, int y0, int w, int h, int total_w) {
148     int y1 = y0+h-1;
149     int x1 = x0+w-1;
150     y0 -= y0 % 2;
151     uint32_t *ptr = (uint32_t*)&data[y0*stride+x0*4];
152     while (y0 <= y1) {
153         int x = x0;
154         while (x++ <= x1) {
155             int index = ftoi(((double)x/(double)total_w) * (GRADIENT_TABLE_SIZE - 1));
156             index = CLAMP (index, 0, GRADIENT_TABLE_SIZE - 1);
157             *ptr++ = colors[index];
158         }
159         y0 += 2;
160         ptr += stride/2-w;
161     }
162 }
163 
164