gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
gl2yuv.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 /*
7  * This code is based on the rgbtoycc.c code from the MPEG-1 Video
8  * Software Encoder (Version 1.5; February 1, 1995), by Lawrence
9  * A. Rowe, Kevin Gong, Eugene Hung, Ketan Patel, Steve Smoot and Dan
10  * Wallach Computer Science Division-EECS, Univ. of Calif. at Berkeley
11  *
12  * Copyright (c) 1995 The Regents of the University of California.
13  * All rights reserved.
14  *
15  * Permission to use, copy, modify, and distribute this software and its
16  * documentation for any purpose, without fee, and without written agreement is
17  * hereby granted, provided that the above copyright notice and the following
18  * two paragraphs appear in all copies of this software.
19  *
20  * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
21  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
22  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
23  * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
26  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
27  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
28  * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
29  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
30  */
31 
32 #include "MallocUtils.h"
33 #include "gl2yuv.h"
34 
35 void create_yuv(FILE *outfile, PixelBuffer *buffer)
36 {
37  if(buffer->getFormat() != GL_RGB || buffer->getType() != GL_UNSIGNED_BYTE) {
38  Msg::Error("YUV only implemented for GL_RGB and GL_UNSIGNED_BYTE");
39  return;
40  }
41 
42  int x, y;
43  unsigned char *dy0, *dy1;
44  unsigned char *dcr, *dcb;
45  unsigned char *src0, *src1;
46  int cdivisor;
47 
48  static int first = 1;
49  static float mult299[1024], mult587[1024], mult114[1024];
50  static float mult16874[1024], mult33126[1024], mult5[1024];
51  static float mult41869[1024], mult08131[1024];
52 
53  unsigned char **orig_y, **orig_cr, **orig_cb;
54 
55  if(first) {
56  int index;
57  int maxValue;
58 
59  maxValue = 255;
60 
61  for(index = 0; index <= maxValue; index++) {
62  mult299[index] = index * 0.29900F;
63  mult587[index] = index * 0.58700F;
64  mult114[index] = index * 0.11400F;
65  mult16874[index] = -0.16874F * index;
66  mult33126[index] = -0.33126F * index;
67  mult5[index] = index * 0.50000F;
68  mult41869[index] = -0.41869F * index;
69  mult08131[index] = -0.08131F * index;
70  }
71 
72  first = 0;
73  }
74 
75  int width = buffer->getWidth();
76  int height = buffer->getHeight();
77  unsigned char *pixels = (unsigned char *)buffer->getPixels();
78 
79  // yuv format assumes even number of rows and columns
80  height -= height % 2;
81  width -= width % 2;
82 
83  int row_stride = width * 3;
84 
85  orig_y = (unsigned char **)Malloc(sizeof(unsigned char *) * height);
86  for(y = 0; y < height; y++) {
87  orig_y[y] = (unsigned char *)Malloc(sizeof(unsigned char) * width);
88  }
89 
90  orig_cr = (unsigned char **)Malloc(sizeof(char *) * height / 2);
91  for(y = 0; y < height / 2; y++) {
92  orig_cr[y] = (unsigned char *)Malloc(sizeof(char) * width / 2);
93  }
94 
95  orig_cb = (unsigned char **)Malloc(sizeof(char *) * height / 2);
96  for(y = 0; y < height / 2; y++) {
97  orig_cb[y] = (unsigned char *)Malloc(sizeof(char) * width / 2);
98  }
99 
100  // assume ydivisor = 1, so cdivisor = 4
101  cdivisor = 4;
102 
103  for(y = 0; y < height; y += 2) {
104  src0 = &(pixels[y * row_stride]);
105  src1 = &(pixels[(y + 1) * row_stride]);
106  dy0 = orig_y[y];
107  dy1 = orig_y[y + 1];
108  dcr = orig_cr[y / 2];
109  dcb = orig_cb[y / 2];
110 
111  for(x = 0; x < width;
112  x += 2, dy0 += 2, dy1 += 2, dcr++, dcb++, src0 += 6, src1 += 6) {
113  *dy0 =
114  (unsigned char)(mult299[*src0] + mult587[src0[1]] + mult114[src0[2]]);
115 
116  *dy1 =
117  (unsigned char)(mult299[*src1] + mult587[src1[1]] + mult114[src1[2]]);
118 
119  dy0[1] =
120  (unsigned char)(mult299[src0[3]] + mult587[src0[4]] + mult114[src0[5]]);
121 
122  dy1[1] =
123  (unsigned char)(mult299[src1[3]] + mult587[src1[4]] + mult114[src1[5]]);
124 
125  *dcb = (unsigned char)((mult16874[*src0] + mult33126[src0[1]] +
126  mult5[src0[2]] + mult16874[*src1] +
127  mult33126[src1[1]] + mult5[src1[2]] +
128  mult16874[src0[3]] + mult33126[src0[4]] +
129  mult5[src0[5]] + mult16874[src1[3]] +
130  mult33126[src1[4]] + mult5[src1[5]]) /
131  cdivisor) +
132  128;
133 
134  *dcr = (unsigned char)((mult5[*src0] + mult41869[src0[1]] +
135  mult08131[src0[2]] + mult5[*src1] +
136  mult41869[src1[1]] + mult08131[src1[2]] +
137  mult5[src0[3]] + mult41869[src0[4]] +
138  mult08131[src0[5]] + mult5[src1[3]] +
139  mult41869[src1[4]] + mult08131[src1[5]]) /
140  cdivisor) +
141  128;
142  }
143  }
144 
145  // Y
146  for(y = height - 1; y >= 0; y--) fwrite(orig_y[y], 1, width, outfile);
147 
148  // U
149  for(y = height / 2 - 1; y >= 0; y--)
150  fwrite(orig_cb[y], 1, width / 2, outfile);
151 
152  // V
153  for(y = height / 2 - 1; y >= 0; y--)
154  fwrite(orig_cr[y], 1, width / 2, outfile);
155 
156  for(y = 0; y < height; y++) Free(orig_y[y]);
157  Free(orig_y);
158 
159  for(y = 0; y < height / 2; y++) Free(orig_cr[y]);
160  Free(orig_cr);
161 
162  for(y = 0; y < height / 2; y++) Free(orig_cb[y]);
163  Free(orig_cb);
164 }
PixelBuffer::getHeight
int getHeight()
Definition: PixelBuffer.h:71
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
PixelBuffer::getFormat
GLenum getFormat()
Definition: PixelBuffer.h:74
PixelBuffer::getType
GLenum getType()
Definition: PixelBuffer.h:75
Free
void Free(void *ptr)
Definition: MallocUtils.cpp:40
PixelBuffer::getPixels
void * getPixels()
Definition: PixelBuffer.h:76
create_yuv
void create_yuv(FILE *outfile, PixelBuffer *buffer)
Definition: gl2yuv.cpp:35
PixelBuffer::getWidth
int getWidth()
Definition: PixelBuffer.h:70
Malloc
void * Malloc(size_t size)
Definition: MallocUtils.cpp:12
PixelBuffer
Definition: PixelBuffer.h:32
gl2yuv.h
MallocUtils.h