⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 phpthumb.bmp.php

📁 是一款免费的轻量级论坛软件
💻 PHP
📖 第 1 页 / 共 3 页
字号:
				// DWORD        bV5ProfileData;
				// DWORD        bV5ProfileSize;
				// DWORD        bV5Reserved;
				$thisfile_bmp_header_raw['intent']              = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
				$offset += 4;
				$thisfile_bmp_header_raw['profile_data_offset'] = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
				$offset += 4;
				$thisfile_bmp_header_raw['profile_data_size']   = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
				$offset += 4;
				$thisfile_bmp_header_raw['reserved3']           = $this->LittleEndian2Int(substr($BMPheader, $offset, 4));
				$offset += 4;
			}

		} else {

			$ThisFileInfo['error'][] = 'Unknown BMP format in header.';
			return false;

		}

		if ($ExtractPalette || $ExtractData) {
			$PaletteEntries = 0;
			if ($thisfile_bmp_header_raw['bits_per_pixel'] < 16) {
				$PaletteEntries = pow(2, $thisfile_bmp_header_raw['bits_per_pixel']);
			} elseif (isset($thisfile_bmp_header_raw['colors_used']) && ($thisfile_bmp_header_raw['colors_used'] > 0) && ($thisfile_bmp_header_raw['colors_used'] <= 256)) {
				$PaletteEntries = $thisfile_bmp_header_raw['colors_used'];
			}
			if ($PaletteEntries > 0) {
				$BMPpalette = substr($BMPdata, $overalloffset, 4 * $PaletteEntries);
				$overalloffset += 4 * $PaletteEntries;

				$paletteoffset = 0;
				for ($i = 0; $i < $PaletteEntries; $i++) {
					// RGBQUAD          - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_5f8y.asp
					// BYTE    rgbBlue;
					// BYTE    rgbGreen;
					// BYTE    rgbRed;
					// BYTE    rgbReserved;
					$blue  = $this->LittleEndian2Int(substr($BMPpalette, $paletteoffset++, 1));
					$green = $this->LittleEndian2Int(substr($BMPpalette, $paletteoffset++, 1));
					$red   = $this->LittleEndian2Int(substr($BMPpalette, $paletteoffset++, 1));
					if (($thisfile_bmp['type_os'] == 'OS/2') && ($thisfile_bmp['type_version'] == 1)) {
						// no padding byte
					} else {
						$paletteoffset++; // padding byte
					}
					$thisfile_bmp['palette'][$i] = (($red << 16) | ($green << 8) | ($blue));
				}
			}
		}

		if ($ExtractData) {
			$RowByteLength = ceil(($thisfile_bmp_header_raw['width'] * ($thisfile_bmp_header_raw['bits_per_pixel'] / 8)) / 4) * 4; // round up to nearest DWORD boundry

			$BMPpixelData = substr($BMPdata, $thisfile_bmp_header_raw['data_offset'], $thisfile_bmp_header_raw['height'] * $RowByteLength);
			$overalloffset = $thisfile_bmp_header_raw['data_offset'] + ($thisfile_bmp_header_raw['height'] * $RowByteLength);

			$pixeldataoffset = 0;
			switch (@$thisfile_bmp_header_raw['compression']) {

				case 0: // BI_RGB
					switch ($thisfile_bmp_header_raw['bits_per_pixel']) {
						case 1:
							for ($row = ($thisfile_bmp_header_raw['height'] - 1); $row >= 0; $row--) {
								for ($col = 0; $col < $thisfile_bmp_header_raw['width']; $col = $col) {
									$paletteindexbyte = ord($BMPpixelData{$pixeldataoffset++});
									for ($i = 7; $i >= 0; $i--) {
										$paletteindex = ($paletteindexbyte & (0x01 << $i)) >> $i;
										$thisfile_bmp['data'][$row][$col] = $thisfile_bmp['palette'][$paletteindex];
										$col++;
									}
								}
								while (($pixeldataoffset % 4) != 0) {
									// lines are padded to nearest DWORD
									$pixeldataoffset++;
								}
							}
							break;

						case 4:
							for ($row = ($thisfile_bmp_header_raw['height'] - 1); $row >= 0; $row--) {
								for ($col = 0; $col < $thisfile_bmp_header_raw['width']; $col = $col) {
									$paletteindexbyte = ord($BMPpixelData{$pixeldataoffset++});
									for ($i = 1; $i >= 0; $i--) {
										$paletteindex = ($paletteindexbyte & (0x0F << (4 * $i))) >> (4 * $i);
										$thisfile_bmp['data'][$row][$col] = $thisfile_bmp['palette'][$paletteindex];
										$col++;
									}
								}
								while (($pixeldataoffset % 4) != 0) {
									// lines are padded to nearest DWORD
									$pixeldataoffset++;
								}
							}
							break;

						case 8:
							for ($row = ($thisfile_bmp_header_raw['height'] - 1); $row >= 0; $row--) {
								for ($col = 0; $col < $thisfile_bmp_header_raw['width']; $col++) {
									$paletteindex = ord($BMPpixelData{$pixeldataoffset++});
									$thisfile_bmp['data'][$row][$col] = $thisfile_bmp['palette'][$paletteindex];
								}
								while (($pixeldataoffset % 4) != 0) {
									// lines are padded to nearest DWORD
									$pixeldataoffset++;
								}
							}
							break;

						case 24:
							for ($row = ($thisfile_bmp_header_raw['height'] - 1); $row >= 0; $row--) {
								for ($col = 0; $col < $thisfile_bmp_header_raw['width']; $col++) {
									$thisfile_bmp['data'][$row][$col] = (ord($BMPpixelData{$pixeldataoffset+2}) << 16) | (ord($BMPpixelData{$pixeldataoffset+1}) << 8) | ord($BMPpixelData{$pixeldataoffset});
									$pixeldataoffset += 3;
								}
								while (($pixeldataoffset % 4) != 0) {
									// lines are padded to nearest DWORD
									$pixeldataoffset++;
								}
							}
							break;

						case 32:
							for ($row = ($thisfile_bmp_header_raw['height'] - 1); $row >= 0; $row--) {
								for ($col = 0; $col < $thisfile_bmp_header_raw['width']; $col++) {
									$thisfile_bmp['data'][$row][$col] = (ord($BMPpixelData{$pixeldataoffset+3}) << 24) | (ord($BMPpixelData{$pixeldataoffset+2}) << 16) | (ord($BMPpixelData{$pixeldataoffset+1}) << 8) | ord($BMPpixelData{$pixeldataoffset});
									$pixeldataoffset += 4;
								}
								while (($pixeldataoffset % 4) != 0) {
									// lines are padded to nearest DWORD
									$pixeldataoffset++;
								}
							}
							break;

						case 16:
							// ?
							break;

						default:
							$ThisFileInfo['error'][] = 'Unknown bits-per-pixel value ('.$thisfile_bmp_header_raw['bits_per_pixel'].') - cannot read pixel data';
							break;
					}
					break;


				case 1: // BI_RLE8 - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_6x0u.asp
					switch ($thisfile_bmp_header_raw['bits_per_pixel']) {
						case 8:
							$pixelcounter = 0;
							while ($pixeldataoffset < strlen($BMPpixelData)) {
								$firstbyte  = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
								$secondbyte = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
								if ($firstbyte == 0) {

									// escaped/absolute mode - the first byte of the pair can be set to zero to
									// indicate an escape character that denotes the end of a line, the end of
									// a bitmap, or a delta, depending on the value of the second byte.
									switch ($secondbyte) {
										case 0:
											// end of line
											// no need for special processing, just ignore
											break;

										case 1:
											// end of bitmap
											$pixeldataoffset = strlen($BMPpixelData); // force to exit loop just in case
											break;

										case 2:
											// delta - The 2 bytes following the escape contain unsigned values
											// indicating the horizontal and vertical offsets of the next pixel
											// from the current position.
											$colincrement = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
											$rowincrement = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
											$col = ($pixelcounter % $thisfile_bmp_header_raw['width']) + $colincrement;
											$row = ($thisfile_bmp_header_raw['height'] - 1 - (($pixelcounter - $col) / $thisfile_bmp_header_raw['width'])) - $rowincrement;
											$pixelcounter = ($row * $thisfile_bmp_header_raw['width']) + $col;
											break;

										default:
											// In absolute mode, the first byte is zero and the second byte is a
											// value in the range 03H through FFH. The second byte represents the
											// number of bytes that follow, each of which contains the color index
											// of a single pixel. Each run must be aligned on a word boundary.
											for ($i = 0; $i < $secondbyte; $i++) {
												$paletteindex = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
												$col = $pixelcounter % $thisfile_bmp_header_raw['width'];
												$row = $thisfile_bmp_header_raw['height'] - 1 - (($pixelcounter - $col) / $thisfile_bmp_header_raw['width']);
												$thisfile_bmp['data'][$row][$col] = $thisfile_bmp['palette'][$paletteindex];
												$pixelcounter++;
											}
											while (($pixeldataoffset % 2) != 0) {
												// Each run must be aligned on a word boundary.
												$pixeldataoffset++;
											}
											break;
									}

								} else {

									// encoded mode - the first byte specifies the number of consecutive pixels
									// to be drawn using the color index contained in the second byte.
									for ($i = 0; $i < $firstbyte; $i++) {
										$col = $pixelcounter % $thisfile_bmp_header_raw['width'];
										$row = $thisfile_bmp_header_raw['height'] - 1 - (($pixelcounter - $col) / $thisfile_bmp_header_raw['width']);
										$thisfile_bmp['data'][$row][$col] = $thisfile_bmp['palette'][$secondbyte];
										$pixelcounter++;
									}

								}
							}
							break;

						default:
							$ThisFileInfo['error'][] = 'Unknown bits-per-pixel value ('.$thisfile_bmp_header_raw['bits_per_pixel'].') - cannot read pixel data';
							break;
					}
					break;



				case 2: // BI_RLE4 - http://msdn.microsoft.com/library/en-us/gdi/bitmaps_6x0u.asp
					switch ($thisfile_bmp_header_raw['bits_per_pixel']) {
						case 4:
							$pixelcounter = 0;
							while ($pixeldataoffset < strlen($BMPpixelData)) {
								$firstbyte  = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
								$secondbyte = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
								if ($firstbyte == 0) {

									// escaped/absolute mode - the first byte of the pair can be set to zero to
									// indicate an escape character that denotes the end of a line, the end of
									// a bitmap, or a delta, depending on the value of the second byte.
									switch ($secondbyte) {
										case 0:
											// end of line
											// no need for special processing, just ignore
											break;

										case 1:
											// end of bitmap
											$pixeldataoffset = strlen($BMPpixelData); // force to exit loop just in case
											break;

										case 2:
											// delta - The 2 bytes following the escape contain unsigned values
											// indicating the horizontal and vertical offsets of the next pixel
											// from the current position.
											$colincrement = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
											$rowincrement = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
											$col = ($pixelcounter % $thisfile_bmp_header_raw['width']) + $colincrement;
											$row = ($thisfile_bmp_header_raw['height'] - 1 - (($pixelcounter - $col) / $thisfile_bmp_header_raw['width'])) - $rowincrement;
											$pixelcounter = ($row * $thisfile_bmp_header_raw['width']) + $col;
											break;

										default:
											// In absolute mode, the first byte is zero. The second byte contains the number
											// of color indexes that follow. Subsequent bytes contain color indexes in their
											// high- and low-order 4 bits, one color index for each pixel. In absolute mode,
											// each run must be aligned on a word boundary.
											unset($paletteindexes);
											for ($i = 0; $i < ceil($secondbyte / 2); $i++) {
												$paletteindexbyte = $this->LittleEndian2Int(substr($BMPpixelData, $pixeldataoffset++, 1));
												$paletteindexes[] = ($paletteindexbyte & 0xF0) >> 4;
												$paletteindexes[] = ($paletteindexbyte & 0x0F);
											}
											while (($pixeldataoffset % 2) != 0) {
												// Each run must be aligned on a word boundary.
												$pixeldataoffset++;
											}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -