Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions lab-matt/.eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
**/node_modules/*
**/vendor/*
**/*.min.js
**/coverage/*
**/build/*
26 changes: 26 additions & 0 deletions lab-matt/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"env": {
"browser": true,
"node": true,
"commonjs": true,
"jest": true,
"es6": true
},
"globals": {
"err": true,
"req": true,
"res": true,
"next": true
},
"extends": "eslint:recommended",
"parserOptions": {
"sourceType": "module"
},
"rules": {
"no-console": "off",
"indent": [ "error", 2 ],
"quotes": ["error", "single", { "allowTemplateLiterals": true }],
"comma-dangle": ["error", "always-multiline"],
"semi": [ "error", "always" ]
}
}
149 changes: 149 additions & 0 deletions lab-matt/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@

# Created by https://www.gitignore.io/api/osx,vim,node,linux,windows,visualstudiocode

### Linux ###
*~

# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*

# KDE directory preferences
.directory

# Linux trash folder which might appear on any partition or disk
.Trash-*

# .nfs files are created when an open file is removed but is still being accessed
.nfs*

### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage

# nyc test coverage
.nyc_output

# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# Typescript v1 declaration files
typings/

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env


### OSX ###
*.DS_Store
.AppleDouble
.LSOverride

# Icon must end with two \r
Icon

# Thumbnails
._*

# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent

# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk

### Vim ###
# swap
[._]*.s[a-v][a-z]
[._]*.sw[a-p]
[._]s[a-v][a-z]
[._]sw[a-p]
# session
Session.vim
# temporary
.netrwhist
# auto-generated tag files
tags

### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history

### Windows ###
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db

# Folder config file
Desktop.ini

# Recycle Bin used on file shares
$RECYCLE.BIN/

# Windows Installer files
*.cab
*.msi
*.msm
*.msp

# Windows shortcuts
*.lnk

# End of https://www.gitignore.io/api/osx,vim,node,linux,windows,visualstudiocode
19 changes: 19 additions & 0 deletions lab-matt/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# 04: Bitmap
Description: **Lab 04 of Code Fellows JavaScript 401d19** </br>
Author: **Matthew LeBlanc** </br>
Date: **12/02/17**

### `bitmap.bufferFile`
has an arity of three that takes in a filePath, transformation type, and a destination, and rewrites the file with the transformation type into the location that was specified.

### `bitmap.createBufferObject`
has an arity of one, which is the read bmp file and creates an object out of that file that has multiple properties pertaining to the buffer

### `transform.invertColors`
has an arity of one that takes in the colorPalette of the buffer object and redefines it by taking the difference of the current color and 255 which in turn inverts the colors

### `transform.randomize`
has an arity of one that takes in the colorPalette of the buffer object and redefines it by creating a random number between 0 and 255 and subtracting the rgb values of the colorPalette from the respective random number

### `transform.grayscale`
has an arity of one that takes in the colorPalette of the buffer object and redefines it by setting each red, green, and blue value to the same
Binary file added lab-matt/__test__/assets/bitmap.bmp
Binary file not shown.
Binary file added lab-matt/__test__/assets/finger-print.bmp
Binary file not shown.
Binary file added lab-matt/__test__/assets/house.bmp
Binary file not shown.
Binary file added lab-matt/__test__/assets/non-palette-bitmap.bmp
Binary file not shown.
41 changes: 41 additions & 0 deletions lab-matt/__test__/bitmap.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use strict';

const bitmap = require('../lib/bitmap.js');
const fs = require('fs');

let files = fs.readdirSync('./__test__/assets/', (err, data) => {
console.log(err);
return data;
});

// ------------- CODE -------------------
describe('testing fs.readdir reads all files in a folder and returns an array', () => {
test('fs.readdir(\'assets/', () => {
expect(files).toEqual(['bitmap.bmp', 'finger-print.bmp', 'house.bmp', 'non-palette-bitmap.bmp']);
});
});

describe('testing buffering file returns data', () => {
test('buffer - type is equal to "BM" and has other properties', (done) => {
bitmap.bufferFile(`./__test__/assets/${files[2]}`, 'grayscale', `${__dirname}/../created_files/`, (data) => {
console.log(data.buffer);
expect(data.type).toEqual('BM');
expect(data.fileSize).not.toBeNull();
expect(data.pixelDataTable).toEqual(1078);
expect(data.width).not.toBeNull();
expect(data.height).not.toBeNull();
expect(data.bitsPerPixel).not.toBeNull();

done();
});
});
});

describe('file formatting', () => {
test('returning just the file name if given either filepath and/or filename.extension', () => {
expect('/desktop/example/lib/fileName.txt'.match(/[\w-]+(?=\.)/)[0]).toEqual('fileName');
expect('/desktop/example/lib/file-Name.txt'.match(/[\w-]+(?=\.)/)[0]).toEqual('file-Name');
expect('fileName.txt'.match(/[\w-]+(?=\.)/)[0]).toEqual('fileName');
expect('file-Name.txt'.match(/[\w-]+(?=\.)/)[0]).toEqual('file-Name');
});
});
22 changes: 22 additions & 0 deletions lab-matt/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env node
'use strict';

const program = require('commander');
const bitmap = require('./lib/bitmap');

program.arguments('<file_location> <invert|grayscale|random> <file_destination>')
.action((fileLocation, transformationType, fileDestination) => {
// console.log(`${fileLocation} - ${transformationType} - ${fileDestination}`);
bitmap.bufferFile(fileLocation, transformationType, fileDestination);
})
.parse(process.argv);


// bitmap.bufferFile(`${__dirname}/__test__/assets/house.bmp`, 'random', `${__dirname}/created_files/`);

// // mattL - runs through each file in a given folder for the transformation
// let files = fs.readdirSync('./__test__/assets/');

// for (let i in files) {
// bitmap.bufferFile(`${__dirname}/__test__/assets/${files[i]}`, 'random', `${__dirname}/created_files/`);
// }
119 changes: 119 additions & 0 deletions lab-matt/lib/bitmap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
'use strict';

const bitmap = module.exports = {};
const fs = require('fs');
const transform = {};

// -------------- CODE ------------------
bitmap.bufferFile = (filePath, transformation, destination, callback) => {
// mattL - fs.readFile creates the buffer object and returns it as data
fs.readFile(`${filePath}`, (err, data) => {
if (err) throw err;

// newly created buffer object with specific properties
let parsedBitmap = bitmap.createBufferObject(data);
console.log('BITMAP OBJECT:', parsedBitmap, '\n');

// mattL - switch case to determine which transformation to use
let transformationName;
switch (transformation) {
case ('invert'):
transformationName = 'inverted';
transform.invertColors(parsedBitmap.colorPalette);
break;
case ('random'):
transformationName = 'randomized';
transform.randomize(parsedBitmap.colorPalette);
break;
case ('grayscale'):
transformationName = 'grayscale';
transform.grayscale(parsedBitmap.colorPalette);
break;
}

// mattL - removing the '.<filetype>' with regex if exists so I can use any type later
let fileName = filePath.match(/[\w-_]+(?=\.)/)[0];
// mattL - writing newly updated file with <transformationName>ed-<fileName> - if there's an error, .log it
fs.writeFile(`${destination}${transformationName}-${fileName}.bmp`, parsedBitmap.buffer, err => { if (err) console.log(err); });

// --- DEV INFORMATION: prints out complete buffer as json and color palette as txt document ---
// fs.writeFile(`${__dirname}/../created_files/dev_information/buffer-${fileName}.json`, JSON.stringify(parsedBitmap.buffer), err => { if (err) console.log(err); });
// fs.writeFile(`${__dirname}/../created_files/dev_information/palette-${fileName}.txt`, JSON.stringify(parsedBitmap.colorPalette), err => { if (err) console.log(err); });
// --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---

// mattL - parsedBitmap is object containing all properties of the buffer
if (callback) callback(parsedBitmap);
});
};

bitmap.createBufferObject = (buffer) => {
let parsedBitmap = {};
let offset = {};

offset = {
FILE_SIZE: 2,
PIXEL_DATA_TABLE: 10,
HEADER_SIZE: 14,
PIXEL_WIDTH: 18,
PIXEL_HEIGHT: 22,
BITS_PER_PIXEL: 28,
COLOR_PALETTE: 54,
};

parsedBitmap.buffer = buffer;
parsedBitmap.type = buffer.toString('utf-8', 0, 2);
parsedBitmap.fileSize = buffer.readInt32LE(offset.FILE_SIZE);
parsedBitmap.pixelDataTable = buffer.readInt32LE(offset.PIXEL_DATA_TABLE);
parsedBitmap.headerSize = buffer.readInt32LE(offset.HEADER_SIZE);
parsedBitmap.width = buffer.readInt32LE(offset.PIXEL_WIDTH);
parsedBitmap.height = buffer.readInt32LE(offset.PIXEL_WIDTH);
parsedBitmap.bitsPerPixel = buffer.readInt8(offset.BITS_PER_PIXEL);
parsedBitmap.colorPalette = buffer.slice(offset.COLOR_PALETTE, parsedBitmap.pixelDataTable);

return parsedBitmap;
};

transform.invertColors = (colorPalette) => {
// blue
for (let i = 0; i < colorPalette.length; i += 4) {
colorPalette.fill(255-colorPalette[i], i, i+1); // buffer.fill(value[, offset[, end]][, encoding])
}

// green
for (let i = 1; i < colorPalette.length; i +=4) {
colorPalette.fill(255-colorPalette[i], i, i+1);
}

// red
for (let i = 2; i < colorPalette.length; i +=4) {
colorPalette.fill(255-colorPalette[i], i, i+1);
}
};

transform.randomize = (colorPalette) => {
let red = Math.floor(Math.random() * 256);
let blue = Math.floor(Math.random() * 256);
let green = Math.floor(Math.random() * 256);

for (let i = 0; i < colorPalette.length; i += 4) {
colorPalette.fill(blue - colorPalette[i], i, i+1);
}

for (let i = 1; i < colorPalette.length; i += 4) {
colorPalette.fill(green - colorPalette[i], i, i+1);
}

for (let i = 2; i < colorPalette.length; i += 4) {
colorPalette.fill(red - colorPalette[i], i, i+1);
}
};

transform.grayscale = (colorPalette) => {
// Red=30%, Green=59%, Blue=11% --- https://www.gimp.org/tutorials/Color2BW/#channelmixer

for (let i = 0; i < colorPalette.length; i += 4) {
colorPalette.fill(
(colorPalette[i] + 1),
i, i+3);
}
};
Loading